diff --git a/awt/java/awt/AWTEvent.java b/awt/java/awt/AWTEvent.java
new file mode 100644
index 0000000..a8dc83a
--- /dev/null
+++ b/awt/java/awt/AWTEvent.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 Dmitry A. Durnev, Michael Danilov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.util.EventObject;
+import java.util.Hashtable;
+import java.util.EventListener;
+
+import java.awt.event.*;
+
+/**
+ * The abstract class AWTEvent is the base class for all AWT events. This class
+ * and its subclasses supersede the original java.awt.Event class.
+ * 
+ * @since Android 1.0
+ */
+public abstract class AWTEvent extends EventObject {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -1825314779160409405L;
+
+    /**
+     * The Constant COMPONENT_EVENT_MASK indicates the event relates to a
+     * component.
+     */
+    public static final long COMPONENT_EVENT_MASK = 1;
+
+    /**
+     * The Constant CONTAINER_EVENT_MASK indicates the event relates to a
+     * container.
+     */
+    public static final long CONTAINER_EVENT_MASK = 2;
+
+    /**
+     * The Constant FOCUS_EVENT_MASK indicates the event relates to the focus.
+     */
+    public static final long FOCUS_EVENT_MASK = 4;
+
+    /**
+     * The Constant KEY_EVENT_MASK indicates the event relates to a key.
+     */
+    public static final long KEY_EVENT_MASK = 8;
+
+    /**
+     * The Constant MOUSE_EVENT_MASK indicates the event relates to the mouse.
+     */
+    public static final long MOUSE_EVENT_MASK = 16;
+
+    /**
+     * The Constant MOUSE_MOTION_EVENT_MASK indicates the event relates to a
+     * mouse motion.
+     */
+    public static final long MOUSE_MOTION_EVENT_MASK = 32;
+
+    /**
+     * The Constant WINDOW_EVENT_MASK indicates the event relates to a window.
+     */
+    public static final long WINDOW_EVENT_MASK = 64;
+
+    /**
+     * The Constant ACTION_EVENT_MASK indicates the event relates to an action.
+     */
+    public static final long ACTION_EVENT_MASK = 128;
+
+    /**
+     * The Constant ADJUSTMENT_EVENT_MASK indicates the event relates to an
+     * adjustment.
+     */
+    public static final long ADJUSTMENT_EVENT_MASK = 256;
+
+    /**
+     * The Constant ITEM_EVENT_MASK indicates the event relates to an item.
+     */
+    public static final long ITEM_EVENT_MASK = 512;
+
+    /**
+     * The Constant TEXT_EVENT_MASK indicates the event relates to text.
+     */
+    public static final long TEXT_EVENT_MASK = 1024;
+
+    /**
+     * The Constant INPUT_METHOD_EVENT_MASK indicates the event relates to an
+     * input method.
+     */
+    public static final long INPUT_METHOD_EVENT_MASK = 2048;
+
+    /**
+     * The Constant PAINT_EVENT_MASK indicates the event relates to a paint
+     * method.
+     */
+    public static final long PAINT_EVENT_MASK = 8192;
+
+    /**
+     * The Constant INVOCATION_EVENT_MASK indicates the event relates to a
+     * method invocation.
+     */
+    public static final long INVOCATION_EVENT_MASK = 16384;
+
+    /**
+     * The Constant HIERARCHY_EVENT_MASK indicates the event relates to a
+     * hierarchy.
+     */
+    public static final long HIERARCHY_EVENT_MASK = 32768;
+
+    /**
+     * The Constant HIERARCHY_BOUNDS_EVENT_MASK indicates the event relates to
+     * hierarchy bounds.
+     */
+    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 65536;
+
+    /**
+     * The Constant MOUSE_WHEEL_EVENT_MASK indicates the event relates to the
+     * mouse wheel.
+     */
+    public static final long MOUSE_WHEEL_EVENT_MASK = 131072;
+
+    /**
+     * The Constant WINDOW_STATE_EVENT_MASK indicates the event relates to a
+     * window state.
+     */
+    public static final long WINDOW_STATE_EVENT_MASK = 262144;
+
+    /**
+     * The Constant WINDOW_FOCUS_EVENT_MASK indicates the event relates to a
+     * window focus.
+     */
+    public static final long WINDOW_FOCUS_EVENT_MASK = 524288;
+
+    /**
+     * The Constant RESERVED_ID_MAX indicates the maximum value for reserved AWT
+     * event IDs.
+     */
+    public static final int RESERVED_ID_MAX = 1999;
+
+    /**
+     * The Constant eventsMap.
+     */
+    private static final Hashtable<Integer, EventDescriptor> eventsMap = new Hashtable<Integer, EventDescriptor>();
+
+    /**
+     * The converter.
+     */
+    private static EventConverter converter;
+
+    /**
+     * The ID of the event.
+     */
+    protected int id;
+
+    /**
+     * The consumed indicates whether or not the event is sent back down to the
+     * peer once the source has processed it (false means it's sent to the peer,
+     * true means it's not).
+     */
+    protected boolean consumed;
+
+    /**
+     * The dispatched by kfm.
+     */
+    boolean dispatchedByKFM;
+
+    /**
+     * The is posted.
+     */
+    transient boolean isPosted;
+
+    static {
+        eventsMap.put(new Integer(KeyEvent.KEY_TYPED), new EventDescriptor(KEY_EVENT_MASK,
+                KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_PRESSED), new EventDescriptor(KEY_EVENT_MASK,
+                KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_RELEASED), new EventDescriptor(KEY_EVENT_MASK,
+                KeyListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_CLICKED), new EventDescriptor(MOUSE_EVENT_MASK,
+                MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_PRESSED), new EventDescriptor(MOUSE_EVENT_MASK,
+                MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_RELEASED), new EventDescriptor(MOUSE_EVENT_MASK,
+                MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_MOVED), new EventDescriptor(
+                MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_ENTERED), new EventDescriptor(MOUSE_EVENT_MASK,
+                MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_EXITED), new EventDescriptor(MOUSE_EVENT_MASK,
+                MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_DRAGGED), new EventDescriptor(
+                MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_WHEEL), new EventDescriptor(
+                MOUSE_WHEEL_EVENT_MASK, MouseWheelListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_MOVED), new EventDescriptor(
+                COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_RESIZED), new EventDescriptor(
+                COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_SHOWN), new EventDescriptor(
+                COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_HIDDEN), new EventDescriptor(
+                COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_GAINED), new EventDescriptor(FOCUS_EVENT_MASK,
+                FocusListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_LOST), new EventDescriptor(FOCUS_EVENT_MASK,
+                FocusListener.class));
+        eventsMap.put(new Integer(PaintEvent.PAINT), new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(PaintEvent.UPDATE), new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_OPENED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSING), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEICONIFIED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ICONIFIED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_STATE_CHANGED), new EventDescriptor(
+                WINDOW_STATE_EVENT_MASK, WindowStateListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_LOST_FOCUS), new EventDescriptor(
+                WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_GAINED_FOCUS), new EventDescriptor(
+                WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEACTIVATED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ACTIVATED), new EventDescriptor(
+                WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.HIERARCHY_CHANGED), new EventDescriptor(
+                HIERARCHY_EVENT_MASK, HierarchyListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_MOVED), new EventDescriptor(
+                HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_RESIZED), new EventDescriptor(
+                HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_ADDED), new EventDescriptor(
+                CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_REMOVED), new EventDescriptor(
+                CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED), new EventDescriptor(
+                INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.CARET_POSITION_CHANGED), new EventDescriptor(
+                INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InvocationEvent.INVOCATION_DEFAULT), new EventDescriptor(
+                INVOCATION_EVENT_MASK, null));
+        eventsMap.put(new Integer(ItemEvent.ITEM_STATE_CHANGED), new EventDescriptor(
+                ITEM_EVENT_MASK, ItemListener.class));
+        eventsMap.put(new Integer(TextEvent.TEXT_VALUE_CHANGED), new EventDescriptor(
+                TEXT_EVENT_MASK, TextListener.class));
+        eventsMap.put(new Integer(ActionEvent.ACTION_PERFORMED), new EventDescriptor(
+                ACTION_EVENT_MASK, ActionListener.class));
+        eventsMap.put(new Integer(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED), new EventDescriptor(
+                ADJUSTMENT_EVENT_MASK, AdjustmentListener.class));
+        converter = new EventConverter();
+    }
+
+    /**
+     * Instantiates a new AWT event from the specified Event object.
+     * 
+     * @param event
+     *            the Event object.
+     */
+    public AWTEvent(Event event) {
+        this(event.target, event.id);
+    }
+
+    /**
+     * Instantiates a new AWT event with the specified object and type.
+     * 
+     * @param source
+     *            the source Object.
+     * @param id
+     *            the event's type.
+     */
+    public AWTEvent(Object source, int id) {
+        super(source);
+        this.id = id;
+        consumed = false;
+    }
+
+    /**
+     * Gets the event's type.
+     * 
+     * @return the event type ID.
+     */
+    public int getID() {
+        return id;
+    }
+
+    /**
+     * Sets a new source for the AWTEvent.
+     * 
+     * @param newSource
+     *            the new source Object for the AWTEvent.
+     */
+    public void setSource(Object newSource) {
+        source = newSource;
+    }
+
+    /**
+     * Returns a String representation of the AWTEvent.
+     * 
+     * @return the String representation of the AWTEvent.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code: AWTEvent event = new AWTEvent(new Component(){},
+         * 1){}; System.out.println(event);
+         */
+        String name = ""; //$NON-NLS-1$
+
+        if (source instanceof Component && (source != null)) {
+            Component comp = (Component)getSource();
+            name = comp.getName();
+            if (name == null) {
+                name = ""; //$NON-NLS-1$
+            }
+        }
+
+        return (getClass().getName() + "[" + paramString() + "]" //$NON-NLS-1$ //$NON-NLS-2$
+                + " on " + (name.length() > 0 ? name : source)); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns a string representation of the AWTEvent state.
+     * 
+     * @return a string representation of the AWTEvent state.
+     */
+    public String paramString() {
+        // nothing to implement: all event types must override this method
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Checks whether or not this AWTEvent has been consumed.
+     * 
+     * @return true, if this AWTEvent has been consumed, false otherwise.
+     */
+    protected boolean isConsumed() {
+        return consumed;
+    }
+
+    /**
+     * Consumes the AWTEvent.
+     */
+    protected void consume() {
+        consumed = true;
+    }
+
+    /**
+     * Convert AWTEvent object to a corresponding (deprecated) Event object.
+     * 
+     * @return new Event object which is a converted AWTEvent object or null if
+     *         the conversion is not possible
+     */
+    Event getEvent() {
+
+        if (id == ActionEvent.ACTION_PERFORMED) {
+            ActionEvent ae = (ActionEvent)this;
+            return converter.convertActionEvent(ae);
+
+        } else if (id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) {
+            AdjustmentEvent ae = (AdjustmentEvent)this;
+            return converter.convertAdjustmentEvent(ae);
+
+            // ???AWT
+            // } else if (id == ComponentEvent.COMPONENT_MOVED
+            // && source instanceof Window) {
+            // //the only type of Component events is COMPONENT_MOVED on window
+            // ComponentEvent ce = (ComponentEvent) this;
+            // return converter.convertComponentEvent(ce);
+
+        } else if (id >= FocusEvent.FOCUS_FIRST && id <= FocusEvent.FOCUS_LAST) {
+            // nothing to convert
+
+            // ???AWT
+            // } else if (id == ItemEvent.ITEM_STATE_CHANGED) {
+            // ItemEvent ie = (ItemEvent) this;
+            // return converter.convertItemEvent(ie);
+
+        } else if (id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED) {
+            KeyEvent ke = (KeyEvent)this;
+            return converter.convertKeyEvent(ke);
+        } else if (id >= MouseEvent.MOUSE_FIRST && id <= MouseEvent.MOUSE_LAST) {
+            MouseEvent me = (MouseEvent)this;
+            return converter.convertMouseEvent(me);
+        } else if (id == WindowEvent.WINDOW_CLOSING || id == WindowEvent.WINDOW_ICONIFIED
+                || id == WindowEvent.WINDOW_DEICONIFIED) {
+            // nothing to convert
+        } else {
+            return null;
+        }
+        return new Event(source, id, null);
+    }
+
+    /**
+     * The class EventDescriptor.
+     */
+    static final class EventDescriptor {
+
+        /**
+         * The event mask.
+         */
+        final long eventMask;
+
+        /**
+         * The listener type.
+         */
+        final Class<? extends EventListener> listenerType;
+
+        /**
+         * Instantiates a new event descriptor.
+         * 
+         * @param eventMask
+         *            the event mask.
+         * @param listenerType
+         *            the listener type.
+         */
+        EventDescriptor(long eventMask, Class<? extends EventListener> listenerType) {
+            this.eventMask = eventMask;
+            this.listenerType = listenerType;
+        }
+
+    }
+
+    /**
+     * The class EventTypeLookup.
+     */
+    static final class EventTypeLookup {
+
+        /**
+         * The last event.
+         */
+        private AWTEvent lastEvent = null;
+
+        /**
+         * The last event descriptor.
+         */
+        private EventDescriptor lastEventDescriptor = null;
+
+        /**
+         * Gets the event descriptor.
+         * 
+         * @param event
+         *            the event.
+         * @return the event descriptor.
+         */
+        EventDescriptor getEventDescriptor(AWTEvent event) {
+            synchronized (this) {
+                if (event != lastEvent) {
+                    lastEvent = event;
+                    lastEventDescriptor = eventsMap.get(new Integer(event.id));
+                }
+
+                return lastEventDescriptor;
+            }
+        }
+
+        /**
+         * Gets the event mask.
+         * 
+         * @param event
+         *            the event.
+         * @return the event mask.
+         */
+        long getEventMask(AWTEvent event) {
+            final EventDescriptor ed = getEventDescriptor(event);
+            return ed == null ? -1 : ed.eventMask;
+        }
+    }
+
+    /**
+     * The class EventConverter.
+     */
+    static final class EventConverter {
+
+        /**
+         * The constant OLD_MOD_MASK.
+         */
+        static final int OLD_MOD_MASK = Event.ALT_MASK | Event.CTRL_MASK | Event.META_MASK
+                | Event.SHIFT_MASK;
+
+        /**
+         * Convert action event.
+         * 
+         * @param ae
+         *            the ae.
+         * @return the event.
+         */
+        Event convertActionEvent(ActionEvent ae) {
+            Event evt = new Event(ae.getSource(), ae.getID(), ae.getActionCommand());
+            evt.when = ae.getWhen();
+            evt.modifiers = ae.getModifiers() & OLD_MOD_MASK;
+
+            /*
+             * if (source instanceof Button) { arg = ((Button)
+             * source).getLabel(); } else if (source instanceof Checkbox) { arg
+             * = new Boolean(((Checkbox) source).getState()); } else if (source
+             * instanceof CheckboxMenuItem) { arg = ((CheckboxMenuItem)
+             * source).getLabel(); } else if (source instanceof Choice) { arg =
+             * ((Choice) source).getSelectedItem(); } else if (source instanceof
+             * List) { arg = ((List) source).getSelectedItem(); } else if
+             * (source instanceof MenuItem) { arg = ((MenuItem)
+             * source).getLabel(); } else if (source instanceof TextField) { arg
+             * = ((TextField) source).getText(); }
+             */
+            return evt;
+        }
+
+        /**
+         * Convert adjustment event.
+         * 
+         * @param ae
+         *            the ae.
+         * @return the event.
+         */
+        Event convertAdjustmentEvent(AdjustmentEvent ae) {
+            // TODO: Event.SCROLL_BEGIN/SCROLL_END
+            return new Event(ae.source, ae.id + ae.getAdjustmentType() - 1, new Integer(ae
+                    .getValue()));
+        }
+
+        /**
+         * Convert component event.
+         * 
+         * @param ce
+         *            the ce.
+         * @return the event.
+         */
+        Event convertComponentEvent(ComponentEvent ce) {
+            Component comp = ce.getComponent();
+            Event evt = new Event(comp, Event.WINDOW_MOVED, null);
+            evt.x = comp.getX();
+            evt.y = comp.getY();
+            return evt;
+        }
+
+        // ???AWT
+        /*
+         * Event convertItemEvent(ItemEvent ie) { int oldId = ie.id +
+         * ie.getStateChange() - 1; Object source = ie.source; int idx = -1; if
+         * (source instanceof List) { List list = (List) source; idx =
+         * list.getSelectedIndex(); } else if (source instanceof Choice) {
+         * Choice choice = (Choice) source; idx = choice.getSelectedIndex(); }
+         * Object arg = idx >= 0 ? new Integer(idx) : null; return new
+         * Event(source, oldId, arg); }
+         */
+
+        /**
+         * Convert key event.
+         * 
+         * @param ke
+         *            the ke.
+         * @return the event.
+         */
+        Event convertKeyEvent(KeyEvent ke) {
+            int oldId = ke.id;
+            // leave only old Event's modifiers
+
+            int mod = ke.getModifiers() & OLD_MOD_MASK;
+            Component comp = ke.getComponent();
+            char keyChar = ke.getKeyChar();
+            int keyCode = ke.getKeyCode();
+            int key = convertKey(keyChar, keyCode);
+            if (key >= Event.HOME && key <= Event.INSERT) {
+                oldId += 2; // non-ASCII key -> action key
+            }
+            return new Event(comp, ke.getWhen(), oldId, 0, 0, key, mod);
+        }
+
+        /**
+         * Convert mouse event.
+         * 
+         * @param me
+         *            the me.
+         * @return the event.
+         */
+        Event convertMouseEvent(MouseEvent me) {
+            int id = me.id;
+            if (id != MouseEvent.MOUSE_CLICKED) {
+                Event evt = new Event(me.source, id, null);
+                evt.x = me.getX();
+                evt.y = me.getY();
+                int mod = me.getModifiers();
+                // in Event modifiers mean button number for mouse events:
+                evt.modifiers = mod & (Event.ALT_MASK | Event.META_MASK);
+                if (id == MouseEvent.MOUSE_PRESSED) {
+                    evt.clickCount = me.getClickCount();
+                }
+                return evt;
+            }
+            return null;
+        }
+
+        /**
+         * Convert key.
+         * 
+         * @param keyChar
+         *            the key char.
+         * @param keyCode
+         *            the key code.
+         * @return the int.
+         */
+        int convertKey(char keyChar, int keyCode) {
+            int key;
+            // F1 - F12
+            if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
+                key = Event.F1 + keyCode - KeyEvent.VK_F1;
+            } else {
+                switch (keyCode) {
+                    default: // non-action key
+                        key = keyChar;
+                        break;
+                    // action keys:
+                    case KeyEvent.VK_HOME:
+                        key = Event.HOME;
+                        break;
+                    case KeyEvent.VK_END:
+                        key = Event.END;
+                        break;
+                    case KeyEvent.VK_PAGE_UP:
+                        key = Event.PGUP;
+                        break;
+                    case KeyEvent.VK_PAGE_DOWN:
+                        key = Event.PGDN;
+                        break;
+                    case KeyEvent.VK_UP:
+                        key = Event.UP;
+                        break;
+                    case KeyEvent.VK_DOWN:
+                        key = Event.DOWN;
+                        break;
+                    case KeyEvent.VK_LEFT:
+                        key = Event.LEFT;
+                        break;
+                    case KeyEvent.VK_RIGHT:
+                        key = Event.RIGHT;
+                        break;
+                    case KeyEvent.VK_PRINTSCREEN:
+                        key = Event.PRINT_SCREEN;
+                        break;
+                    case KeyEvent.VK_SCROLL_LOCK:
+                        key = Event.SCROLL_LOCK;
+                        break;
+                    case KeyEvent.VK_CAPS_LOCK:
+                        key = Event.CAPS_LOCK;
+                        break;
+                    case KeyEvent.VK_NUM_LOCK:
+                        key = Event.NUM_LOCK;
+                        break;
+                    case KeyEvent.VK_PAUSE:
+                        key = Event.PAUSE;
+                        break;
+                    case KeyEvent.VK_INSERT:
+                        key = Event.INSERT;
+                        break;
+                }
+            }
+            return key;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/AWTException.java b/awt/java/awt/AWTException.java
new file mode 100644
index 0000000..6590b73
--- /dev/null
+++ b/awt/java/awt/AWTException.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 Michael Danilov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The AWTException class is used to provide notification and information about
+ * AWT errors.
+ * 
+ * @since Android 1.0
+ */
+public class AWTException extends Exception {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -1900414231151323879L;
+
+    /**
+     * Instantiates a new AWT exception with the specified message.
+     * 
+     * @param msg
+     *            the specific message for current exception.
+     */
+    public AWTException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/awt/java/awt/AWTKeyStroke.java b/awt/java/awt/AWTKeyStroke.java
new file mode 100644
index 0000000..f01f6f0
--- /dev/null
+++ b/awt/java/awt/AWTKeyStroke.java
@@ -0,0 +1,712 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AWTKeyStroke holds all of the information for the complete act of 
+ * typing a character. This includes the events that are generated when 
+ * the key is pressed, released, or typed (pressed and released generating
+ * a Unicode character result) which are associated with the event
+ * objects KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, or KeyEvent.KEY_TYPED.
+ * It also holds information about which modifiers (such as control or 
+ * shift) were used in conjunction with the keystroke. The following masks 
+ * are available to identify the modifiers:
+ * <ul>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+ * <li>java.awt.event.InputEvent.META_MASK</li>  
+ * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+ * </ul>  
+ * <br>
+ *  The AWTKeyStroke is unique, and applications should not create their own 
+ *  instances of AWTKeyStroke. All applications should use getAWTKeyStroke 
+ *  methods for obtaining instances of AWTKeyStroke.
+ *  
+ *  @since Android 1.0
+ */
+public class AWTKeyStroke implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -6430539691155161871L;
+
+    /**
+     * The Constant cache.
+     */
+    private static final Map<AWTKeyStroke, AWTKeyStroke> cache = new HashMap<AWTKeyStroke, AWTKeyStroke>(); // Map
+
+    // <
+    // AWTKeyStroke
+    // ,
+    // ?
+    // extends
+    // AWTKeyStroke
+    // >
+
+    /**
+     * The Constant keyEventTypesMap.
+     */
+    private static final Map<Integer, String> keyEventTypesMap = new HashMap<Integer, String>(); // Map
+
+    // <
+    // int
+    // ,
+    // String
+    // >
+
+    private static Constructor<?> subConstructor;
+
+    static {
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_PRESSED), "pressed"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_RELEASED), "released"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_TYPED), "typed"); //$NON-NLS-1$
+    }
+
+    /**
+     * The key char.
+     */
+    private char keyChar;
+
+    /**
+     * The key code.
+     */
+    private int keyCode;
+
+    /**
+     * The modifiers.
+     */
+    private int modifiers;
+
+    /**
+     * The on key release.
+     */
+    private boolean onKeyRelease;
+
+    /**
+     * Instantiates a new AWTKeyStroke. getAWTKeyStroke method should be used by
+     * applications code.
+     * 
+     * @param keyChar
+     *            the key char.
+     * @param keyCode
+     *            the key code.
+     * @param modifiers
+     *            the modifiers.
+     * @param onKeyRelease
+     *            true if AWTKeyStroke is for a key release, false otherwise.
+     */
+    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease) {
+        setAWTKeyStroke(keyChar, keyCode, modifiers, onKeyRelease);
+    }
+
+    /**
+     * Sets the AWT key stroke.
+     * 
+     * @param keyChar
+     *            the key char.
+     * @param keyCode
+     *            the key code.
+     * @param modifiers
+     *            the modifiers.
+     * @param onKeyRelease
+     *            the on key release.
+     */
+    private void setAWTKeyStroke(char keyChar, int keyCode, int modifiers, boolean onKeyRelease) {
+        this.keyChar = keyChar;
+        this.keyCode = keyCode;
+        this.modifiers = modifiers;
+        this.onKeyRelease = onKeyRelease;
+    }
+
+    /**
+     * Instantiates a new AWTKeyStroke with default parameters:
+     * KeyEvent.CHAR_UNDEFINED key char, KeyEvent.VK_UNDEFINED key code, without
+     * modifiers and false key realized value.
+     */
+    protected AWTKeyStroke() {
+        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns the unique number value for AWTKeyStroke object.
+     * 
+     * @return the integer unique value of the AWTKeyStroke object.
+     */
+    @Override
+    public int hashCode() {
+        return modifiers + (keyCode != KeyEvent.VK_UNDEFINED ? keyCode : keyChar)
+                + (onKeyRelease ? -1 : 0);
+    }
+
+    /**
+     * Gets the set of modifiers for the AWTKeyStroke object.
+     * 
+     * @return the integer value which contains modifiers.
+     */
+    public final int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Compares this AWTKeyStroke object to the specified object.
+     * 
+     * @param anObject
+     *            the specified AWTKeyStroke object to compare with this
+     *            instance.
+     * @return true if objects are identical, false otherwise.
+     */
+    @Override
+    public final boolean equals(Object anObject) {
+        if (anObject instanceof AWTKeyStroke) {
+            AWTKeyStroke key = (AWTKeyStroke)anObject;
+            return ((key.keyCode == keyCode) && (key.keyChar == keyChar)
+                    && (key.modifiers == modifiers) && (key.onKeyRelease == onKeyRelease));
+        }
+        return false;
+    }
+
+    /**
+     * Returns the string representation of the AWTKeyStroke. This string should
+     * contain key stroke properties.
+     * 
+     * @return the string representation of the AWTKeyStroke.
+     */
+    @Override
+    public String toString() {
+        int type = getKeyEventType();
+        return InputEvent.getModifiersExText(getModifiers()) + " " + //$NON-NLS-1$
+                keyEventTypesMap.get(new Integer(type)) + " " + //$NON-NLS-1$
+                (type == KeyEvent.KEY_TYPED ? new String(new char[] {
+                    keyChar
+                }) : KeyEvent.getKeyText(keyCode));
+    }
+
+    /**
+     * Gets the key code for the AWTKeyStroke object.
+     * 
+     * @return the key code for the AWTKeyStroke object.
+     */
+    public final int getKeyCode() {
+        return keyCode;
+    }
+
+    /**
+     * Gets the key character for the AWTKeyStroke object.
+     * 
+     * @return the key character for the AWTKeyStroke object.
+     */
+    public final char getKeyChar() {
+        return keyChar;
+    }
+
+    /**
+     * Gets the AWT key stroke.
+     * 
+     * @param keyChar
+     *            the key char.
+     * @param keyCode
+     *            the key code.
+     * @param modifiers
+     *            the modifiers.
+     * @param onKeyRelease
+     *            the on key release.
+     * @return the AWT key stroke.
+     */
+    private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease) {
+        AWTKeyStroke key = newInstance(keyChar, keyCode, modifiers, onKeyRelease);
+
+        AWTKeyStroke value = cache.get(key);
+        if (value == null) {
+            value = key;
+            cache.put(key, value);
+        }
+        return value;
+    }
+
+    /**
+     * New instance.
+     * 
+     * @param keyChar
+     *            the key char.
+     * @param keyCode
+     *            the key code.
+     * @param modifiers
+     *            the modifiers.
+     * @param onKeyRelease
+     *            the on key release.
+     * @return the AWT key stroke.
+     */
+    private static AWTKeyStroke newInstance(char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease) {
+        AWTKeyStroke key;
+        // ???AWT
+        // if (subConstructor == null) {
+        key = new AWTKeyStroke();
+        // ???AWT
+        // } else {
+        // try {
+        // key = (AWTKeyStroke) subConstructor.newInstance();
+        // } catch (Exception e) {
+        // throw new RuntimeException(e);
+        // }
+        // }
+        int allModifiers = getAllModifiers(modifiers);
+        key.setAWTKeyStroke(keyChar, keyCode, allModifiers, onKeyRelease);
+        return key;
+    }
+
+    /**
+     * Adds the mask.
+     * 
+     * @param mod
+     *            the mod.
+     * @param mask
+     *            the mask.
+     * @return the int.
+     */
+    private static int addMask(int mod, int mask) {
+        return ((mod & mask) != 0) ? (mod | mask) : mod;
+    }
+
+    /**
+     * Return all (old & new) modifiers corresponding to.
+     * 
+     * @param mod
+     *            old or new modifiers.
+     * @return old and new modifiers together.
+     */
+    static int getAllModifiers(int mod) {
+        int allMod = mod;
+        int shift = (InputEvent.SHIFT_MASK | InputEvent.SHIFT_DOWN_MASK);
+        int ctrl = (InputEvent.CTRL_MASK | InputEvent.CTRL_DOWN_MASK);
+        int meta = (InputEvent.META_MASK | InputEvent.META_DOWN_MASK);
+        int alt = (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK);
+        int altGr = (InputEvent.ALT_GRAPH_MASK | InputEvent.ALT_GRAPH_DOWN_MASK);
+        // button modifiers are not converted between old & new
+
+        allMod = addMask(allMod, shift);
+        allMod = addMask(allMod, ctrl);
+        allMod = addMask(allMod, meta);
+        allMod = addMask(allMod, alt);
+        allMod = addMask(allMod, altGr);
+
+        return allMod;
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for parsed string. The string must
+     * have the following syntax:
+     *<p>
+     * &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
+     *<p>
+     * modifiers := shift | control | ctrl | meta | alt | altGraph <br>
+     * typedID := typed <typedKey> <br>
+     * typedKey := string of length 1 giving the Unicode character. <br>
+     * pressedReleasedID := (pressed | released) <key> <br>
+     * key := KeyEvent key code name, i.e. the name following "VK_".
+     * <p>
+     * 
+     * @param s
+     *            the String which contains key stroke parameters.
+     * @return the AWTKeyStroke for string.
+     * @throws IllegalArgumentException
+     *             if string has incorrect format or null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(String s) {
+        if (s == null) {
+            // awt.65=null argument
+            throw new IllegalArgumentException(Messages.getString("awt.65")); //$NON-NLS-1$
+        }
+
+        StringTokenizer tokenizer = new StringTokenizer(s);
+
+        Boolean release = null;
+        int modifiers = 0;
+        int keyCode = KeyEvent.VK_UNDEFINED;
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+        boolean typed = false;
+        long modifier = 0;
+        String token = null;
+        do {
+            token = getNextToken(tokenizer);
+            modifier = parseModifier(token);
+            modifiers |= modifier;
+        } while (modifier > 0);
+
+        typed = parseTypedID(token);
+
+        if (typed) {
+            token = getNextToken(tokenizer);
+            keyChar = parseTypedKey(token);
+
+        }
+        if (keyChar == KeyEvent.CHAR_UNDEFINED) {
+            release = parsePressedReleasedID(token);
+            if (release != null) {
+                token = getNextToken(tokenizer);
+            }
+            keyCode = parseKey(token);
+        }
+        if (tokenizer.hasMoreTokens()) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+
+        return getAWTKeyStroke(keyChar, keyCode, modifiers, release == Boolean.TRUE);
+    }
+
+    /**
+     * Gets the next token.
+     * 
+     * @param tokenizer
+     *            the tokenizer.
+     * @return the next token.
+     */
+    private static String getNextToken(StringTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (NoSuchElementException exception) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets the key code.
+     * 
+     * @param s
+     *            the s.
+     * @return the key code.
+     */
+    static int getKeyCode(String s) {
+        try {
+            Field vk = KeyEvent.class.getField("VK_" + s); //$NON-NLS-1$
+            return vk.getInt(null);
+        } catch (Exception e) {
+            if (s.length() != 1) {
+                // awt.66=Invalid format
+                throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+            }
+            return KeyEvent.VK_UNDEFINED;
+        }
+    }
+
+    /**
+     * Gets an instance of the AWTKeyStroke for specified character.
+     * 
+     * @param keyChar
+     *            the keyboard character value.
+     * @return a AWTKeyStroke for specified character.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
+        return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a given key code, set of
+     * modifiers, and specified key released flag value. The key codes are
+     * defined in java.awt.event.KeyEvent class. The set of modifiers is given
+     * as a bitwise combination of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
+     * java.awt.event.InputEvent.META_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * <br>
+     * 
+     * @param keyCode
+     *            the specified key code of keyboard.
+     * @param modifiers
+     *            the bit set of modifiers.
+     * @param onKeyRelease
+     *            the value which represents whether this AWTKeyStroke shall
+     *            represents a key release.
+     * @return the AWTKeyStroke.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) {
+        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers, onKeyRelease);
+    }
+
+    /**
+     * Returns AWTKeyStroke for a specified character and set of modifiers. The
+     * set of modifiers is given as a bitwise combination of masks taken from
+     * the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
+     * java.awt.event.InputEvent.META_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * 
+     * @param keyChar
+     *            the Character object which represents keyboard character
+     *            value.
+     * @param modifiers
+     *            the bit set of modifiers.
+     * @return the AWTKeyStroke object.
+     * @throws IllegalArgumentException
+     *             if keyChar value is null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) {
+        if (keyChar == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "keyChar")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED, modifiers, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a specified key code and set of
+     * modifiers. The key codes are defined in java.awt.event.KeyEvent class.
+     * The set of modifiers is given as a bitwise combination of masks taken
+     * from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.META_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_DOWN_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_GRAPH_MASK</li> <li>
+     * java.awt.event.InputEvent.ALT_MASK</li> <li>
+     * java.awt.event.InputEvent.CTRL_MASK</li> <li>
+     * java.awt.event.InputEvent.META_MASK</li> <li>
+     * java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * 
+     * @param keyCode
+     *            the specified key code of keyboard.
+     * @param modifiers
+     *            the bit set of modifiers.
+     * @return the AWTKeyStroke.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
+        return getAWTKeyStroke(keyCode, modifiers, false);
+    }
+
+    /**
+     * Gets the AWTKeyStroke for a key event. This method obtains the key char
+     * and key code from the specified key event.
+     * 
+     * @param anEvent
+     *            the key event which identifies the desired AWTKeyStroke.
+     * @return the AWTKeyStroke for the key event.
+     */
+    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
+        int id = anEvent.getID();
+        char undef = KeyEvent.CHAR_UNDEFINED;
+        char keyChar = (id == KeyEvent.KEY_TYPED ? anEvent.getKeyChar() : undef);
+        int keyCode = (keyChar == undef ? anEvent.getKeyCode() : KeyEvent.VK_UNDEFINED);
+        return getAWTKeyStroke(keyChar, keyCode, anEvent.getModifiersEx(),
+                id == KeyEvent.KEY_RELEASED);
+    }
+
+    /**
+     * Gets the key event type for the AWTKeyStroke object.
+     * 
+     * @return the key event type: KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or
+     *         KeyEvent.KEY_RELEASED.
+     */
+    public final int getKeyEventType() {
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            return KeyEvent.KEY_TYPED;
+        }
+        return (onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED);
+    }
+
+    /**
+     * Returns true if the key event is associated with the AWTKeyStroke is
+     * KEY_RELEASED, false otherwise.
+     * 
+     * @return true, if if the key event associated with the AWTKeyStroke is
+     *         KEY_RELEASED, false otherwise.
+     */
+    public final boolean isOnKeyRelease() {
+        return onKeyRelease;
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object.
+     * @throws ObjectStreamException
+     *             the object stream exception.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return getAWTKeyStroke(this.keyChar, this.keyCode, this.modifiers, this.onKeyRelease);
+    }
+
+    /**
+     * Register subclass.
+     * 
+     * @param subclass
+     *            the subclass.
+     */
+    protected static void registerSubclass(Class<?> subclass) {
+        // ???AWT
+        /*
+         * if (subclass == null) { // awt.01='{0}' parameter is null throw new
+         * IllegalArgumentException(Messages.getString("awt.01", "subclass"));
+         * //$NON-NLS-1$ //$NON-NLS-2$ } if (!
+         * AWTKeyStroke.class.isAssignableFrom(subclass)) { // awt.67=subclass
+         * is not derived from AWTKeyStroke throw new
+         * ClassCastException(Messages.getString("awt.67")); //$NON-NLS-1$ } try
+         * { subConstructor = subclass.getDeclaredConstructor();
+         * subConstructor.setAccessible(true); } catch (SecurityException e) {
+         * throw new RuntimeException(e); } catch (NoSuchMethodException e) { //
+         * awt.68=subclass could not be instantiated throw new
+         * IllegalArgumentException(Messages.getString("awt.68")); //$NON-NLS-1$
+         * } cache.clear(); //flush the cache
+         */
+    }
+
+    /**
+     * Parses the modifier.
+     * 
+     * @param strMod
+     *            the str mod.
+     * @return the long.
+     */
+    private static long parseModifier(String strMod) {
+        long modifiers = 0l;
+        if (strMod.equals("shift")) { //$NON-NLS-1$
+            modifiers |= InputEvent.SHIFT_DOWN_MASK;
+        } else if (strMod.equals("control") || strMod.equals("ctrl")) { //$NON-NLS-1$ //$NON-NLS-2$
+            modifiers |= InputEvent.CTRL_DOWN_MASK;
+        } else if (strMod.equals("meta")) { //$NON-NLS-1$
+            modifiers |= InputEvent.META_DOWN_MASK;
+        } else if (strMod.equals("alt")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_DOWN_MASK;
+        } else if (strMod.equals("altGraph")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
+        } else if (strMod.equals("button1")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
+        } else if (strMod.equals("button2")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
+        } else if (strMod.equals("button3")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+        }
+        return modifiers;
+    }
+
+    /**
+     * Parses the typed id.
+     * 
+     * @param strTyped
+     *            the str typed.
+     * @return true, if successful.
+     */
+    private static boolean parseTypedID(String strTyped) {
+        if (strTyped.equals("typed")) { //$NON-NLS-1$
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses the typed key.
+     * 
+     * @param strChar
+     *            the str char.
+     * @return the char.
+     */
+    private static char parseTypedKey(String strChar) {
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+
+        if (strChar.length() != 1) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        keyChar = strChar.charAt(0);
+        return keyChar;
+    }
+
+    /**
+     * Parses the pressed released id.
+     * 
+     * @param str
+     *            the str.
+     * @return the boolean.
+     */
+    private static Boolean parsePressedReleasedID(String str) {
+
+        if (str.equals("pressed")) { //$NON-NLS-1$
+            return Boolean.FALSE;
+        } else if (str.equals("released")) { //$NON-NLS-1$
+            return Boolean.TRUE;
+        }
+        return null;
+    }
+
+    /**
+     * Parses the key.
+     * 
+     * @param strCode
+     *            the str code.
+     * @return the int.
+     */
+    private static int parseKey(String strCode) {
+        int keyCode = KeyEvent.VK_UNDEFINED;
+
+        keyCode = getKeyCode(strCode);
+
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        return keyCode;
+    }
+}
diff --git a/awt/java/awt/AWTListenerList.java b/awt/java/awt/AWTListenerList.java
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..4bd8357
--- /dev/null
+++ b/awt/java/awt/AWTPermission.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;
+
+import java.security.BasicPermission;
+
+/**
+ * The AWTPermission specifies the name of the permission and the corresponding
+ * action list.
+ * 
+ * @since Android 1.0
+ */
+public final class AWTPermission extends BasicPermission {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 8890392402588814465L;
+
+    /**
+     * Instantiates a new AWTPermission with defined name and actions.
+     * 
+     * @param name
+     *            the name of a new AWTPermission.
+     * @param actions
+     *            the actions of a new AWTPermission.
+     */
+    public AWTPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /**
+     * Instantiates a new AWT permission with the defined name.
+     * 
+     * @param name
+     *            the name of a new AWTPermission.
+     */
+    public AWTPermission(String name) {
+        super(name);
+    }
+
+}
diff --git a/awt/java/awt/ActiveEvent.java b/awt/java/awt/ActiveEvent.java
new file mode 100644
index 0000000..7044623
--- /dev/null
+++ b/awt/java/awt/ActiveEvent.java
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * This interface defines events that know how to dispatch themselves. Such
+ * event can be placed upon the event queue and its dispatch method will be
+ * called when the event is dispatched.
+ * 
+ * @since Android 1.0
+ */
+public interface ActiveEvent {
+
+    /**
+     * Dispatches the event to the listeners of the event's source, or does
+     * whatever it is this event is supposed to do.
+     */
+    public void dispatch();
+
+}
diff --git a/awt/java/awt/Adjustable.java b/awt/java/awt/Adjustable.java
new file mode 100644
index 0000000..baf80f7
--- /dev/null
+++ b/awt/java/awt/Adjustable.java
@@ -0,0 +1,166 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+
+/**
+ * The Adjustable interface represents an adjustable numeric value contained
+ * within a bounded range of values, such as the current location in scrollable
+ * region or the value of a gauge.
+ * 
+ * @since Android 1.0
+ */
+public interface Adjustable {
+
+    /**
+     * The Constant HORIZONTAL indicates that the Adjustable's orientation is
+     * horizontal.
+     */
+    public static final int HORIZONTAL = 0;
+
+    /**
+     * The Constant VERTICAL indicates that the Adjustable's orientation is
+     * vertical.
+     */
+    public static final int VERTICAL = 1;
+
+    /**
+     * The Constant NO_ORIENTATION indicates that the Adjustable has no
+     * orientation.
+     */
+    public static final int NO_ORIENTATION = 2;
+
+    /**
+     * Gets the value of the Adjustable.
+     * 
+     * @return the current value of the Adjustable.
+     */
+    public int getValue();
+
+    /**
+     * Sets the value to the Adjustable object.
+     * 
+     * @param a0
+     *            the new value of the Adjustable object.
+     */
+    public void setValue(int a0);
+
+    /**
+     * Adds the AdjustmentListener to current Adjustment.
+     * 
+     * @param a0
+     *            the AdjustmentListener object.
+     */
+    public void addAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Gets the block increment of the Adjustable.
+     * 
+     * @return the block increment of the Adjustable.
+     */
+    public int getBlockIncrement();
+
+    /**
+     * Gets the maximum value of the Adjustable.
+     * 
+     * @return the maximum value of the Adjustable.
+     */
+    public int getMaximum();
+
+    /**
+     * Gets the minimum value of the Adjustable.
+     * 
+     * @return the minimum value of the Adjustable.
+     */
+    public int getMinimum();
+
+    /**
+     * Gets the orientation of the Adjustable.
+     * 
+     * @return the orientation of the Adjustable.
+     */
+    public int getOrientation();
+
+    /**
+     * Gets the unit increment of the Adjustable.
+     * 
+     * @return the unit increment of the Adjustable.
+     */
+    public int getUnitIncrement();
+
+    /**
+     * Gets the visible amount of the Adjustable.
+     * 
+     * @return the visible amount of the Adjustable.
+     */
+    public int getVisibleAmount();
+
+    /**
+     * Removes the adjustment listener of the Adjustable.
+     * 
+     * @param a0
+     *            the specified AdjustmentListener to be removed.
+     */
+    public void removeAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Sets the block increment for the Adjustable.
+     * 
+     * @param a0
+     *            the new block increment.
+     */
+    public void setBlockIncrement(int a0);
+
+    /**
+     * Sets the maximum value of the Adjustable.
+     * 
+     * @param a0
+     *            the new maximum of the Adjustable.
+     */
+    public void setMaximum(int a0);
+
+    /**
+     * Sets the minimum value of the Adjustable.
+     * 
+     * @param a0
+     *            the new minimum of the Adjustable.
+     */
+    public void setMinimum(int a0);
+
+    /**
+     * Sets the unit increment of the Adjustable.
+     * 
+     * @param a0
+     *            the new unit increment of the Adjustable.
+     */
+    public void setUnitIncrement(int a0);
+
+    /**
+     * Sets the visible amount of the Adjustable.
+     * 
+     * @param a0
+     *            the new visible amount of the Adjustable.
+     */
+    public void setVisibleAmount(int a0);
+
+}
diff --git a/awt/java/awt/AlphaComposite.java b/awt/java/awt/AlphaComposite.java
new file mode 100644
index 0000000..8389eb4
--- /dev/null
+++ b/awt/java/awt/AlphaComposite.java
@@ -0,0 +1,352 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.gl.ICompositeContext;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AlphaComposite class defines a basic alpha compositing rules for
+ * combining source and destination colors to achieve blending and transparency
+ * effects with graphics and images.
+ * 
+ * @since Android 1.0
+ */
+public final class AlphaComposite implements Composite {
+
+    /**
+     * The Constant CLEAR indicates that both the color and the alpha of the
+     * destination are cleared (Porter-Duff Clear rule).
+     */
+    public static final int CLEAR = 1;
+
+    /**
+     * The Constant SRC indicates that the source is copied to the destination
+     * (Porter-Duff Source rule).
+     */
+    public static final int SRC = 2;
+
+    /**
+     * The Constant DST indicates that the destination is left untouched
+     * (Porter-Duff Destination rule).
+     */
+    public static final int DST = 9;
+
+    /**
+     * The Constant SRC_OVER indicates that the source is composited over the
+     * destination (Porter-Duff Source Over Destination rule).
+     */
+    public static final int SRC_OVER = 3;
+
+    /**
+     * The Constant DST_OVER indicates that The destination is composited over
+     * the source and the result replaces the destination (Porter-Duff
+     * Destination Over Source rule).
+     */
+    public static final int DST_OVER = 4;
+
+    /**
+     * The Constant SRC_IN indicates that the part of the source lying inside of
+     * the destination replaces the destination (Porter-Duff Source In
+     * Destination rule).
+     */
+    public static final int SRC_IN = 5;
+
+    /**
+     * The Constant DST_IN indicates that the part of the destination lying
+     * inside of the source replaces the destination (Porter-Duff Destination In
+     * Source rule).
+     */
+    public static final int DST_IN = 6;
+
+    /**
+     * The Constant SRC_OUT indicates that the part of the source lying outside
+     * of the destination replaces the destination (Porter-Duff Source Held Out
+     * By Destination rule).
+     */
+    public static final int SRC_OUT = 7;
+
+    /**
+     * The Constant DST_OUT indicates that the part of the destination lying
+     * outside of the source replaces the destination (Porter-Duff Destination
+     * Held Out By Source rule).
+     */
+    public static final int DST_OUT = 8;
+
+    /**
+     * The Constant SRC_ATOP indicates that the part of the source lying inside
+     * of the destination is composited onto the destination (Porter-Duff Source
+     * Atop Destination rule).
+     */
+    public static final int SRC_ATOP = 10;
+
+    /**
+     * The Constant DST_ATOP indicates that the part of the destination lying
+     * inside of the source is composited over the source and replaces the
+     * destination (Porter-Duff Destination Atop Source rule).
+     */
+    public static final int DST_ATOP = 11;
+
+    /**
+     * The Constant XOR indicates that the part of the source that lies outside
+     * of the destination is combined with the part of the destination that lies
+     * outside of the source (Porter-Duff Source Xor Destination rule).
+     */
+    public static final int XOR = 12;
+
+    /**
+     * AlphaComposite object with the opaque CLEAR rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
+
+    /**
+     * AlphaComposite object with the opaque SRC rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite Src = new AlphaComposite(SRC);
+
+    /**
+     * AlphaComposite object with the opaque DST rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite Dst = new AlphaComposite(DST);
+
+    /**
+     * AlphaComposite object with the opaque SRC_OVER rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
+
+    /**
+     * AlphaComposite object with the opaque DST_OVER rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
+
+    /**
+     * AlphaComposite object with the opaque SRC_IN rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
+
+    /**
+     * AlphaComposite object with the opaque DST_IN rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
+
+    /**
+     * AlphaComposite object with the opaque SRC_OUT rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
+
+    /**
+     * AlphaComposite object with the opaque DST_OUT rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
+
+    /**
+     * AlphaComposite object with the opaque SRC_ATOP rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
+
+    /**
+     * AlphaComposite object with the opaque DST_ATOP rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
+
+    /**
+     * AlphaComposite object with the opaque XOR rule and an alpha of 1.0f.
+     */
+    public static final AlphaComposite Xor = new AlphaComposite(XOR);
+
+    /**
+     * The rule.
+     */
+    private int rule;
+
+    /**
+     * The alpha.
+     */
+    private float alpha;
+
+    /**
+     * Instantiates a new alpha composite. Creates a context for the compositing
+     * operation. The context contains state that is used in performing the
+     * compositing operation.
+     * 
+     * @param rule
+     *            the rule.
+     * @param alpha
+     *            the alpha.
+     */
+    private AlphaComposite(int rule, float alpha) {
+        if (rule < CLEAR || rule > XOR) {
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+        if (alpha < 0.0f || alpha > 1.0f) {
+            // awt.11E=Wrong alpha value
+            throw new IllegalArgumentException(Messages.getString("awt.11E")); //$NON-NLS-1$
+        }
+
+        this.rule = rule;
+        this.alpha = alpha;
+    }
+
+    /**
+     * Instantiates a new alpha composite.
+     * 
+     * @param rule
+     *            the rule.
+     */
+    private AlphaComposite(int rule) {
+        this(rule, 1.0f);
+    }
+
+    /**
+     * Creates a CompositeContext object with the specified source ColorModel,
+     * destination ColorModel and RenderingHints parameters for a composing
+     * operation.
+     * 
+     * @param srcColorModel
+     *            the source's ColorModel.
+     * @param dstColorModel
+     *            the destination's ColorModel.
+     * @param hints
+     *            the RenderingHints object.
+     * @return the CompositeContext object.
+     * @see java.awt.Composite#createContext(java.awt.image.ColorModel,
+     *      java.awt.image.ColorModel, java.awt.RenderingHints)
+     */
+    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
+            RenderingHints hints) {
+        return new ICompositeContext(this, srcColorModel, dstColorModel);
+    }
+
+    /**
+     * Compares the AlphaComposite object with the specified object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the AlphaComposite object is equal to the specified
+     *         object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof AlphaComposite)) {
+            return false;
+        }
+        AlphaComposite other = (AlphaComposite)obj;
+        return (this.rule == other.getRule() && this.alpha == other.getAlpha());
+    }
+
+    /**
+     * Returns the hash code of the AlphaComposite object.
+     * 
+     * @return the hash code of the AlphaComposite object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = Float.floatToIntBits(alpha);
+        int tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= rule;
+        return hash;
+    }
+
+    /**
+     * Gets the compositing rule of this AlphaComposite object.
+     * 
+     * @return the compositing rule of this AlphaComposite object.
+     */
+    public int getRule() {
+        return rule;
+    }
+
+    /**
+     * Gets the alpha value of this AlphaComposite object; returns 1.0 if this
+     * AlphaComposite object doesn't have alpha value.
+     * 
+     * @return the alpha value of this AlphaComposite object or 1.0 if this
+     *         AlphaComposite object doesn't have alpha value.
+     */
+    public float getAlpha() {
+        return alpha;
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule and alpha value.
+     * 
+     * @param rule
+     *            the compositing rule.
+     * @param alpha
+     *            the alpha value.
+     * @return the AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule, float alpha) {
+        if (alpha == 1.0f) {
+            return getInstance(rule);
+        }
+        return new AlphaComposite(rule, alpha);
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule.
+     * 
+     * @param rule
+     *            the compositing rule.
+     * @return the AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule) {
+        switch (rule) {
+            case CLEAR:
+                return Clear;
+            case SRC:
+                return Src;
+            case DST:
+                return Dst;
+            case SRC_OVER:
+                return SrcOver;
+            case DST_OVER:
+                return DstOver;
+            case SRC_IN:
+                return SrcIn;
+            case DST_IN:
+                return DstIn;
+            case SRC_OUT:
+                return SrcOut;
+            case DST_OUT:
+                return DstOut;
+            case SRC_ATOP:
+                return SrcAtop;
+            case DST_ATOP:
+                return DstAtop;
+            case XOR:
+                return Xor;
+            default:
+                // awt.11D=Unknown rule
+                throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+    }
+
+}
diff --git a/awt/java/awt/BasicStroke.java b/awt/java/awt/BasicStroke.java
new file mode 100644
index 0000000..2457815
--- /dev/null
+++ b/awt/java/awt/BasicStroke.java
@@ -0,0 +1,2443 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The BasicStroke class specifies a set of rendering attributes for the
+ * outlines of graphics primitives. The BasicStroke attributes describe the
+ * shape of the pen which draws the outline of a Shape and the decorations
+ * applied at the ends and joins of path segments of the Shape. The BasicStroke
+ * has the following rendering attributes:
+ * <p>
+ * <ul>
+ * <li>line width -the pen width which draws the outlines.</li>
+ * <li>end caps - indicates the decoration applied to the ends of unclosed
+ * subpaths and dash segments. The BasicStroke defines three different
+ * decorations: CAP_BUTT, CAP_ROUND, and CAP_SQUARE.</li>
+ * <li>line joins - indicates the decoration applied at the intersection of two
+ * path segments and at the intersection of the endpoints of a subpath. The
+ * BasicStroke defines three decorations: JOIN_BEVEL, JOIN_MITER, and
+ * JOIN_ROUND.</li>
+ * <li>miter limit - the limit to trim a line join that has a JOIN_MITER
+ * decoration.</li>
+ * <li>dash attributes - the definition of how to make a dash pattern by
+ * alternating between opaque and transparent sections</li>
+ * </ul>
+ * </p>
+ * 
+ * @since Android 1.0
+ */
+public class BasicStroke implements Stroke {
+
+    /**
+     * The Constant CAP_BUTT indicates the ends of unclosed subpaths and dash
+     * segments have no added decoration.
+     */
+    public static final int CAP_BUTT = 0;
+
+    /**
+     * The Constant CAP_ROUND indicates the ends of unclosed subpaths and dash
+     * segments have a round decoration.
+     */
+    public static final int CAP_ROUND = 1;
+
+    /**
+     * The Constant CAP_SQUARE indicates the ends of unclosed subpaths and dash
+     * segments have a square projection.
+     */
+    public static final int CAP_SQUARE = 2;
+
+    /**
+     * The Constant JOIN_MITER indicates that path segments are joined by
+     * extending their outside edges until they meet.
+     */
+    public static final int JOIN_MITER = 0;
+
+    /**
+     * The Constant JOIN_ROUND indicates that path segments are joined by
+     * rounding off the corner at a radius of half the line width.
+     */
+    public static final int JOIN_ROUND = 1;
+
+    /**
+     * The Constant JOIN_BEVEL indicates that path segments are joined by
+     * connecting the outer corners of their wide outlines with a straight
+     * segment.
+     */
+    public static final int JOIN_BEVEL = 2;
+
+    /**
+     * Constants for calculating.
+     */
+    static final int MAX_LEVEL = 20; // Maximal deepness of curve subdivision
+
+    /**
+     * The Constant CURVE_DELTA.
+     */
+    static final double CURVE_DELTA = 2.0; // Width tolerance
+
+    /**
+     * The Constant CORNER_ANGLE.
+     */
+    static final double CORNER_ANGLE = 4.0; // Minimum corner angle
+
+    /**
+     * The Constant CORNER_ZERO.
+     */
+    static final double CORNER_ZERO = 0.01; // Zero angle
+
+    /**
+     * The Constant CUBIC_ARC.
+     */
+    static final double CUBIC_ARC = 4.0 / 3.0 * (Math.sqrt(2.0) - 1);
+
+    /**
+     * Stroke width.
+     */
+    float width;
+
+    /**
+     * Stroke cap type.
+     */
+    int cap;
+
+    /**
+     * Stroke join type.
+     */
+    int join;
+
+    /**
+     * Stroke miter limit.
+     */
+    float miterLimit;
+
+    /**
+     * Stroke dashes array.
+     */
+    float dash[];
+
+    /**
+     * Stroke dash phase.
+     */
+    float dashPhase;
+
+    /**
+     * The temporary pre-calculated values.
+     */
+    double curveDelta;
+
+    /**
+     * The corner delta.
+     */
+    double cornerDelta;
+
+    /**
+     * The zero delta.
+     */
+    double zeroDelta;
+
+    /**
+     * The w2.
+     */
+    double w2;
+
+    /**
+     * The fmy.
+     */
+    double fmx, fmy;
+
+    /**
+     * The smy.
+     */
+    double scx, scy, smx, smy;
+
+    /**
+     * The cy.
+     */
+    double mx, my, cx, cy;
+
+    /**
+     * The temporary indicators.
+     */
+    boolean isMove;
+
+    /**
+     * The is first.
+     */
+    boolean isFirst;
+
+    /**
+     * The check move.
+     */
+    boolean checkMove;
+
+    /**
+     * The temporary and destination work paths.
+     */
+    BufferedPath dst, lp, rp, sp;
+
+    /**
+     * Stroke dasher class.
+     */
+    Dasher dasher;
+
+    /**
+     * Instantiates a new BasicStroke with default width, cap, join, limit, dash
+     * attributes parameters. The default parameters are a solid line of width
+     * 1.0, CAP_SQUARE, JOIN_MITER, a miter limit of 10.0, null dash attributes,
+     * and a dash phase of 0.0f.
+     */
+    public BasicStroke() {
+        this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with the specified width, caps, joins,
+     * limit, dash attributes, dash phase parameters.
+     * 
+     * @param width
+     *            the width of BasikStroke.
+     * @param cap
+     *            the end decoration of BasikStroke.
+     * @param join
+     *            the join segments decoration.
+     * @param miterLimit
+     *            the limit to trim the miter join.
+     * @param dash
+     *            the array with the dashing pattern.
+     * @param dashPhase
+     *            the offset to start the dashing pattern.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit, float[] dash,
+            float dashPhase) {
+        if (width < 0.0f) {
+            // awt.133=Negative width
+            throw new IllegalArgumentException(Messages.getString("awt.133")); //$NON-NLS-1$
+        }
+        if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
+            // awt.134=Illegal cap
+            throw new IllegalArgumentException(Messages.getString("awt.134")); //$NON-NLS-1$
+        }
+        if (join != JOIN_MITER && join != JOIN_ROUND && join != JOIN_BEVEL) {
+            // awt.135=Illegal join
+            throw new IllegalArgumentException(Messages.getString("awt.135")); //$NON-NLS-1$
+        }
+        if (join == JOIN_MITER && miterLimit < 1.0f) {
+            // awt.136=miterLimit less than 1.0f
+            throw new IllegalArgumentException(Messages.getString("awt.136")); //$NON-NLS-1$
+        }
+        if (dash != null) {
+            if (dashPhase < 0.0f) {
+                // awt.137=Negative dashPhase
+                throw new IllegalArgumentException(Messages.getString("awt.137")); //$NON-NLS-1$
+            }
+            if (dash.length == 0) {
+                // awt.138=Zero dash length
+                throw new IllegalArgumentException(Messages.getString("awt.138")); //$NON-NLS-1$
+            }
+            ZERO: {
+                for (int i = 0; i < dash.length; i++) {
+                    if (dash[i] < 0.0) {
+                        // awt.139=Negative dash[{0}]
+                        throw new IllegalArgumentException(Messages.getString("awt.139", i)); //$NON-NLS-1$
+                    }
+                    if (dash[i] > 0.0) {
+                        break ZERO;
+                    }
+                }
+                // awt.13A=All dash lengths zero
+                throw new IllegalArgumentException(Messages.getString("awt.13A")); //$NON-NLS-1$
+            }
+        }
+        this.width = width;
+        this.cap = cap;
+        this.join = join;
+        this.miterLimit = miterLimit;
+        this.dash = dash;
+        this.dashPhase = dashPhase;
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join, limit and
+     * default dash attributes parameters.
+     * 
+     * @param width
+     *            the width of BasikStroke.
+     * @param cap
+     *            the end decoration of BasikStroke.
+     * @param join
+     *            the join segments decoration.
+     * @param miterLimit
+     *            the limit to trim the miter join.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit) {
+        this(width, cap, join, miterLimit, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join and
+     * default limit and dash attributes parameters.
+     * 
+     * @param width
+     *            the width of BasikStroke.
+     * @param cap
+     *            the end decoration of BasikStroke.
+     * @param join
+     *            the join segments decoration.
+     */
+    public BasicStroke(float width, int cap, int join) {
+        this(width, cap, join, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width and default cap,
+     * join, limit, dash attributes parameters.
+     * 
+     * @param width
+     *            the width of BasicStroke.
+     */
+    public BasicStroke(float width) {
+        this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Gets the line width of the BasicStroke.
+     * 
+     * @return the line width of the BasicStroke.
+     */
+    public float getLineWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the end cap style of the BasicStroke.
+     * 
+     * @return the end cap style of the BasicStroke.
+     */
+    public int getEndCap() {
+        return cap;
+    }
+
+    /**
+     * Gets the line join style of the BasicStroke.
+     * 
+     * @return the line join style of the BasicStroke.
+     */
+    public int getLineJoin() {
+        return join;
+    }
+
+    /**
+     * Gets the miter limit of the BasicStroke (the limit to trim the miter
+     * join).
+     * 
+     * @return the miter limit of the BasicStroke.
+     */
+    public float getMiterLimit() {
+        return miterLimit;
+    }
+
+    /**
+     * Gets the dash attributes array of the BasicStroke.
+     * 
+     * @return the dash attributes array of the BasicStroke.
+     */
+    public float[] getDashArray() {
+        return dash;
+    }
+
+    /**
+     * Gets the dash phase of the BasicStroke.
+     * 
+     * @return the dash phase of the BasicStroke.
+     */
+    public float getDashPhase() {
+        return dashPhase;
+    }
+
+    /**
+     * Returns hash code of this BasicStroke.
+     * 
+     * @return the hash code of this BasicStroke.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(cap);
+        hash.append(join);
+        hash.append(miterLimit);
+        if (dash != null) {
+            hash.append(dashPhase);
+            for (float element : dash) {
+                hash.append(element);
+            }
+        }
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this BasicStroke object with the specified Object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the Object is a BasicStroke with the same data values as
+     *         this BasicStroke; false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof BasicStroke) {
+            BasicStroke bs = (BasicStroke)obj;
+            return bs.width == width && bs.cap == cap && bs.join == join
+                    && bs.miterLimit == miterLimit && bs.dashPhase == dashPhase
+                    && java.util.Arrays.equals(bs.dash, dash);
+        }
+        return false;
+    }
+
+    /**
+     * Calculates allowable curve derivation.
+     * 
+     * @param width
+     *            the width.
+     * @return the curve delta.
+     */
+    double getCurveDelta(double width) {
+        double a = width + CURVE_DELTA;
+        double cos = 1.0 - 2.0 * width * width / (a * a);
+        double sin = Math.sqrt(1.0 - cos * cos);
+        return Math.abs(sin / cos);
+    }
+
+    /**
+     * Calculates the value to detect a small angle.
+     * 
+     * @param width
+     *            the width.
+     * @return the corner delta.
+     */
+    double getCornerDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ANGLE / 180.0);
+    }
+
+    /**
+     * Calculates value to detect a zero angle.
+     * 
+     * @param width
+     *            the width.
+     * @return the zero delta.
+     */
+    double getZeroDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ZERO / 180.0);
+    }
+
+    /**
+     * Creates a Shape from the outline of the specified shape drawn with this
+     * BasicStroke.
+     * 
+     * @param s
+     *            the specified Shape to be stroked.
+     * @return the Shape of the stroked outline.
+     * @see java.awt.Stroke#createStrokedShape(java.awt.Shape)
+     */
+    public Shape createStrokedShape(Shape s) {
+        w2 = width / 2.0;
+        curveDelta = getCurveDelta(w2);
+        cornerDelta = getCornerDelta(w2);
+        zeroDelta = getZeroDelta(w2);
+
+        dst = new BufferedPath();
+        lp = new BufferedPath();
+        rp = new BufferedPath();
+
+        if (dash == null) {
+            createSolidShape(s.getPathIterator(null));
+        } else {
+            createDashedShape(s.getPathIterator(null));
+        }
+
+        return dst.createGeneralPath();
+    }
+
+    /**
+     * Generates a shape with a solid (not dashed) outline.
+     * 
+     * @param p
+     *            the PathIterator of source shape.
+     */
+    void createSolidShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        isMove = false;
+        isFirst = false;
+        checkMove = true;
+        boolean isClosed = true;
+
+        while (!p.isDone()) {
+            switch (p.currentSegment(coords)) {
+                case PathIterator.SEG_MOVETO:
+                    if (!isClosed) {
+                        closeSolidShape();
+                    }
+                    rp.clean();
+                    mx = cx = coords[0];
+                    my = cy = coords[1];
+                    isMove = true;
+                    isClosed = false;
+                    break;
+                case PathIterator.SEG_LINETO:
+                    addLine(cx, cy, cx = coords[0], cy = coords[1], true);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    addQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    addCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4],
+                            cy = coords[5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    addLine(cx, cy, mx, my, false);
+                    addJoin(lp, mx, my, lp.xMove, lp.yMove, true);
+                    addJoin(rp, mx, my, rp.xMove, rp.yMove, false);
+                    lp.closePath();
+                    rp.closePath();
+                    lp.appendReverse(rp);
+                    isClosed = true;
+                    break;
+            }
+            p.next();
+        }
+        if (!isClosed) {
+            closeSolidShape();
+        }
+
+        dst = lp;
+    }
+
+    /**
+     * Closes solid shape path.
+     */
+    void closeSolidShape() {
+        addCap(lp, cx, cy, rp.xLast, rp.yLast);
+        lp.combine(rp);
+        addCap(lp, mx, my, lp.xMove, lp.yMove);
+        lp.closePath();
+    }
+
+    /**
+     * Generates dashed stroked shape.
+     * 
+     * @param p
+     *            the PathIterator of source shape.
+     */
+    void createDashedShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        smx = smy = scx = scy = 0.0;
+        isMove = false;
+        checkMove = false;
+        boolean isClosed = true;
+
+        while (!p.isDone()) {
+            switch (p.currentSegment(coords)) {
+                case PathIterator.SEG_MOVETO:
+
+                    if (!isClosed) {
+                        closeDashedShape();
+                    }
+
+                    dasher = new Dasher(dash, dashPhase);
+                    lp.clean();
+                    rp.clean();
+                    sp = null;
+                    isFirst = true;
+                    isMove = true;
+                    isClosed = false;
+                    mx = cx = coords[0];
+                    my = cy = coords[1];
+                    break;
+                case PathIterator.SEG_LINETO:
+                    addDashLine(cx, cy, cx = coords[0], cy = coords[1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    addDashQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    addDashCubic(cx, cy, coords[0], coords[1], coords[2], coords[3],
+                            cx = coords[4], cy = coords[5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    addDashLine(cx, cy, cx = mx, cy = my);
+
+                    if (dasher.isConnected()) {
+                        // Connect current and head segments
+                        addJoin(lp, fmx, fmy, sp.xMove, sp.yMove, true);
+                        lp.join(sp);
+                        addJoin(lp, fmx, fmy, rp.xLast, rp.yLast, true);
+                        lp.combine(rp);
+                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                        lp.closePath();
+                        dst.append(lp);
+                        sp = null;
+                    } else {
+                        closeDashedShape();
+                    }
+
+                    isClosed = true;
+                    break;
+            }
+            p.next();
+        }
+
+        if (!isClosed) {
+            closeDashedShape();
+        }
+
+    }
+
+    /**
+     * Closes dashed shape path.
+     */
+    void closeDashedShape() {
+        // Add head segment
+        if (sp != null) {
+            addCap(sp, fmx, fmy, sp.xMove, sp.yMove);
+            sp.closePath();
+            dst.append(sp);
+        }
+        if (lp.typeSize > 0) {
+            // Close current segment
+            if (!dasher.isClosed()) {
+                addCap(lp, scx, scy, rp.xLast, rp.yLast);
+                lp.combine(rp);
+                addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                lp.closePath();
+            }
+            dst.append(lp);
+        }
+    }
+
+    /**
+     * Adds cap to the work path.
+     * 
+     * @param p
+     *            the BufferedPath object of work path.
+     * @param x0
+     *            the x coordinate of the source path.
+     * @param y0
+     *            the y coordinate on the source path.
+     * @param x2
+     *            the x coordinate of the next point on the work path.
+     * @param y2
+     *            the y coordinate of the next point on the work path.
+     */
+    void addCap(BufferedPath p, double x0, double y0, double x2, double y2) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        switch (cap) {
+            case CAP_BUTT:
+                p.lineTo(x2, y2);
+                break;
+            case CAP_ROUND:
+                double mx = x10 * CUBIC_ARC;
+                double my = y10 * CUBIC_ARC;
+
+                double x3 = x0 + y10;
+                double y3 = y0 - x10;
+
+                x10 *= CUBIC_ARC;
+                y10 *= CUBIC_ARC;
+                x20 *= CUBIC_ARC;
+                y20 *= CUBIC_ARC;
+
+                p.cubicTo(x1 + y10, y1 - x10, x3 + mx, y3 + my, x3, y3);
+                p.cubicTo(x3 - mx, y3 - my, x2 - y20, y2 + x20, x2, y2);
+                break;
+            case CAP_SQUARE:
+                p.lineTo(x1 + y10, y1 - x10);
+                p.lineTo(x2 - y20, y2 + x20);
+                p.lineTo(x2, y2);
+                break;
+        }
+    }
+
+    /**
+     * Adds bevel and miter join to the work path.
+     * 
+     * @param p
+     *            the BufferedPath object of work path.
+     * @param x0
+     *            the x coordinate of the source path.
+     * @param y0
+     *            the y coordinate on the source path.
+     * @param x2
+     *            the x coordinate of the next point on the work path.
+     * @param y2
+     *            the y coordinate of the next point on the work path.
+     * @param isLeft
+     *            the orientation of work path, true if work path lies to the
+     *            left from source path, false otherwise.
+     */
+    void addJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+        double sin0 = x10 * y20 - y10 * x20;
+
+        // Small corner
+        if (-cornerDelta < sin0 && sin0 < cornerDelta) {
+            double cos0 = x10 * x20 + y10 * y20;
+            if (cos0 > 0.0) {
+                // if zero corner do nothing
+                if (-zeroDelta > sin0 || sin0 > zeroDelta) {
+                    double x3 = x0 + w2 * w2 * (y20 - y10) / sin0;
+                    double y3 = y0 + w2 * w2 * (x10 - x20) / sin0;
+                    p.setLast(x3, y3);
+                }
+                return;
+            }
+            // Zero corner
+            if (-zeroDelta < sin0 && sin0 < zeroDelta) {
+                p.lineTo(x2, y2);
+            }
+            return;
+        }
+
+        if (isLeft ^ (sin0 < 0.0)) {
+            // Twisted corner
+            p.lineTo(x0, y0);
+            p.lineTo(x2, y2);
+        } else {
+            switch (join) {
+                case JOIN_BEVEL:
+                    p.lineTo(x2, y2);
+                    break;
+                case JOIN_MITER:
+                    double s1 = x1 * x10 + y1 * y10;
+                    double s2 = x2 * x20 + y2 * y20;
+                    double x3 = (s1 * y20 - s2 * y10) / sin0;
+                    double y3 = (s2 * x10 - s1 * x20) / sin0;
+                    double x30 = x3 - x0;
+                    double y30 = y3 - y0;
+                    double miterLength = Math.sqrt(x30 * x30 + y30 * y30);
+                    if (miterLength < miterLimit * w2) {
+                        p.lineTo(x3, y3);
+                    }
+                    p.lineTo(x2, y2);
+                    break;
+                case JOIN_ROUND:
+                    addRoundJoin(p, x0, y0, x2, y2, isLeft);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Adds round join to the work path.
+     * 
+     * @param p
+     *            the BufferedPath object of work path.
+     * @param x0
+     *            the x coordinate of the source path.
+     * @param y0
+     *            the y coordinate on the source path.
+     * @param x2
+     *            the x coordinate of the next point on the work path.
+     * @param y2
+     *            the y coordinate of the next point on the work path.
+     * @param isLeft
+     *            the orientation of work path, true if work path lies to the
+     *            left from source path, false otherwise.
+     */
+    void addRoundJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        double x30 = x10 + x20;
+        double y30 = y10 + y20;
+
+        double l30 = Math.sqrt(x30 * x30 + y30 * y30);
+
+        if (l30 < 1E-5) {
+            p.lineTo(x2, y2);
+            return;
+        }
+
+        double w = w2 / l30;
+
+        x30 *= w;
+        y30 *= w;
+
+        double x3 = x0 + x30;
+        double y3 = y0 + y30;
+
+        double cos = x10 * x20 + y10 * y20;
+        double a = Math.acos(cos / (w2 * w2));
+        if (cos >= 0.0) {
+            double k = 4.0 / 3.0 * Math.tan(a / 4.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x2 + y20, y2 - x20, x2, y2);
+        } else {
+            double k = 4.0 / 3.0 * Math.tan(a / 8.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+            x30 *= k;
+            y30 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x3 + y30, y3 - x30, x3, y3);
+            p.cubicTo(x3 - y30, y3 + x30, x2 + y20, y2 - x20, x2, y2);
+        }
+
+    }
+
+    /**
+     * Adds solid line segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the start line point.
+     * @param y1
+     *            the y coordinate of the start line point.
+     * @param x2
+     *            the x coordinate of the end line point.
+     * @param y2
+     *            the y coordinate of the end line point.
+     * @param zero
+     *            if true it's allowable to add zero length line segment.
+     */
+    void addLine(double x1, double y1, double x2, double y2, boolean zero) {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+
+        if (dx == 0.0 && dy == 0.0) {
+            if (!zero) {
+                return;
+            }
+            dx = w2;
+            dy = 0;
+        } else {
+            double w = w2 / Math.sqrt(dx * dx + dy * dy);
+            dx *= w;
+            dy *= w;
+        }
+
+        double lx1 = x1 - dy;
+        double ly1 = y1 + dx;
+        double rx1 = x1 + dy;
+        double ry1 = y1 - dx;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        lp.lineTo(x2 - dy, y2 + dx);
+        rp.lineTo(x2 + dy, y2 - dx);
+    }
+
+    /**
+     * Adds solid quad segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     */
+    void addQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            addLine(x1, y1, x3, y3, false);
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        double w;
+        w = w2 / l21;
+        double mx1 = -y21 * w;
+        double my1 = x21 * w;
+        w = w2 / l23;
+        double mx3 = y23 * w;
+        double my3 = -x23 * w;
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (x21 * y23 - y21 * x23 == 0.0) {
+            // On line curve
+            if (x21 * x23 + y21 * y23 > 0.0) {
+                // Twisted curve
+                if (l21 == l23) {
+                    double px = x1 + (x21 + x23) / 4.0;
+                    double py = y1 + (y21 + y23) / 4.0;
+                    lp.lineTo(px + mx1, py + my1);
+                    rp.lineTo(px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    lp.lineTo(x3 - mx1, y3 - my1);
+                    rp.lineTo(x3 + mx1, y3 + my1);
+                } else {
+                    double px1, py1;
+                    double k = l21 / (l21 + l23);
+                    double px = x1 + (x21 + x23) * k * k;
+                    double py = y1 + (y21 + y23) * k * k;
+                    px1 = (x1 + px) / 2.0;
+                    py1 = (y1 + py) / 2.0;
+                    lp.quadTo(px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.quadTo(px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    px1 = (x3 + px) / 2.0;
+                    py1 = (y3 + py) / 2.0;
+                    lp.quadTo(px1 - mx1, py1 - my1, x3 - mx1, y3 - my1);
+                    rp.quadTo(px1 + mx1, py1 + my1, x3 + mx1, y3 + my1);
+                }
+            } else {
+                // Simple curve
+                lp.quadTo(x2 + mx1, y2 + my1, x3 + mx3, y3 + my3);
+                rp.quadTo(x2 - mx1, y2 - my1, x3 - mx3, y3 - my3);
+            }
+        } else {
+            addSubQuad(x1, y1, x2, y2, x3, y3, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid quad curve to make outline for source quad segment and
+     * adds it to work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     * @param level
+     *            the maximum level of subdivision deepness.
+     */
+    void addSubQuad(double x1, double y1, double x2, double y2, double x3, double y3, int level) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double cos = x21 * x23 + y21 * y23;
+        double sin = x21 * y23 - y21 * x23;
+
+        if (level < MAX_LEVEL && (cos >= 0.0 || (Math.abs(sin / cos) > curveDelta))) {
+            double c1x = (x2 + x1) / 2.0;
+            double c1y = (y2 + y1) / 2.0;
+            double c2x = (x2 + x3) / 2.0;
+            double c2y = (y2 + y3) / 2.0;
+            double c3x = (c1x + c2x) / 2.0;
+            double c3y = (c1y + c2y) / 2.0;
+            addSubQuad(x1, y1, c1x, c1y, c3x, c3y, level + 1);
+            addSubQuad(c3x, c3y, c2x, c2y, x3, y3, level + 1);
+        } else {
+            double w;
+            double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            w = w2 / sin;
+            double mx2 = (x21 * l23 + x23 * l21) * w;
+            double my2 = (y21 * l23 + y23 * l21) * w;
+            w = w2 / l23;
+            double mx3 = y23 * w;
+            double my3 = -x23 * w;
+            lp.quadTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3);
+            rp.quadTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3);
+        }
+    }
+
+    /**
+     * Adds solid cubic segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     * @param x4
+     *            the x coordinate of the fours control point.
+     * @param y4
+     *            the y coordinate of the fours control point.
+     */
+    void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
+            double y4) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x4, y4, false);
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addLine(x3, y3, x4, y4, false);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        double w, mx1, my1, mx4, my4;
+        boolean onLine;
+
+        if (l12 == 0.0) {
+            w = w2 / l23;
+            mx1 = y23 * w;
+            my1 = -x23 * w;
+            w = w2 / l34;
+            mx4 = y34 * w;
+            my4 = -x34 * w;
+            onLine = -x23 * y34 + y23 * x34 == 0.0; // sin3
+        } else if (l34 == 0.0) {
+            w = w2 / l12;
+            mx1 = y12 * w;
+            my1 = -x12 * w;
+            w = w2 / l23;
+            mx4 = y23 * w;
+            my4 = -x23 * w;
+            onLine = -x12 * y23 + y12 * x23 == 0.0; // sin2
+        } else {
+            w = w2 / l12;
+            mx1 = y12 * w;
+            my1 = -x12 * w;
+            w = w2 / l34;
+            mx4 = y34 * w;
+            my4 = -x34 * w;
+            if (l23 == 0.0) {
+                onLine = -x12 * y34 + y12 * x34 == 0.0;
+            } else {
+                onLine = -x12 * y34 + y12 * x34 == 0.0 && -x12 * y23 + y12 * x23 == 0.0 && // sin2
+                        -x23 * y34 + y23 * x34 == 0.0; // sin3
+            }
+        }
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (onLine) {
+            if ((x1 == x2 && y1 < y2) || x1 < x2) {
+                l12 = -l12;
+            }
+            if ((x2 == x3 && y2 < y3) || x2 < x3) {
+                l23 = -l23;
+            }
+            if ((x3 == x4 && y3 < y4) || x3 < x4) {
+                l34 = -l34;
+            }
+            double d = l23 * l23 - l12 * l34;
+            double roots[] = new double[3];
+            int rc = 0;
+            if (d == 0.0) {
+                double t = (l12 - l23) / (l12 + l34 - l23 - l23);
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            } else if (d > 0.0) {
+                d = Math.sqrt(d);
+                double z = l12 + l34 - l23 - l23;
+                double t;
+                t = (l12 - l23 + d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+                t = (l12 - l23 - d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            }
+
+            if (rc > 0) {
+                // Sort roots
+                if (rc == 2 && roots[0] > roots[1]) {
+                    double tmp = roots[0];
+                    roots[0] = roots[1];
+                    roots[1] = tmp;
+                }
+                roots[rc++] = 1.0;
+
+                double ax = -x34 - x12 + x23 + x23;
+                double ay = -y34 - y12 + y23 + y23;
+                double bx = 3.0 * (-x23 + x12);
+                double by = 3.0 * (-y23 + y12);
+                double cx = 3.0 * (-x12);
+                double cy = 3.0 * (-y12);
+                double xPrev = x1;
+                double yPrev = y1;
+                for (int i = 0; i < rc; i++) {
+                    double t = roots[i];
+                    double px = t * (t * (t * ax + bx) + cx) + x1;
+                    double py = t * (t * (t * ay + by) + cy) + y1;
+                    double px1 = (xPrev + px) / 2.0;
+                    double py1 = (yPrev + py) / 2.0;
+                    lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    if (i < rc - 1) {
+                        lp.lineTo(px - mx1, py - my1);
+                        rp.lineTo(px + mx1, py + my1);
+                    }
+                    xPrev = px;
+                    yPrev = py;
+                    mx1 = -mx1;
+                    my1 = -my1;
+                }
+            } else {
+                lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
+                rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
+            }
+        } else {
+            addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid cubic curve to make outline for source quad segment and
+     * adds it to work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     * @param x4
+     *            the x coordinate of the fours control point.
+     * @param y4
+     *            the y coordinate of the fours control point.
+     * @param level
+     *            the maximum level of subdivision deepness.
+     */
+    void addSubCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
+            double y4, int level) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double cos2 = -x12 * x23 - y12 * y23;
+        double cos3 = -x23 * x34 - y23 * y34;
+        double sin2 = -x12 * y23 + y12 * x23;
+        double sin3 = -x23 * y34 + y23 * x34;
+        double sin0 = -x12 * y34 + y12 * x34;
+        double cos0 = -x12 * x34 - y12 * y34;
+
+        if (level < MAX_LEVEL
+                && (sin2 != 0.0 || sin3 != 0.0 || sin0 != 0.0)
+                && (cos2 >= 0.0 || cos3 >= 0.0 || cos0 >= 0.0
+                        || (Math.abs(sin2 / cos2) > curveDelta)
+                        || (Math.abs(sin3 / cos3) > curveDelta) || (Math.abs(sin0 / cos0) > curveDelta))) {
+            double cx = (x2 + x3) / 2.0;
+            double cy = (y2 + y3) / 2.0;
+            double lx2 = (x2 + x1) / 2.0;
+            double ly2 = (y2 + y1) / 2.0;
+            double rx3 = (x3 + x4) / 2.0;
+            double ry3 = (y3 + y4) / 2.0;
+            double lx3 = (cx + lx2) / 2.0;
+            double ly3 = (cy + ly2) / 2.0;
+            double rx2 = (cx + rx3) / 2.0;
+            double ry2 = (cy + ry3) / 2.0;
+            cx = (lx3 + rx2) / 2.0;
+            cy = (ly3 + ry2) / 2.0;
+            addSubCubic(x1, y1, lx2, ly2, lx3, ly3, cx, cy, level + 1);
+            addSubCubic(cx, cy, rx2, ry2, rx3, ry3, x4, y4, level + 1);
+        } else {
+            double w, mx1, my1, mx2, my2, mx3, my3, mx4, my4;
+            double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+            if (l12 == 0.0) {
+                w = w2 / l23;
+                mx1 = y23 * w;
+                my1 = -x23 * w;
+                w = w2 / l34;
+                mx4 = y34 * w;
+                my4 = -x34 * w;
+            } else if (l34 == 0.0) {
+                w = w2 / l12;
+                mx1 = y12 * w;
+                my1 = -x12 * w;
+                w = w2 / l23;
+                mx4 = y23 * w;
+                my4 = -x23 * w;
+            } else {
+                // Common case
+                w = w2 / l12;
+                mx1 = y12 * w;
+                my1 = -x12 * w;
+                w = w2 / l34;
+                mx4 = y34 * w;
+                my4 = -x34 * w;
+            }
+
+            if (sin2 == 0.0) {
+                mx2 = mx1;
+                my2 = my1;
+            } else {
+                w = w2 / sin2;
+                mx2 = -(x12 * l23 - x23 * l12) * w;
+                my2 = -(y12 * l23 - y23 * l12) * w;
+            }
+            if (sin3 == 0.0) {
+                mx3 = mx4;
+                my3 = my4;
+            } else {
+                w = w2 / sin3;
+                mx3 = -(x23 * l34 - x34 * l23) * w;
+                my3 = -(y23 * l34 - y34 * l23) * w;
+            }
+
+            lp.cubicTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3, x4 + mx4, y4 + my4);
+            rp.cubicTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3, x4 - mx4, y4 - my4);
+        }
+    }
+
+    /**
+     * Adds dashed line segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the start line point.
+     * @param y1
+     *            the y coordinate of the start line point.
+     * @param x2
+     *            the x coordinate of the end line point.
+     * @param y2
+     *            the y coordinate of the end line point.
+     */
+    void addDashLine(double x1, double y1, double x2, double y2) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+
+        if (l21 == 0.0) {
+            return;
+        }
+
+        double px1, py1;
+        px1 = py1 = 0.0;
+        double w = w2 / l21;
+        double mx = -y21 * w;
+        double my = x21 * w;
+
+        dasher.init(new DashIterator.Line(l21));
+
+        while (!dasher.eof()) {
+            double t = dasher.getValue();
+            scx = x1 + t * x21;
+            scy = y1 + t * y21;
+
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double lx1 = px1 + mx;
+                double ly1 = py1 + my;
+                double rx1 = px1 - mx;
+                double ry1 = py1 - my;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else if (dasher.isContinue()) {
+                double px2 = scx;
+                double py2 = scy;
+                lp.lineTo(px2 + mx, py2 + my);
+                rp.lineTo(px2 - mx, py2 - my);
+                if (dasher.close) {
+                    addCap(lp, px2, py2, rp.xLast, rp.yLast);
+                    lp.combine(rp);
+                    if (isFirst) {
+                        isFirst = false;
+                        fmx = smx;
+                        fmy = smy;
+                        sp = lp;
+                        lp = new BufferedPath();
+                    } else {
+                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                        lp.closePath();
+                    }
+                    isMove = true;
+                }
+            }
+
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed quad segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     */
+    void addDashQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        double ax = x1 + x3 - x2 - x2;
+        double ay = y1 + y3 - y2 - y2;
+        double bx = x2 - x1;
+        double by = y2 - y1;
+        double cx = x1;
+        double cy = y1;
+
+        double px1, py1, dx1, dy1;
+        px1 = py1 = dx1 = dy1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Quad(x1, y1, x2, y2, x3, y3));
+
+        while (!dasher.eof()) {
+            double t = dasher.getValue();
+            double dx = t * ax + bx;
+            double dy = t * ay + by;
+            scx = t * (dx + bx) + cx; // t^2 * ax + 2.0 * t * bx + cx
+            scy = t * (dy + by) + cy; // t^2 * ay + 2.0 * t * by + cy
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                dx1 = dx;
+                dy1 = dy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = -dy1 * w;
+                double my1 = dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else if (dasher.isContinue()) {
+                double px3 = scx;
+                double py3 = scy;
+                double sx = x2 - x23 * prev;
+                double sy = y2 - y23 * prev;
+                double t2 = (t - prev) / (1 - prev);
+                double px2 = px1 + (sx - px1) * t2;
+                double py2 = py1 + (sy - py1) * t2;
+
+                addQuad(px1, py1, px2, py2, px3, py3);
+                if (dasher.isClosed()) {
+                    addCap(lp, px3, py3, rp.xLast, rp.yLast);
+                    lp.combine(rp);
+                    if (isFirst) {
+                        isFirst = false;
+                        fmx = smx;
+                        fmy = smy;
+                        sp = lp;
+                        lp = new BufferedPath();
+                    } else {
+                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                        lp.closePath();
+                    }
+                    isMove = true;
+                }
+            }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed cubic segment to the work path.
+     * 
+     * @param x1
+     *            the x coordinate of the first control point.
+     * @param y1
+     *            the y coordinate of the first control point.
+     * @param x2
+     *            the x coordinate of the second control point.
+     * @param y2
+     *            the y coordinate of the second control point.
+     * @param x3
+     *            the x coordinate of the third control point.
+     * @param y3
+     *            the y coordinate of the third control point.
+     * @param x4
+     *            the x coordinate of the fours control point.
+     * @param y4
+     *            the y coordinate of the fours control point.
+     */
+    void addDashCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
+            double y4) {
+
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            // NOTHING
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addDashLine(x3, y3, x4, y4);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        double ax = x4 - x1 + 3.0 * (x2 - x3);
+        double ay = y4 - y1 + 3.0 * (y2 - y3);
+        double bx = 3.0 * (x1 + x3 - x2 - x2);
+        double by = 3.0 * (y1 + y3 - y2 - y2);
+        double cx = 3.0 * (x2 - x1);
+        double cy = 3.0 * (y2 - y1);
+        double dx = x1;
+        double dy = y1;
+
+        double px1 = 0.0;
+        double py1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Cubic(x1, y1, x2, y2, x3, y3, x4, y4));
+
+        while (!dasher.eof()) {
+
+            double t = dasher.getValue();
+            scx = t * (t * (t * ax + bx) + cx) + dx;
+            scy = t * (t * (t * ay + by) + cy) + dy;
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double dx1 = t * (t * (ax + ax + ax) + bx + bx) + cx;
+                double dy1 = t * (t * (ay + ay + ay) + by + by) + cy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = -dy1 * w;
+                double my1 = dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else if (dasher.isContinue()) {
+                double sx1 = x2 - x23 * prev;
+                double sy1 = y2 - y23 * prev;
+                double sx2 = x3 - x34 * prev;
+                double sy2 = y3 - y34 * prev;
+                double sx3 = sx1 + (sx2 - sx1) * prev;
+                double sy3 = sy1 + (sy2 - sy1) * prev;
+                double t2 = (t - prev) / (1 - prev);
+                double sx4 = sx3 + (sx2 - sx3) * t2;
+                double sy4 = sy3 + (sy2 - sy3) * t2;
+
+                double px4 = scx;
+                double py4 = scy;
+                double px2 = px1 + (sx3 - px1) * t2;
+                double py2 = py1 + (sy3 - py1) * t2;
+                double px3 = px2 + (sx4 - px2) * t2;
+                double py3 = py2 + (sy4 - py2) * t2;
+
+                addCubic(px1, py1, px2, py2, px3, py3, px4, py4);
+                if (dasher.isClosed()) {
+                    addCap(lp, px4, py4, rp.xLast, rp.yLast);
+                    lp.combine(rp);
+                    if (isFirst) {
+                        isFirst = false;
+                        fmx = smx;
+                        fmy = smy;
+                        sp = lp;
+                        lp = new BufferedPath();
+                    } else {
+                        addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                        lp.closePath();
+                    }
+                    isMove = true;
+                }
+            }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Dasher class provides dashing for particular dash style.
+     */
+    class Dasher {
+
+        /**
+         * The pos.
+         */
+        double pos;
+
+        /**
+         * The first.
+         */
+        boolean close, visible, first;
+
+        /**
+         * The dash.
+         */
+        float dash[];
+
+        /**
+         * The phase.
+         */
+        float phase;
+
+        /**
+         * The index.
+         */
+        int index;
+
+        /**
+         * The iter.
+         */
+        DashIterator iter;
+
+        /**
+         * Instantiates a new dasher.
+         * 
+         * @param dash
+         *            the dash.
+         * @param phase
+         *            the phase.
+         */
+        Dasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+            index = 0;
+            pos = phase;
+            visible = true;
+            while (pos >= dash[index]) {
+                visible = !visible;
+                pos -= dash[index];
+                index = (index + 1) % dash.length;
+            }
+            pos = -pos;
+            first = visible;
+        }
+
+        /**
+         * Inits the.
+         * 
+         * @param iter
+         *            the iter.
+         */
+        void init(DashIterator iter) {
+            this.iter = iter;
+            close = true;
+        }
+
+        /**
+         * Checks if is open.
+         * 
+         * @return true, if is open.
+         */
+        boolean isOpen() {
+            return visible && pos < iter.length;
+        }
+
+        /**
+         * Checks if is continue.
+         * 
+         * @return true, if is continue.
+         */
+        boolean isContinue() {
+            return !visible && pos > 0;
+        }
+
+        /**
+         * Checks if is closed.
+         * 
+         * @return true, if is closed.
+         */
+        boolean isClosed() {
+            return close;
+        }
+
+        /**
+         * Checks if is connected.
+         * 
+         * @return true, if is connected.
+         */
+        boolean isConnected() {
+            return first && !close;
+        }
+
+        /**
+         * Eof.
+         * 
+         * @return true, if successful.
+         */
+        boolean eof() {
+            if (!close) {
+                pos -= iter.length;
+                return true;
+            }
+            if (pos >= iter.length) {
+                if (visible) {
+                    pos -= iter.length;
+                    return true;
+                }
+                close = pos == iter.length;
+            }
+            return false;
+        }
+
+        /**
+         * Next.
+         */
+        void next() {
+            if (close) {
+                pos += dash[index];
+                index = (index + 1) % dash.length;
+            } else {
+                // Go back
+                index = (index + dash.length - 1) % dash.length;
+                pos -= dash[index];
+            }
+            visible = !visible;
+        }
+
+        /**
+         * Gets the value.
+         * 
+         * @return the value.
+         */
+        double getValue() {
+            double t = iter.getNext(pos);
+            return t < 0 ? 0 : (t > 1 ? 1 : t);
+        }
+
+    }
+
+    /**
+     * DashIterator class provides dashing for particular segment type.
+     */
+    static abstract class DashIterator {
+
+        /**
+         * The Constant FLATNESS.
+         */
+        static final double FLATNESS = 1.0;
+
+        /**
+         * The Class Line.
+         */
+        static class Line extends DashIterator {
+
+            /**
+             * Instantiates a new line.
+             * 
+             * @param len
+             *            the len.
+             */
+            Line(double len) {
+                length = len;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                return dashPos / length;
+            }
+
+        }
+
+        /**
+         * The Class Quad.
+         */
+        static class Quad extends DashIterator {
+
+            /**
+             * The val size.
+             */
+            int valSize;
+
+            /**
+             * The val pos.
+             */
+            int valPos;
+
+            /**
+             * The cur len.
+             */
+            double curLen;
+
+            /**
+             * The prev len.
+             */
+            double prevLen;
+
+            /**
+             * The last len.
+             */
+            double lastLen;
+
+            /**
+             * The values.
+             */
+            double[] values;
+
+            /**
+             * The step.
+             */
+            double step;
+
+            /**
+             * Instantiates a new quad.
+             * 
+             * @param x1
+             *            the x1.
+             * @param y1
+             *            the y1.
+             * @param x2
+             *            the x2.
+             * @param y2
+             *            the y2.
+             * @param x3
+             *            the x3.
+             * @param y3
+             *            the y3.
+             */
+            Quad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+                double nx = x1 + x3 - x2 - x2;
+                double ny = y1 + y3 - y2 - y2;
+
+                int n = (int)(1 + Math.sqrt(0.75 * (Math.abs(nx) + Math.abs(ny)) * FLATNESS));
+                step = 1.0 / n;
+
+                double ax = x1 + x3 - x2 - x2;
+                double ay = y1 + y3 - y2 - y2;
+                double bx = 2.0 * (x2 - x1);
+                double by = 2.0 * (y2 - y1);
+
+                double dx1 = step * (step * ax + bx);
+                double dy1 = step * (step * ay + by);
+                double dx2 = step * (step * ax * 2.0);
+                double dy2 = step * (step * ay * 2.0);
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for (int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /**
+         * The Class Cubic.
+         */
+        static class Cubic extends DashIterator {
+
+            /**
+             * The val size.
+             */
+            int valSize;
+
+            /**
+             * The val pos.
+             */
+            int valPos;
+
+            /**
+             * The cur len.
+             */
+            double curLen;
+
+            /**
+             * The prev len.
+             */
+            double prevLen;
+
+            /**
+             * The last len.
+             */
+            double lastLen;
+
+            /**
+             * The values.
+             */
+            double[] values;
+
+            /**
+             * The step.
+             */
+            double step;
+
+            /**
+             * Instantiates a new cubic.
+             * 
+             * @param x1
+             *            the x1.
+             * @param y1
+             *            the y1.
+             * @param x2
+             *            the x2.
+             * @param y2
+             *            the y2.
+             * @param x3
+             *            the x3.
+             * @param y3
+             *            the y3.
+             * @param x4
+             *            the x4.
+             * @param y4
+             *            the y4.
+             */
+            Cubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4,
+                    double y4) {
+
+                double nx1 = x1 + x3 - x2 - x2;
+                double ny1 = y1 + y3 - y2 - y2;
+                double nx2 = x2 + x4 - x3 - x3;
+                double ny2 = y2 + y4 - y3 - y3;
+
+                double max = Math.max(Math.abs(nx1) + Math.abs(ny1), Math.abs(nx2) + Math.abs(ny2));
+                int n = (int)(1 + Math.sqrt(0.75 * max) * FLATNESS);
+                step = 1.0 / n;
+
+                double ax = x4 - x1 + 3.0 * (x2 - x3);
+                double ay = y4 - y1 + 3.0 * (y2 - y3);
+                double bx = 3.0 * (x1 + x3 - x2 - x2);
+                double by = 3.0 * (y1 + y3 - y2 - y2);
+                double cx = 3.0 * (x2 - x1);
+                double cy = 3.0 * (y2 - y1);
+
+                double dx1 = step * (step * (step * ax + bx) + cx);
+                double dy1 = step * (step * (step * ay + by) + cy);
+                double dx2 = step * (step * (step * ax * 6.0 + bx * 2.0));
+                double dy2 = step * (step * (step * ay * 6.0 + by * 2.0));
+                double dx3 = step * (step * (step * ax * 6.0));
+                double dy3 = step * (step * (step * ay * 6.0));
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for (int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    dx2 += dx3;
+                    dy2 += dy3;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /**
+         * The length.
+         */
+        double length;
+
+        /**
+         * Gets the next.
+         * 
+         * @param dashPos
+         *            the dash pos.
+         * @return the next.
+         */
+        abstract double getNext(double dashPos);
+
+    }
+
+    /**
+     * BufferedPath class provides work path storing and processing.
+     */
+    static class BufferedPath {
+
+        /**
+         * The Constant bufCapacity.
+         */
+        private static final int bufCapacity = 10;
+
+        /**
+         * The point shift.
+         */
+        static int pointShift[] = {
+                2, // MOVETO
+                2, // LINETO
+                4, // QUADTO
+                6, // CUBICTO
+                0
+        }; // CLOSE
+
+        /**
+         * The types.
+         */
+        byte[] types;
+
+        /**
+         * The points.
+         */
+        float[] points;
+
+        /**
+         * The type size.
+         */
+        int typeSize;
+
+        /**
+         * The point size.
+         */
+        int pointSize;
+
+        /**
+         * The x last.
+         */
+        float xLast;
+
+        /**
+         * The y last.
+         */
+        float yLast;
+
+        /**
+         * The x move.
+         */
+        float xMove;
+
+        /**
+         * The y move.
+         */
+        float yMove;
+
+        /**
+         * Instantiates a new buffered path.
+         */
+        public BufferedPath() {
+            types = new byte[bufCapacity];
+            points = new float[bufCapacity * 2];
+        }
+
+        /**
+         * Check buf.
+         * 
+         * @param typeCount
+         *            the type count.
+         * @param pointCount
+         *            the point count.
+         */
+        void checkBuf(int typeCount, int pointCount) {
+            if (typeSize + typeCount > types.length) {
+                byte tmp[] = new byte[typeSize + Math.max(bufCapacity, typeCount)];
+                System.arraycopy(types, 0, tmp, 0, typeSize);
+                types = tmp;
+            }
+            if (pointSize + pointCount > points.length) {
+                float tmp[] = new float[pointSize + Math.max(bufCapacity * 2, pointCount)];
+                System.arraycopy(points, 0, tmp, 0, pointSize);
+                points = tmp;
+            }
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty.
+         */
+        boolean isEmpty() {
+            return typeSize == 0;
+        }
+
+        /**
+         * Clean.
+         */
+        void clean() {
+            typeSize = 0;
+            pointSize = 0;
+        }
+
+        /**
+         * Move to.
+         * 
+         * @param x
+         *            the x.
+         * @param y
+         *            the y.
+         */
+        void moveTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = xMove = (float)x;
+            points[pointSize++] = yMove = (float)y;
+        }
+
+        /**
+         * Line to.
+         * 
+         * @param x
+         *            the x.
+         * @param y
+         *            the y.
+         */
+        void lineTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_LINETO;
+            points[pointSize++] = xLast = (float)x;
+            points[pointSize++] = yLast = (float)y;
+        }
+
+        /**
+         * Quad to.
+         * 
+         * @param x1
+         *            the x1.
+         * @param y1
+         *            the y1.
+         * @param x2
+         *            the x2.
+         * @param y2
+         *            the y2.
+         */
+        void quadTo(double x1, double y1, double x2, double y2) {
+            checkBuf(1, 4);
+            types[typeSize++] = PathIterator.SEG_QUADTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = xLast = (float)x2;
+            points[pointSize++] = yLast = (float)y2;
+        }
+
+        /**
+         * Cubic to.
+         * 
+         * @param x1
+         *            the x1.
+         * @param y1
+         *            the y1.
+         * @param x2
+         *            the x2.
+         * @param y2
+         *            the y2.
+         * @param x3
+         *            the x3.
+         * @param y3
+         *            the y3.
+         */
+        void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) {
+            checkBuf(1, 6);
+            types[typeSize++] = PathIterator.SEG_CUBICTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = (float)x2;
+            points[pointSize++] = (float)y2;
+            points[pointSize++] = xLast = (float)x3;
+            points[pointSize++] = yLast = (float)y3;
+        }
+
+        /**
+         * Close path.
+         */
+        void closePath() {
+            checkBuf(1, 0);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+
+        /**
+         * Sets the last.
+         * 
+         * @param x
+         *            the x.
+         * @param y
+         *            the y.
+         */
+        void setLast(double x, double y) {
+            points[pointSize - 2] = xLast = (float)x;
+            points[pointSize - 1] = yLast = (float)y;
+        }
+
+        /**
+         * Append.
+         * 
+         * @param p
+         *            the p.
+         */
+        void append(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            System.arraycopy(p.points, 0, points, pointSize, p.pointSize);
+            System.arraycopy(p.types, 0, types, typeSize, p.typeSize);
+            pointSize += p.pointSize;
+            typeSize += p.typeSize;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Append reverse.
+         * 
+         * @param p
+         *            the p.
+         */
+        void appendReverse(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            // Skip last point, beacause it's the first point of the second path
+            for (int i = p.pointSize - 2; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            int closeIndex = 0;
+            for (int i = p.typeSize - 1; i >= 0; i--) {
+                byte type = p.types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    types[closeIndex] = PathIterator.SEG_MOVETO;
+                    types[typeSize++] = PathIterator.SEG_CLOSE;
+                } else {
+                    if (type == PathIterator.SEG_CLOSE) {
+                        closeIndex = typeSize;
+                    }
+                    types[typeSize++] = type;
+                }
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Join.
+         * 
+         * @param p
+         *            the p.
+         */
+        void join(BufferedPath p) {
+            // Skip MOVETO
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            System.arraycopy(p.points, 2, points, pointSize, p.pointSize - 2);
+            System.arraycopy(p.types, 1, types, typeSize, p.typeSize - 1);
+            pointSize += p.pointSize - 2;
+            typeSize += p.typeSize - 1;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Combine.
+         * 
+         * @param p
+         *            the p.
+         */
+        void combine(BufferedPath p) {
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            // Skip last point, beacause it's the first point of the second path
+            for (int i = p.pointSize - 4; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            for (int i = p.typeSize - 1; i >= 1; i--) {
+                types[typeSize++] = p.types[i];
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Creates the general path.
+         * 
+         * @return the general path.
+         */
+        GeneralPath createGeneralPath() {
+            GeneralPath p = new GeneralPath();
+            int j = 0;
+            for (int i = 0; i < typeSize; i++) {
+                int type = types[i];
+                switch (type) {
+                    case PathIterator.SEG_MOVETO:
+                        p.moveTo(points[j], points[j + 1]);
+                        break;
+                    case PathIterator.SEG_LINETO:
+                        p.lineTo(points[j], points[j + 1]);
+                        break;
+                    case PathIterator.SEG_QUADTO:
+                        p.quadTo(points[j], points[j + 1], points[j + 2], points[j + 3]);
+                        break;
+                    case PathIterator.SEG_CUBICTO:
+                        p.curveTo(points[j], points[j + 1], points[j + 2], points[j + 3],
+                                points[j + 4], points[j + 5]);
+                        break;
+                    case PathIterator.SEG_CLOSE:
+                        p.closePath();
+                        break;
+                }
+                j += pointShift[type];
+            }
+            return p;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/BufferCapabilities.java b/awt/java/awt/BufferCapabilities.java
new file mode 100644
index 0000000..cd5fe7b
--- /dev/null
+++ b/awt/java/awt/BufferCapabilities.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The BufferCapabilities class represents the capabilities and other properties
+ * of the image buffers.
+ * 
+ * @since Android 1.0
+ */
+public class BufferCapabilities implements Cloneable {
+
+    /**
+     * The front buffer capabilities.
+     */
+    private final ImageCapabilities frontBufferCapabilities;
+
+    /**
+     * The back buffer capabilities.
+     */
+    private final ImageCapabilities backBufferCapabilities;
+
+    /**
+     * The flip contents.
+     */
+    private final FlipContents flipContents;
+
+    /**
+     * Instantiates a new BufferCapabilities object.
+     * 
+     * @param frontBufferCapabilities
+     *            the front buffer capabilities, can not be null.
+     * @param backBufferCapabilities
+     *            the the back and intermediate buffers capabilities, can not be
+     *            null.
+     * @param flipContents
+     *            the back buffer contents after page flipping, null if page
+     *            flipping is not used.
+     */
+    public BufferCapabilities(ImageCapabilities frontBufferCapabilities,
+            ImageCapabilities backBufferCapabilities, FlipContents flipContents) {
+        if (frontBufferCapabilities == null || backBufferCapabilities == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.frontBufferCapabilities = frontBufferCapabilities;
+        this.backBufferCapabilities = backBufferCapabilities;
+        this.flipContents = flipContents;
+    }
+
+    /**
+     * Returns a copy of the BufferCapabilities object.
+     * 
+     * @return a copy of the BufferCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new BufferCapabilities(frontBufferCapabilities, backBufferCapabilities, flipContents);
+    }
+
+    /**
+     * Gets the image capabilities of the front buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities of the
+     *         front buffer.
+     */
+    public ImageCapabilities getFrontBufferCapabilities() {
+        return frontBufferCapabilities;
+    }
+
+    /**
+     * Gets the image capabilities of the back buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities of the back
+     *         buffer.
+     */
+    public ImageCapabilities getBackBufferCapabilities() {
+        return backBufferCapabilities;
+    }
+
+    /**
+     * Gets the flip contents of the back buffer after page-flipping.
+     * 
+     * @return the FlipContents of the back buffer after page-flipping.
+     */
+    public FlipContents getFlipContents() {
+        return flipContents;
+    }
+
+    /**
+     * Checks if the buffer strategy uses page flipping.
+     * 
+     * @return true, if the buffer strategy uses page flipping, false otherwise.
+     */
+    public boolean isPageFlipping() {
+        return flipContents != null;
+    }
+
+    /**
+     * Checks if page flipping is only available in full-screen mode.
+     * 
+     * @return true, if page flipping is only available in full-screen mode,
+     *         false otherwise.
+     */
+    public boolean isFullScreenRequired() {
+        return false;
+    }
+
+    /**
+     * Checks if page flipping can be performed using more than two buffers.
+     * 
+     * @return true, if page flipping can be performed using more than two
+     *         buffers, false otherwise.
+     */
+    public boolean isMultiBufferAvailable() {
+        return false;
+    }
+
+    /**
+     * The FlipContents class represents a set of possible back buffer contents
+     * after page-flipping.
+     * 
+     * @since Android 1.0
+     */
+    public static final class FlipContents {
+
+        /**
+         * The back buffered contents are cleared with the background color
+         * after flipping.
+         */
+        public static final FlipContents BACKGROUND = new FlipContents();
+
+        /**
+         * The back buffered contents are copied to the front buffer before
+         * flipping.
+         */
+        public static final FlipContents COPIED = new FlipContents();
+
+        /**
+         * The back buffer contents are the prior contents of the front buffer.
+         */
+        public static final FlipContents PRIOR = new FlipContents();
+
+        /**
+         * The back buffer contents are undefined after flipping
+         */
+        public static final FlipContents UNDEFINED = new FlipContents();
+
+        /**
+         * Instantiates a new flip contents.
+         */
+        private FlipContents() {
+
+        }
+
+        /**
+         * Returns the hash code of the FlipContents object.
+         * 
+         * @return the hash code of the FlipContents object.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Returns the String representation of the FlipContents object.
+         * 
+         * @return the string
+         */
+        @Override
+        public String toString() {
+            return super.toString();
+        }
+    }
+}
diff --git a/awt/java/awt/Color.java b/awt/java/awt/Color.java
new file mode 100644
index 0000000..93c532d
--- /dev/null
+++ b/awt/java/awt/Color.java
@@ -0,0 +1,990 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Color class defines colors in the default sRGB color space or in the
+ * specified ColorSpace. Every Color contains alpha value. The alpha value
+ * defines the transparency of a color and can be represented by a float value
+ * in the range 0.0 - 1.0 or 0 - 255.
+ * 
+ * @since Android 1.0
+ */
+public class Color implements Paint, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 118526816881161077L;
+
+    /*
+     * The values of the following colors are based on 1.5 release behavior
+     * which can be revealed using the following or similar code: Color c =
+     * Color.white; System.out.println(c);
+     */
+
+    /**
+     * The color white.
+     */
+    public static final Color white = new Color(255, 255, 255);
+
+    /**
+     * The color white.
+     */
+    public static final Color WHITE = white;
+
+    /**
+     * The color light gray.
+     */
+    public static final Color lightGray = new Color(192, 192, 192);
+
+    /**
+     * The color light gray.
+     */
+    public static final Color LIGHT_GRAY = lightGray;
+
+    /**
+     * The color gray.
+     */
+    public static final Color gray = new Color(128, 128, 128);
+
+    /**
+     * The color gray.
+     */
+    public static final Color GRAY = gray;
+
+    /**
+     * The color dark gray.
+     */
+    public static final Color darkGray = new Color(64, 64, 64);
+
+    /**
+     * The color dark gray.
+     */
+    public static final Color DARK_GRAY = darkGray;
+
+    /**
+     * The color black.
+     */
+    public static final Color black = new Color(0, 0, 0);
+
+    /**
+     * The color black.
+     */
+    public static final Color BLACK = black;
+
+    /**
+     * The color red.
+     */
+    public static final Color red = new Color(255, 0, 0);
+
+    /**
+     * The color red.
+     */
+    public static final Color RED = red;
+
+    /**
+     * The color pink.
+     */
+    public static final Color pink = new Color(255, 175, 175);
+
+    /**
+     * The color pink.
+     */
+    public static final Color PINK = pink;
+
+    /**
+     * The color orange.
+     */
+    public static final Color orange = new Color(255, 200, 0);
+
+    /**
+     * The color orange.
+     */
+    public static final Color ORANGE = orange;
+
+    /**
+     * The color yellow.
+     */
+    public static final Color yellow = new Color(255, 255, 0);
+
+    /**
+     * The color yellow.
+     */
+    public static final Color YELLOW = yellow;
+
+    /**
+     * The color green.
+     */
+    public static final Color green = new Color(0, 255, 0);
+
+    /**
+     * The color green.
+     */
+    public static final Color GREEN = green;
+
+    /**
+     * The color magenta.
+     */
+    public static final Color magenta = new Color(255, 0, 255);
+
+    /**
+     * The color magenta.
+     */
+    public static final Color MAGENTA = magenta;
+
+    /**
+     * The color cyan.
+     */
+    public static final Color cyan = new Color(0, 255, 255);
+
+    /**
+     * The color cyan.
+     */
+    public static final Color CYAN = cyan;
+
+    /**
+     * The color blue.
+     */
+    public static final Color blue = new Color(0, 0, 255);
+
+    /**
+     * The color blue.
+     */
+    public static final Color BLUE = blue;
+
+    /**
+     * integer RGB value.
+     */
+    int value;
+
+    /**
+     * Float sRGB value.
+     */
+    private float[] frgbvalue;
+
+    /**
+     * Color in an arbitrary color space with <code>float</code> components. If
+     * null, other value should be used.
+     */
+    private float fvalue[];
+
+    /**
+     * Float alpha value. If frgbvalue is null, this is not valid data.
+     */
+    private float falpha;
+
+    /**
+     * The color's color space if applicable.
+     */
+    private ColorSpace cs;
+
+    /*
+     * The value of the SCALE_FACTOR is based on 1.5 release behavior which can
+     * be revealed using the following code: Color c = new Color(100, 100, 100);
+     * Color bc = c.brighter(); System.out.println("Brighter factor: " +
+     * ((float)c.getRed())/((float)bc.getRed())); Color dc = c.darker();
+     * System.out.println("Darker factor: " +
+     * ((float)dc.getRed())/((float)c.getRed())); The result is the same for
+     * brighter and darker methods, so we need only one scale factor for both.
+     */
+    /**
+     * The Constant SCALE_FACTOR.
+     */
+    private static final double SCALE_FACTOR = 0.7;
+
+    /**
+     * The Constant MIN_SCALABLE.
+     */
+    private static final int MIN_SCALABLE = 3; // should increase when
+
+    // multiplied by SCALE_FACTOR
+
+    /**
+     * The current paint context.
+     */
+    transient private PaintContext currentPaintContext;
+
+    /**
+     * Creates a color in the specified ColorSpace, the specified color
+     * components and the specified alpha.
+     * 
+     * @param cspace
+     *            the ColorSpace to be used to define the components.
+     * @param components
+     *            the components.
+     * @param alpha
+     *            the alpha.
+     */
+    public Color(ColorSpace cspace, float[] components, float alpha) {
+        int nComps = cspace.getNumComponents();
+        float comp;
+        fvalue = new float[nComps];
+
+        for (int i = 0; i < nComps; i++) {
+            comp = components[i];
+            if (comp < 0.0f || comp > 1.0f) {
+                // awt.107=Color parameter outside of expected range: component
+                // {0}.
+                throw new IllegalArgumentException(Messages.getString("awt.107", i)); //$NON-NLS-1$
+            }
+            fvalue[i] = components[i];
+        }
+
+        if (alpha < 0.0f || alpha > 1.0f) {
+            // awt.108=Alpha value outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
+        }
+        falpha = alpha;
+
+        cs = cspace;
+
+        frgbvalue = cs.toRGB(fvalue);
+
+        value = ((int)(frgbvalue[2] * 255 + 0.5)) | (((int)(frgbvalue[1] * 255 + 0.5)) << 8)
+                | (((int)(frgbvalue[0] * 255 + 0.5)) << 16) | (((int)(falpha * 255 + 0.5)) << 24);
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified combined RGBA value
+     * consisting of the alpha component in bits 24-31, the red component in
+     * bits 16-23, the green component in bits 8-15, and the blue component in
+     * bits 0-7. If the hasalpha argument is false, the alpha has default value
+     * - 255.
+     * 
+     * @param rgba
+     *            the RGBA components.
+     * @param hasAlpha
+     *            the alpha parameter is true if alpha bits are valid, false
+     *            otherwise.
+     */
+    public Color(int rgba, boolean hasAlpha) {
+        if (!hasAlpha) {
+            value = rgba | 0xFF000000;
+        } else {
+            value = rgba;
+        }
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha
+     * components.
+     * 
+     * @param r
+     *            the red component.
+     * @param g
+     *            the green component.
+     * @param b
+     *            the blue component.
+     * @param a
+     *            the alpha component.
+     */
+    public Color(int r, int g, int b, int a) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        value = b | (g << 8) | (r << 16) | (a << 24);
+    }
+
+    /**
+     * Instantiates a new opaque sRGB color with the specified red, green, and
+     * blue values. The Alpha component is set to the default - 1.0.
+     * 
+     * @param r
+     *            the red component.
+     * @param g
+     *            the green component.
+     * @param b
+     *            the blue component.
+     */
+    public Color(int r, int g, int b) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        // 0xFF for alpha channel
+        value = b | (g << 8) | (r << 16) | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified RGB value consisting of
+     * the red component in bits 16-23, the green component in bits 8-15, and
+     * the blue component in bits 0-7. Alpha has default value - 255.
+     * 
+     * @param rgb
+     *            the RGB components.
+     */
+    public Color(int rgb) {
+        value = rgb | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha
+     * components.
+     * 
+     * @param r
+     *            the red component.
+     * @param g
+     *            the green component.
+     * @param b
+     *            the blue component.
+     * @param a
+     *            the alpha component.
+     */
+    public Color(float r, float g, float b, float a) {
+        this((int)(r * 255 + 0.5), (int)(g * 255 + 0.5), (int)(b * 255 + 0.5), (int)(a * 255 + 0.5));
+        falpha = a;
+        fvalue = new float[3];
+        fvalue[0] = r;
+        fvalue[1] = g;
+        fvalue[2] = b;
+        frgbvalue = fvalue;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, and blue
+     * components and default alpha value - 1.0.
+     * 
+     * @param r
+     *            the red component.
+     * @param g
+     *            the green component.
+     * @param b
+     *            the blue component.
+     */
+    public Color(float r, float g, float b) {
+        this(r, g, b, 1.0f);
+    }
+
+    public PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d,
+            AffineTransform xform, RenderingHints rhs) {
+        if (currentPaintContext != null) {
+            return currentPaintContext;
+        }
+        currentPaintContext = new Color.ColorPaintContext(value);
+        return currentPaintContext;
+    }
+
+    /**
+     * Returns a string representation of the Color object.
+     * 
+     * @return the string representation of the Color object.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format of the string is based on 1.5 release behavior which can
+         * be revealed using the following code: Color c = new Color(1, 2, 3);
+         * System.out.println(c);
+         */
+
+        return getClass().getName() + "[r=" + getRed() + //$NON-NLS-1$
+                ",g=" + getGreen() + //$NON-NLS-1$
+                ",b=" + getBlue() + //$NON-NLS-1$
+                "]"; //$NON-NLS-1$
+    }
+
+    /**
+     * Compares the specified Object to the Color.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified Object is a Color whose value is equal to
+     *         this Color, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Color) {
+            return ((Color)obj).value == this.value;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of the
+     * Color in the specified ColorSpace.
+     * 
+     * @param colorSpace
+     *            the specified ColorSpace.
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. If null, a float array will be created.
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(ColorSpace colorSpace, float[] components) {
+        int nComps = colorSpace.getNumComponents();
+        if (components == null) {
+            components = new float[nComps + 1];
+        }
+
+        getColorComponents(colorSpace, components);
+
+        if (frgbvalue != null) {
+            components[nComps] = falpha;
+        } else {
+            components[nComps] = getAlpha() / 255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of the Color in the
+     * specified ColorSpace.
+     * 
+     * @param colorSpace
+     *            the specified ColorSpace.
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. If null, a float array will be created.
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
+        float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
+        float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
+
+        if (components == null) {
+            return csComponents;
+        }
+
+        for (int i = 0; i < csComponents.length; i++) {
+            components[i] = csComponents[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the ColorSpace of this Color.
+     * 
+     * @return the ColorSpace object.
+     */
+    public ColorSpace getColorSpace() {
+        if (cs == null) {
+            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        }
+
+        return cs;
+    }
+
+    /**
+     * Creates a new Color which is a darker than this Color according to a
+     * fixed scale factor.
+     * 
+     * @return the darker Color.
+     */
+    public Color darker() {
+        return new Color((int)(getRed() * SCALE_FACTOR), (int)(getGreen() * SCALE_FACTOR),
+                (int)(getBlue() * SCALE_FACTOR));
+    }
+
+    /**
+     * Creates a new Color which is a brighter than this Color.
+     * 
+     * @return the brighter Color.
+     */
+    public Color brighter() {
+
+        int r = getRed();
+        int b = getBlue();
+        int g = getGreen();
+
+        if (r == 0 && b == 0 && g == 0) {
+            return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
+        }
+
+        if (r < MIN_SCALABLE && r != 0) {
+            r = MIN_SCALABLE;
+        } else {
+            r = (int)(r / SCALE_FACTOR);
+            r = (r > 255) ? 255 : r;
+        }
+
+        if (b < MIN_SCALABLE && b != 0) {
+            b = MIN_SCALABLE;
+        } else {
+            b = (int)(b / SCALE_FACTOR);
+            b = (b > 255) ? 255 : b;
+        }
+
+        if (g < MIN_SCALABLE && g != 0) {
+            g = MIN_SCALABLE;
+        } else {
+            g = (int)(g / SCALE_FACTOR);
+            g = (g > 255) ? 255 : g;
+        }
+
+        return new Color(r, g, b);
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of the
+     * Color in the default sRGB color space.
+     * 
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. A new float array will be created if this argument is
+     *            null.
+     * @return the RGB color and alpha components in a float array.
+     */
+    public float[] getRGBComponents(float[] components) {
+        if (components == null) {
+            components = new float[4];
+        }
+
+        if (frgbvalue != null) {
+            components[3] = falpha;
+        } else {
+            components[3] = getAlpha() / 255f;
+        }
+
+        getRGBColorComponents(components);
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of the Color in the
+     * default sRGB color space.
+     * 
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. A new float array will be created if this argument is
+     *            null.
+     * @return the RGB color components in a float array.
+     */
+    public float[] getRGBColorComponents(float[] components) {
+        if (components == null) {
+            components = new float[3];
+        }
+
+        if (frgbvalue != null) {
+            components[2] = frgbvalue[2];
+            components[1] = frgbvalue[1];
+            components[0] = frgbvalue[0];
+        } else {
+            components[2] = getBlue() / 255f;
+            components[1] = getGreen() / 255f;
+            components[0] = getRed() / 255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color and alpha components of
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. A new float array will be created if this argument is
+     *            null.
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(float[] components) {
+        if (fvalue == null) {
+            return getRGBComponents(components);
+        }
+
+        int nColorComps = fvalue.length;
+
+        if (components == null) {
+            components = new float[nColorComps + 1];
+        }
+
+        getColorComponents(components);
+
+        components[nColorComps] = falpha;
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color components of the Color in
+     * the ColorSpace of the Color.
+     * 
+     * @param components
+     *            the results of this method will be written to this float
+     *            array. A new float array will be created if this argument is
+     *            null.
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(float[] components) {
+        if (fvalue == null) {
+            return getRGBColorComponents(components);
+        }
+
+        if (components == null) {
+            components = new float[fvalue.length];
+        }
+
+        for (int i = 0; i < fvalue.length; i++) {
+            components[i] = fvalue[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a hash code of this Color object.
+     * 
+     * @return a hash code of this Color object.
+     */
+    @Override
+    public int hashCode() {
+        return value;
+    }
+
+    public int getTransparency() {
+        switch (getAlpha()) {
+            case 0xff:
+                return Transparency.OPAQUE;
+            case 0:
+                return Transparency.BITMASK;
+            default:
+                return Transparency.TRANSLUCENT;
+        }
+    }
+
+    /**
+     * Gets the red component of the Color in the range 0-255.
+     * 
+     * @return the red component of the Color.
+     */
+    public int getRed() {
+        return (value >> 16) & 0xFF;
+    }
+
+    /**
+     * Gets the RGB value that represents the color in the default sRGB
+     * ColorModel.
+     * 
+     * @return the RGB color value in the default sRGB ColorModel.
+     */
+    public int getRGB() {
+        return value;
+    }
+
+    /**
+     * Gets the green component of the Color in the range 0-255.
+     * 
+     * @return the green component of the Color.
+     */
+    public int getGreen() {
+        return (value >> 8) & 0xFF;
+    }
+
+    /**
+     * Gets the blue component of the Color in the range 0-255.
+     * 
+     * @return the blue component of the Color.
+     */
+    public int getBlue() {
+        return value & 0xFF;
+    }
+
+    /**
+     * Gets the alpha component of the Color in the range 0-255.
+     * 
+     * @return the alpha component of the Color.
+     */
+    public int getAlpha() {
+        return (value >> 24) & 0xFF;
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color specified
+     * by the second parameter.
+     * 
+     * @param nm
+     *            the specified string.
+     * @param def
+     *            the default Color.
+     * @return the color from the specified string, or the Color specified by
+     *         the second parameter.
+     */
+    public static Color getColor(String nm, Color def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return def;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color converted
+     * from the second parameter.
+     * 
+     * @param nm
+     *            the specified string.
+     * @param def
+     *            the default Color.
+     * @return the color from the specified string, or the Color converted from
+     *         the second parameter.
+     */
+    public static Color getColor(String nm, int def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return new Color(def);
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified String.
+     * 
+     * @param nm
+     *            the specified string.
+     * @return the Color object, or null.
+     */
+    public static Color getColor(String nm) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return null;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Decodes a String to an integer and returns the specified opaque Color.
+     * 
+     * @param nm
+     *            the String which represents an opaque color as a 24-bit
+     *            integer.
+     * @return the Color object from the given String.
+     * @throws NumberFormatException
+     *             if the specified string can not be converted to an integer.
+     */
+    public static Color decode(String nm) throws NumberFormatException {
+        Integer integer = Integer.decode(nm);
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets a Color object using the specified values of the HSB color model.
+     * 
+     * @param h
+     *            the hue component of the Color.
+     * @param s
+     *            the saturation of the Color.
+     * @param b
+     *            the brightness of the Color.
+     * @return a color object with the specified hue, saturation and brightness
+     *         values.
+     */
+    public static Color getHSBColor(float h, float s, float b) {
+        return new Color(HSBtoRGB(h, s, b));
+    }
+
+    /**
+     * Converts the Color specified by the RGB model to an equivalent color in
+     * the HSB model.
+     * 
+     * @param r
+     *            the red component.
+     * @param g
+     *            the green component.
+     * @param b
+     *            the blue component.
+     * @param hsbvals
+     *            the array of result hue, saturation, brightness values or
+     *            null.
+     * @return the float array of hue, saturation, brightness values.
+     */
+    public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
+        if (hsbvals == null) {
+            hsbvals = new float[3];
+        }
+
+        int V = Math.max(b, Math.max(r, g));
+        int temp = Math.min(b, Math.min(r, g));
+
+        float H, S, B;
+
+        B = V / 255.f;
+
+        if (V == temp) {
+            H = S = 0;
+        } else {
+            S = (V - temp) / ((float)V);
+
+            float Cr = (V - r) / (float)(V - temp);
+            float Cg = (V - g) / (float)(V - temp);
+            float Cb = (V - b) / (float)(V - temp);
+
+            if (r == V) {
+                H = Cb - Cg;
+            } else if (g == V) {
+                H = 2 + Cr - Cb;
+            } else {
+                H = 4 + Cg - Cr;
+            }
+
+            H /= 6.f;
+            if (H < 0) {
+                H++;
+            }
+        }
+
+        hsbvals[0] = H;
+        hsbvals[1] = S;
+        hsbvals[2] = B;
+
+        return hsbvals;
+    }
+
+    /**
+     * Converts the Color specified by the HSB model to an equivalent color in
+     * the default RGB model.
+     * 
+     * @param hue
+     *            the hue component of the Color.
+     * @param saturation
+     *            the saturation of the Color.
+     * @param brightness
+     *            the brightness of the Color.
+     * @return the RGB value of the color with the specified hue, saturation and
+     *         brightness.
+     */
+    public static int HSBtoRGB(float hue, float saturation, float brightness) {
+        float fr, fg, fb;
+
+        if (saturation == 0) {
+            fr = fg = fb = brightness;
+        } else {
+            float H = (hue - (float)Math.floor(hue)) * 6;
+            int I = (int)Math.floor(H);
+            float F = H - I;
+            float M = brightness * (1 - saturation);
+            float N = brightness * (1 - saturation * F);
+            float K = brightness * (1 - saturation * (1 - F));
+
+            switch (I) {
+                case 0:
+                    fr = brightness;
+                    fg = K;
+                    fb = M;
+                    break;
+                case 1:
+                    fr = N;
+                    fg = brightness;
+                    fb = M;
+                    break;
+                case 2:
+                    fr = M;
+                    fg = brightness;
+                    fb = K;
+                    break;
+                case 3:
+                    fr = M;
+                    fg = N;
+                    fb = brightness;
+                    break;
+                case 4:
+                    fr = K;
+                    fg = M;
+                    fb = brightness;
+                    break;
+                case 5:
+                    fr = brightness;
+                    fg = M;
+                    fb = N;
+                    break;
+                default:
+                    fr = fb = fg = 0; // impossible, to supress compiler error
+            }
+        }
+
+        int r = (int)(fr * 255. + 0.5);
+        int g = (int)(fg * 255. + 0.5);
+        int b = (int)(fb * 255. + 0.5);
+
+        return (r << 16) | (g << 8) | b | 0xFF000000;
+    }
+
+    /**
+     * The Class ColorPaintContext.
+     */
+    class ColorPaintContext implements PaintContext {
+
+        /**
+         * The RGB value.
+         */
+        int rgbValue;
+
+        /**
+         * The saved raster.
+         */
+        WritableRaster savedRaster = null;
+
+        /**
+         * Instantiates a new color paint context.
+         * 
+         * @param rgb
+         *            the RGB value.
+         */
+        protected ColorPaintContext(int rgb) {
+            rgbValue = rgb;
+        }
+
+        public void dispose() {
+            savedRaster = null;
+        }
+
+        public ColorModel getColorModel() {
+            return ColorModel.getRGBdefault();
+        }
+
+        public Raster getRaster(int x, int y, int w, int h) {
+            if (savedRaster == null || w != savedRaster.getWidth() || h != savedRaster.getHeight()) {
+                savedRaster = getColorModel().createCompatibleWritableRaster(w, h);
+
+                // Suppose we have here simple INT/RGB color/sample model
+                DataBufferInt intBuffer = (DataBufferInt)savedRaster.getDataBuffer();
+                int rgbValues[] = intBuffer.getData();
+                int rgbFillValue = rgbValue;
+                Arrays.fill(rgbValues, rgbFillValue);
+            }
+
+            return savedRaster;
+        }
+    }
+}
diff --git a/awt/java/awt/Component.java b/awt/java/awt/Component.java
new file mode 100644
index 0000000..c52a9f4
--- /dev/null
+++ b/awt/java/awt/Component.java
@@ -0,0 +1,6020 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+//import java.awt.dnd.DropTarget;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.InvocationEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.awt.peer.ComponentPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleState;
+//import javax.accessibility.AccessibleStateSet;
+
+import org.apache.harmony.awt.ClipRegion; //import org.apache.harmony.awt.FieldsAccessor;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.state.State; //import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+import org.apache.harmony.awt.wtk.NativeWindow;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ * The abstract Component class specifies an object with a graphical
+ * representation that can be displayed on the screen and that can interact with
+ * the user (for example: scrollbars, buttons, checkboxes).
+ * 
+ * @since Android 1.0
+ */
+public abstract class Component implements ImageObserver, MenuContainer, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -7644114512714619750L;
+
+    /**
+     * The Constant TOP_ALIGNMENT indicates the top alignment of the component.
+     */
+    public static final float TOP_ALIGNMENT = 0.0f;
+
+    /**
+     * The Constant CENTER_ALIGNMENT indicates the center alignment of the
+     * component.
+     */
+    public static final float CENTER_ALIGNMENT = 0.5f;
+
+    /**
+     * The Constant BOTTOM_ALIGNMENT indicates the bottom alignment of the
+     * component.
+     */
+    public static final float BOTTOM_ALIGNMENT = 1.0f;
+
+    /**
+     * The Constant LEFT_ALIGNMENT indicates the left alignment of the
+     * component.
+     */
+    public static final float LEFT_ALIGNMENT = 0.0f;
+
+    /**
+     * The Constant RIGHT_ALIGNMENT indicates the right alignment of the
+     * component.
+     */
+    public static final float RIGHT_ALIGNMENT = 1.0f;
+
+    /**
+     * The Constant childClassesFlags.
+     */
+    private static final Hashtable<Class<?>, Boolean> childClassesFlags = new Hashtable<Class<?>, Boolean>();
+
+    /**
+     * The Constant peer.
+     */
+    private static final ComponentPeer peer = new ComponentPeer() {
+    };
+
+    /**
+     * The Constant incrementalImageUpdate.
+     */
+    private static final boolean incrementalImageUpdate;
+
+    /**
+     * The toolkit.
+     */
+    final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    // ???AWT
+    /*
+     * protected abstract class AccessibleAWTComponent extends AccessibleContext
+     * implements Serializable, AccessibleComponent { private static final long
+     * serialVersionUID = 642321655757800191L; protected class
+     * AccessibleAWTComponentHandler implements ComponentListener { protected
+     * AccessibleAWTComponentHandler() { } public void
+     * componentHidden(ComponentEvent e) { if (behaviour.isLightweight()) {
+     * return; } firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+     * AccessibleState.VISIBLE, null); } public void
+     * componentMoved(ComponentEvent e) { } public void
+     * componentResized(ComponentEvent e) { } public void
+     * componentShown(ComponentEvent e) { if (behaviour.isLightweight()) {
+     * return; } firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+     * null, AccessibleState.VISIBLE); } } protected class
+     * AccessibleAWTFocusHandler implements FocusListener { public void
+     * focusGained(FocusEvent e) { if (behaviour.isLightweight()) { return; }
+     * firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+     * AccessibleState.FOCUSED); } public void focusLost(FocusEvent e) { if
+     * (behaviour.isLightweight()) { return; }
+     * firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+     * AccessibleState.FOCUSED, null); } } protected ComponentListener
+     * accessibleAWTComponentHandler; protected FocusListener
+     * accessibleAWTFocusHandler;
+     */
+    /*
+     * Number of registered property change listeners.
+     */
+    /*
+     * int listenersCount; public void addFocusListener(FocusListener l) {
+     * Component.this.addFocusListener(l); }
+     * @Override public void addPropertyChangeListener(PropertyChangeListener
+     * listener) { toolkit.lockAWT(); try {
+     * super.addPropertyChangeListener(listener); listenersCount++; if
+     * (accessibleAWTComponentHandler == null) { accessibleAWTComponentHandler =
+     * new AccessibleAWTComponentHandler();
+     * Component.this.addComponentListener(accessibleAWTComponentHandler); } if
+     * (accessibleAWTFocusHandler == null) { accessibleAWTFocusHandler = new
+     * AccessibleAWTFocusHandler();
+     * Component.this.addFocusListener(accessibleAWTFocusHandler); } } finally {
+     * toolkit.unlockAWT(); } } public boolean contains(Point p) {
+     * toolkit.lockAWT(); try { return Component.this.contains(p); } finally {
+     * toolkit.unlockAWT(); } } public Accessible getAccessibleAt(Point arg0) {
+     * toolkit.lockAWT(); try { return null; } finally { toolkit.unlockAWT(); }
+     * } public Color getBackground() { toolkit.lockAWT(); try { return
+     * Component.this.getBackground(); } finally { toolkit.unlockAWT(); } }
+     * public Rectangle getBounds() { toolkit.lockAWT(); try { return
+     * Component.this.getBounds(); } finally { toolkit.unlockAWT(); } } public
+     * Cursor getCursor() { toolkit.lockAWT(); try { return
+     * Component.this.getCursor(); } finally { toolkit.unlockAWT(); } } public
+     * Font getFont() { toolkit.lockAWT(); try { return
+     * Component.this.getFont(); } finally { toolkit.unlockAWT(); } } public
+     * FontMetrics getFontMetrics(Font f) { toolkit.lockAWT(); try { return
+     * Component.this.getFontMetrics(f); } finally { toolkit.unlockAWT(); } }
+     * public Color getForeground() { toolkit.lockAWT(); try { return
+     * Component.this.getForeground(); } finally { toolkit.unlockAWT(); } }
+     * public Point getLocation() { toolkit.lockAWT(); try { return
+     * Component.this.getLocation(); } finally { toolkit.unlockAWT(); } } public
+     * Point getLocationOnScreen() { toolkit.lockAWT(); try { return
+     * Component.this.getLocationOnScreen(); } finally { toolkit.unlockAWT(); }
+     * } public Dimension getSize() { toolkit.lockAWT(); try { return
+     * Component.this.getSize(); } finally { toolkit.unlockAWT(); } } public
+     * boolean isEnabled() { toolkit.lockAWT(); try { return
+     * Component.this.isEnabled(); } finally { toolkit.unlockAWT(); } } public
+     * boolean isFocusTraversable() { toolkit.lockAWT(); try { return
+     * Component.this.isFocusTraversable(); } finally { toolkit.unlockAWT(); } }
+     * public boolean isShowing() { toolkit.lockAWT(); try { return
+     * Component.this.isShowing(); } finally { toolkit.unlockAWT(); } } public
+     * boolean isVisible() { toolkit.lockAWT(); try { return
+     * Component.this.isVisible(); } finally { toolkit.unlockAWT(); } } public
+     * void removeFocusListener(FocusListener l) {
+     * Component.this.removeFocusListener(l); }
+     * @Override public void removePropertyChangeListener(PropertyChangeListener
+     * listener) { toolkit.lockAWT(); try {
+     * super.removePropertyChangeListener(listener); listenersCount--; if
+     * (listenersCount > 0) { return; } // if there are no more listeners,
+     * remove handlers:
+     * Component.this.removeFocusListener(accessibleAWTFocusHandler);
+     * Component.this.removeComponentListener(accessibleAWTComponentHandler);
+     * accessibleAWTComponentHandler = null; accessibleAWTFocusHandler = null; }
+     * finally { toolkit.unlockAWT(); } } public void requestFocus() {
+     * toolkit.lockAWT(); try { Component.this.requestFocus(); } finally {
+     * toolkit.unlockAWT(); } } public void setBackground(Color color) {
+     * toolkit.lockAWT(); try { Component.this.setBackground(color); } finally {
+     * toolkit.unlockAWT(); } } public void setBounds(Rectangle r) {
+     * toolkit.lockAWT(); try { Component.this.setBounds(r); } finally {
+     * toolkit.unlockAWT(); } } public void setCursor(Cursor cursor) {
+     * toolkit.lockAWT(); try { Component.this.setCursor(cursor); } finally {
+     * toolkit.unlockAWT(); } } public void setEnabled(boolean enabled) {
+     * toolkit.lockAWT(); try { Component.this.setEnabled(enabled); } finally {
+     * toolkit.unlockAWT(); } } public void setFont(Font f) { toolkit.lockAWT();
+     * try { Component.this.setFont(f); } finally { toolkit.unlockAWT(); } }
+     * public void setForeground(Color color) { toolkit.lockAWT(); try {
+     * Component.this.setForeground(color); } finally { toolkit.unlockAWT(); } }
+     * public void setLocation(Point p) { toolkit.lockAWT(); try {
+     * Component.this.setLocation(p); } finally { toolkit.unlockAWT(); } }
+     * public void setSize(Dimension size) { toolkit.lockAWT(); try {
+     * Component.this.setSize(size); } finally { toolkit.unlockAWT(); } } public
+     * void setVisible(boolean visible) { toolkit.lockAWT(); try {
+     * Component.this.setVisible(visible); } finally { toolkit.unlockAWT(); } }
+     * @Override public Accessible getAccessibleParent() { toolkit.lockAWT();
+     * try { Accessible aParent = super.getAccessibleParent(); if (aParent !=
+     * null) { return aParent; } Container parent = getParent(); return (parent
+     * instanceof Accessible ? (Accessible) parent : null); } finally {
+     * toolkit.unlockAWT(); } }
+     * @Override public Accessible getAccessibleChild(int i) {
+     * toolkit.lockAWT(); try { return null; } finally { toolkit.unlockAWT(); }
+     * }
+     * @Override public int getAccessibleChildrenCount() { toolkit.lockAWT();
+     * try { return 0; } finally { toolkit.unlockAWT(); } }
+     * @Override public AccessibleComponent getAccessibleComponent() { return
+     * this; }
+     * @Override public String getAccessibleDescription() { return
+     * super.getAccessibleDescription(); // why override? }
+     * @Override public int getAccessibleIndexInParent() { toolkit.lockAWT();
+     * try { if (getAccessibleParent() == null) { return -1; } int count = 0;
+     * Container parent = getParent(); for (int i = 0; i <
+     * parent.getComponentCount(); i++) { Component aComp =
+     * parent.getComponent(i); if (aComp instanceof Accessible) { if (aComp ==
+     * Component.this) { return count; } ++count; } } return -1; } finally {
+     * toolkit.unlockAWT(); } }
+     * @Override public AccessibleRole getAccessibleRole() { toolkit.lockAWT();
+     * try { return AccessibleRole.AWT_COMPONENT; } finally {
+     * toolkit.unlockAWT(); } }
+     * @Override public AccessibleStateSet getAccessibleStateSet() {
+     * toolkit.lockAWT(); try { AccessibleStateSet set = new
+     * AccessibleStateSet(); if (isEnabled()) {
+     * set.add(AccessibleState.ENABLED); } if (isFocusable()) {
+     * set.add(AccessibleState.FOCUSABLE); } if (hasFocus()) {
+     * set.add(AccessibleState.FOCUSED); } if (isOpaque()) {
+     * set.add(AccessibleState.OPAQUE); } if (isShowing()) {
+     * set.add(AccessibleState.SHOWING); } if (isVisible()) {
+     * set.add(AccessibleState.VISIBLE); } return set; } finally {
+     * toolkit.unlockAWT(); } }
+     * @Override public Locale getLocale() throws IllegalComponentStateException
+     * { toolkit.lockAWT(); try { return Component.this.getLocale(); } finally {
+     * toolkit.unlockAWT(); } } }
+     */
+    /**
+     * The BltBufferStrategy class provides opportunity of blitting offscreen
+     * surfaces to a component. For more information on blitting, see <a
+     * href="http://en.wikipedia.org/wiki/Bit_blit">Bit blit</a>.
+     * 
+     * @since Android 1.0
+     */
+    protected class BltBufferStrategy extends BufferStrategy {
+
+        /**
+         * The back buffers.
+         */
+        protected VolatileImage[] backBuffers;
+
+        /**
+         * The caps.
+         */
+        protected BufferCapabilities caps;
+
+        /**
+         * The width.
+         */
+        protected int width;
+
+        /**
+         * The height.
+         */
+        protected int height;
+
+        /**
+         * The validated contents.
+         */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new BltBufferStrategy buffer strategy.
+         * 
+         * @param numBuffers
+         *            the number of buffers.
+         * @param caps
+         *            the BufferCapabilities.
+         * @throws NotImplementedException
+         *             the not implemented exception.
+         */
+        protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
+                throws org.apache.harmony.luni.util.NotImplementedException {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call
+         * to getDrawGraphics.
+         * 
+         * @return true if the drawing buffer has been lost since the last call
+         *         to getDrawGraphics, false otherwise.
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         *         state and reinitialized to the default background color,
+         *         false otherwise.
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates the back buffers.
+         * 
+         * @param numBuffers
+         *            the number of buffers.
+         */
+        protected void createBackBuffers(int numBuffers) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities)caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The FlipBufferStrategy class is for flipping buffers on a component.
+     * 
+     * @since Android 1.0
+     */
+    protected class FlipBufferStrategy extends BufferStrategy {
+
+        /**
+         * The Buffer Capabilities.
+         */
+        protected BufferCapabilities caps;
+
+        /**
+         * The drawing buffer.
+         */
+        protected Image drawBuffer;
+
+        /**
+         * The drawing VolatileImage buffer.
+         */
+        protected VolatileImage drawVBuffer;
+
+        /**
+         * The number of buffers.
+         */
+        protected int numBuffers;
+
+        /**
+         * The validated contents indicates if the drawing buffer is restored
+         * from lost state.
+         */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new flip buffer strategy.
+         * 
+         * @param numBuffers
+         *            the number of buffers.
+         * @param caps
+         *            the BufferCapabilities.
+         * @throws AWTException
+         *             if the capabilities supplied could not be supported or
+         *             met.
+         */
+        protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps) throws AWTException {
+            // ???AWT
+            /*
+             * if (!(Component.this instanceof Window) && !(Component.this
+             * instanceof Canvas)) { // awt.14B=Only Canvas or Window is allowed
+             * throw new ClassCastException(Messages.getString("awt.14B"));
+             * //$NON-NLS-1$ }
+             */
+            // TODO: throw new AWTException("Capabilities are not supported");
+            this.numBuffers = numBuffers;
+            this.caps = (BufferCapabilities)caps.clone();
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call
+         * to getDrawGraphics.
+         * 
+         * @return true if the drawing buffer has been lost since the last call
+         *         to getDrawGraphics, false otherwise.
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         *         state and reinitialized to the default background color,
+         *         false otherwise.
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates flipping buffers with the specified buffer capabilities.
+         * 
+         * @param numBuffers
+         *            the number of buffers.
+         * @param caps
+         *            the BufferCapabilities.
+         * @throws AWTException
+         *             if the capabilities could not be supported or met.
+         */
+        protected void createBuffers(int numBuffers, BufferCapabilities caps) throws AWTException {
+            if (numBuffers < 2) {
+                // awt.14C=Number of buffers must be greater than one
+                throw new IllegalArgumentException(Messages.getString("awt.14C")); //$NON-NLS-1$
+            }
+            if (!caps.isPageFlipping()) {
+                // awt.14D=Buffer capabilities should support flipping
+                throw new IllegalArgumentException(Messages.getString("awt.14D")); //$NON-NLS-1$
+            }
+            if (!Component.this.behaviour.isDisplayable()) {
+                // awt.14E=Component should be displayable
+                throw new IllegalStateException(Messages.getString("awt.14E")); //$NON-NLS-1$
+            }
+            // TODO: throw new AWTException("Capabilities are not supported");
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Destroy buffers.
+         */
+        protected void destroyBuffers() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Flips the contents of the back buffer to the front buffer.
+         * 
+         * @param flipAction
+         *            the flip action.
+         */
+        protected void flip(BufferCapabilities.FlipContents flipAction) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Gets the back buffer as Image.
+         * 
+         * @return the back buffer as Image.
+         */
+        protected Image getBackBuffer() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities)caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The internal component's state utilized by the visual theme.
+     */
+    class ComponentState implements State {
+
+        /**
+         * The default minimum size.
+         */
+        private Dimension defaultMinimumSize = new Dimension();
+
+        /**
+         * Checks if the component is enabled.
+         * 
+         * @return true, if the component is enabled.
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        /**
+         * Checks if the component is visible.
+         * 
+         * @return true, if the component is visible.
+         */
+        public boolean isVisible() {
+            return visible;
+        }
+
+        /**
+         * Checks if is focused.
+         * 
+         * @return true, if is focused.
+         */
+        public boolean isFocused() {
+            // ???AWT: return isFocusOwner();
+            return false;
+        }
+
+        /**
+         * Gets the font.
+         * 
+         * @return the font.
+         */
+        public Font getFont() {
+            return Component.this.getFont();
+        }
+
+        /**
+         * Checks if the font has been set.
+         * 
+         * @return true, if the font has been set.
+         */
+        public boolean isFontSet() {
+            return font != null;
+        }
+
+        /**
+         * Gets the background color.
+         * 
+         * @return the background color.
+         */
+        public Color getBackground() {
+            Color c = Component.this.getBackground();
+            return (c != null) ? c : getDefaultBackground();
+        }
+
+        /**
+         * Checks if the background is set.
+         * 
+         * @return true, if the background is set.
+         */
+        public boolean isBackgroundSet() {
+            return backColor != null;
+        }
+
+        /**
+         * Gets the text color.
+         * 
+         * @return the text color.
+         */
+        public Color getTextColor() {
+            Color c = getForeground();
+            return (c != null) ? c : getDefaultForeground();
+        }
+
+        /**
+         * Checks if the text color is set.
+         * 
+         * @return true, if the text color is set.
+         */
+        public boolean isTextColorSet() {
+            return foreColor != null;
+        }
+
+        /**
+         * Gets the font metrics.
+         * 
+         * @return the font metrics.
+         */
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics() {
+            return toolkit.getFontMetrics(Component.this.getFont());
+        }
+
+        /**
+         * Gets the bounding rectangle.
+         * 
+         * @return the bounding rectangle.
+         */
+        public Rectangle getBounds() {
+            return new Rectangle(x, y, w, h);
+        }
+
+        /**
+         * Gets the size of the bounding rectangle.
+         * 
+         * @return the size of the bounding rectangle.
+         */
+        public Dimension getSize() {
+            return new Dimension(w, h);
+        }
+
+        /**
+         * Gets the window id.
+         * 
+         * @return the window id.
+         */
+        public long getWindowId() {
+            NativeWindow win = getNativeWindow();
+            return (win != null) ? win.getId() : 0;
+        }
+
+        /**
+         * Gets the default minimum size.
+         * 
+         * @return the default minimum size.
+         */
+        public Dimension getDefaultMinimumSize() {
+            if (defaultMinimumSize == null) {
+                calculate();
+            }
+            return defaultMinimumSize;
+        }
+
+        /**
+         * Sets the default minimum size.
+         * 
+         * @param size
+         *            the new default minimum size.
+         */
+        public void setDefaultMinimumSize(Dimension size) {
+            defaultMinimumSize = size;
+        }
+
+        /**
+         * Reset the default minimum size to null.
+         */
+        public void reset() {
+            defaultMinimumSize = null;
+        }
+
+        /**
+         * Calculate the default minimum size: to be overridden.
+         */
+        public void calculate() {
+            // to be overridden
+        }
+    }
+
+    // ???AWT: private transient AccessibleContext accessibleContext;
+
+    /**
+     * The behaviour.
+     */
+    final transient ComponentBehavior behaviour;
+
+    // ???AWT: Container parent;
+
+    /**
+     * The name.
+     */
+    private String name;
+
+    /**
+     * The auto name.
+     */
+    private boolean autoName = true;
+
+    /**
+     * The font.
+     */
+    private Font font;
+
+    /**
+     * The back color.
+     */
+    private Color backColor;
+
+    /**
+     * The fore color.
+     */
+    private Color foreColor;
+
+    /**
+     * The deprecated event handler.
+     */
+    boolean deprecatedEventHandler = true;
+
+    /**
+     * The enabled events.
+     */
+    private long enabledEvents;
+
+    /**
+     * The enabled AWT events.
+     */
+    private long enabledAWTEvents;
+
+    /**
+     * The component listeners.
+     */
+    private final AWTListenerList<ComponentListener> componentListeners = new AWTListenerList<ComponentListener>(
+            this);
+
+    /**
+     * The focus listeners.
+     */
+    private final AWTListenerList<FocusListener> focusListeners = new AWTListenerList<FocusListener>(
+            this);
+
+    /**
+     * The hierarchy listeners.
+     */
+    private final AWTListenerList<HierarchyListener> hierarchyListeners = new AWTListenerList<HierarchyListener>(
+            this);
+
+    /**
+     * The hierarchy bounds listeners.
+     */
+    private final AWTListenerList<HierarchyBoundsListener> hierarchyBoundsListeners = new AWTListenerList<HierarchyBoundsListener>(
+            this);
+
+    /**
+     * The key listeners.
+     */
+    private final AWTListenerList<KeyListener> keyListeners = new AWTListenerList<KeyListener>(this);
+
+    /**
+     * The mouse listeners.
+     */
+    private final AWTListenerList<MouseListener> mouseListeners = new AWTListenerList<MouseListener>(
+            this);
+
+    /**
+     * The mouse motion listeners.
+     */
+    private final AWTListenerList<MouseMotionListener> mouseMotionListeners = new AWTListenerList<MouseMotionListener>(
+            this);
+
+    /**
+     * The mouse wheel listeners.
+     */
+    private final AWTListenerList<MouseWheelListener> mouseWheelListeners = new AWTListenerList<MouseWheelListener>(
+            this);
+
+    /**
+     * The input method listeners.
+     */
+    private final AWTListenerList<InputMethodListener> inputMethodListeners = new AWTListenerList<InputMethodListener>(
+            this);
+
+    /**
+     * The x.
+     */
+    int x;
+
+    /**
+     * The y.
+     */
+    int y;
+
+    /**
+     * The w.
+     */
+    int w;
+
+    /**
+     * The h.
+     */
+    int h;
+
+    /**
+     * The maximum size.
+     */
+    private Dimension maximumSize;
+
+    /**
+     * The minimum size.
+     */
+    private Dimension minimumSize;
+
+    /**
+     * The preferred size.
+     */
+    private Dimension preferredSize;
+
+    /**
+     * The bounds mask param.
+     */
+    private int boundsMaskParam;
+
+    /**
+     * The ignore repaint.
+     */
+    private boolean ignoreRepaint;
+
+    /**
+     * The enabled.
+     */
+    private boolean enabled = true;
+
+    /**
+     * The input methods enabled.
+     */
+    private boolean inputMethodsEnabled = true;
+
+    /**
+     * The dispatch to im.
+     */
+    transient boolean dispatchToIM = true;
+
+    /**
+     * The focusable.
+     */
+    private boolean focusable = true; // By default, all Components return
+
+    // true from isFocusable() method
+    /**
+     * The visible.
+     */
+    boolean visible = true;
+
+    /**
+     * The called set focusable.
+     */
+    private boolean calledSetFocusable;
+
+    /**
+     * The overridden is focusable.
+     */
+    private boolean overridenIsFocusable = true;
+
+    /**
+     * The focus traversal keys enabled.
+     */
+    private boolean focusTraversalKeysEnabled = true;
+
+    /**
+     * Possible keys are: FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
+     * UP_CYCLE_TRAVERSAL_KEYS.
+     */
+    private final Map<Integer, Set<? extends AWTKeyStroke>> traversalKeys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+
+    /**
+     * The traversal i ds.
+     */
+    int[] traversalIDs;
+
+    /**
+     * The locale.
+     */
+    private Locale locale;
+
+    /**
+     * The orientation.
+     */
+    private ComponentOrientation orientation;
+
+    /**
+     * The property change support.
+     */
+    private PropertyChangeSupport propertyChangeSupport;
+
+    // ???AWT: private ArrayList<PopupMenu> popups;
+
+    /**
+     * The coalescer.
+     */
+    private boolean coalescer;
+
+    /**
+     * The events table.
+     */
+    private Hashtable<Integer, LinkedList<AWTEvent>> eventsTable;
+
+    /**
+     * Cashed reference used during EventQueue.postEvent()
+     */
+    private LinkedList<AWTEvent> eventsList;
+
+    /**
+     * The hierarchy changing counter.
+     */
+    private int hierarchyChangingCounter;
+
+    /**
+     * The was showing.
+     */
+    private boolean wasShowing;
+
+    /**
+     * The was displayable.
+     */
+    private boolean wasDisplayable;
+
+    /**
+     * The cursor.
+     */
+    Cursor cursor;
+
+    // ???AWT: DropTarget dropTarget;
+
+    /**
+     * The mouse exited expected.
+     */
+    private boolean mouseExitedExpected;
+
+    /**
+     * The repaint region.
+     */
+    transient MultiRectArea repaintRegion;
+
+    // ???AWT: transient RedrawManager redrawManager;
+    /**
+     * The redraw manager.
+     */
+    transient Object redrawManager;
+
+    /**
+     * The valid.
+     */
+    private boolean valid;
+
+    /**
+     * The updated images.
+     */
+    private HashMap<Image, ImageParameters> updatedImages;
+
+    /**
+     * The lock object for private component's data which don't affect the
+     * component hierarchy.
+     */
+    private class ComponentLock {
+    }
+
+    /**
+     * The component lock.
+     */
+    private final transient Object componentLock = new ComponentLock();
+    static {
+        PrivilegedAction<String[]> action = new PrivilegedAction<String[]>() {
+            public String[] run() {
+                String properties[] = new String[2];
+                properties[0] = System.getProperty("awt.image.redrawrate", "100"); //$NON-NLS-1$ //$NON-NLS-2$
+                properties[1] = System.getProperty("awt.image.incrementaldraw", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+                return properties;
+            }
+        };
+        String properties[] = AccessController.doPrivileged(action);
+        // FIXME: rate is never used, can this code and the get property above
+        // be removed?
+        // int rate;
+        //
+        // try {
+        // rate = Integer.decode(properties[0]).intValue();
+        // } catch (NumberFormatException e) {
+        // rate = 100;
+        // }
+        incrementalImageUpdate = properties[1].equals("true"); //$NON-NLS-1$
+    }
+
+    /**
+     * Instantiates a new component.
+     */
+    protected Component() {
+        toolkit.lockAWT();
+        try {
+            orientation = ComponentOrientation.UNKNOWN;
+            redrawManager = null;
+            // ???AWT
+            /*
+             * traversalIDs = this instanceof Container ?
+             * KeyboardFocusManager.contTraversalIDs :
+             * KeyboardFocusManager.compTraversalIDs; for (int element :
+             * traversalIDs) { traversalKeys.put(new Integer(element), null); }
+             * behaviour = createBehavior();
+             */
+            behaviour = null;
+
+            deriveCoalescerFlag();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Determine that the class inherited from Component declares the method
+     * coalesceEvents(), and put the results to the childClassesFlags map.
+     */
+    private void deriveCoalescerFlag() {
+        Class<?> thisClass = getClass();
+        boolean flag = true;
+        synchronized (childClassesFlags) {
+            Boolean flagWrapper = childClassesFlags.get(thisClass);
+            if (flagWrapper == null) {
+                Method coalesceMethod = null;
+                for (Class<?> c = thisClass; c != Component.class; c = c.getSuperclass()) {
+                    try {
+                        coalesceMethod = c.getDeclaredMethod("coalesceEvents", new Class[] { //$NON-NLS-1$
+                                        Class.forName("java.awt.AWTEvent"), //$NON-NLS-1$
+                                        Class.forName("java.awt.AWTEvent")}); //$NON-NLS-1$
+                    } catch (Exception e) {
+                    }
+                    if (coalesceMethod != null) {
+                        break;
+                    }
+                }
+                flag = (coalesceMethod != null);
+                childClassesFlags.put(thisClass, Boolean.valueOf(flag));
+            } else {
+                flag = flagWrapper.booleanValue();
+            }
+        }
+        coalescer = flag;
+        if (flag) {
+            eventsTable = new Hashtable<Integer, LinkedList<AWTEvent>>();
+        } else {
+            eventsTable = null;
+        }
+    }
+
+    /**
+     * Sets the name of the Component.
+     * 
+     * @param name
+     *            the new name of the Component.
+     */
+    public void setName(String name) {
+        String oldName;
+        toolkit.lockAWT();
+        try {
+            autoName = false;
+            oldName = this.name;
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("name", oldName, name); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the name of this Component.
+     * 
+     * @return the name of this Component.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            if ((name == null) && autoName) {
+                name = autoName();
+            }
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string.
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        // ???AWT
+        // int number = toolkit.autoNumber.nextComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Returns the string representation of the Component.
+     * 
+     * @return the string representation of the Component.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code: Component c = new Component(){};
+         * c.setVisible(false); System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * public void add(PopupMenu popup) { toolkit.lockAWT(); try { if
+     * (popup.getParent() == this) { return; } if (popups == null) { popups =
+     * new ArrayList<PopupMenu>(); } popup.setParent(this); popups.add(popup); }
+     * finally { toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Returns true, if the component contains the specified Point.
+     * 
+     * @param p
+     *            the Point.
+     * @return true, if the component contains the specified Point, false
+     *         otherwise.
+     */
+    public boolean contains(Point p) {
+        toolkit.lockAWT();
+        try {
+            return contains(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true, if the component contains the point with the specified
+     * coordinates.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if the component contains the point with the specified
+     *         coordinates, false otherwise.
+     */
+    public boolean contains(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return inside(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by replaced by getSize() method.
+     * 
+     * @return the dimension.
+     * @deprecated Replaced by getSize() method.
+     */
+    @Deprecated
+    public Dimension size() {
+        toolkit.lockAWT();
+        try {
+            return new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * public Container getParent() { toolkit.lockAWT(); try { return parent; }
+     * finally { toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * List.
+     * 
+     * @param out
+     *            the out.
+     * @param indent
+     *            the indent
+     * @return the nearest heavyweight ancestor in hierarchy or
+     *         <code>null</code> if not found.
+     */
+    // ???AWT
+    /*
+     * Component getHWAncestor() { return (parent != null ?
+     * parent.getHWSurface() : null); }
+     */
+
+    /**
+     * @return heavyweight component that is equal to or is a nearest
+     *         heavyweight container of the current component, or
+     *         <code>null</code> if not found.
+     */
+    // ???AWT
+    /*
+     * Component getHWSurface() { Component parent; for (parent = this; (parent
+     * != null) && (parent.isLightweight()); parent = parent .getParent()) { ; }
+     * return parent; } Window getWindowAncestor() { Component par; for (par =
+     * this; par != null && !(par instanceof Window); par = par.getParent()) { ;
+     * } return (Window) par; }
+     */
+
+    /**
+     * To be called by container
+     */
+    // ???AWT
+    /*
+     * void setParent(Container parent) { this.parent = parent;
+     * setRedrawManager(); } void setRedrawManager() { redrawManager =
+     * getRedrawManager(); } public void remove(MenuComponent menu) {
+     * toolkit.lockAWT(); try { if (menu.getParent() == this) {
+     * menu.setParent(null); popups.remove(menu); } } finally {
+     * toolkit.unlockAWT(); } }
+     */
+    /**
+     * Prints a list of this component with the specified number of leading
+     * whitespace characters to the specified PrintStream.
+     * 
+     * @param out
+     *            the output PrintStream object.
+     * @param indent
+     *            how many leading whitespace characters to prepend.
+     */
+    public void list(PrintStream out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintWriter.
+     * 
+     * @param out
+     *            the output PrintWriter object.
+     */
+    public void list(PrintWriter out) {
+        toolkit.lockAWT();
+        try {
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component with the specified number of leading
+     * whitespace characters to the specified PrintWriter.
+     * 
+     * @param out
+     *            the output PrintWriter object.
+     * @param indent
+     *            how many leading whitespace characters to prepend.
+     */
+    public void list(PrintWriter out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets a string composed of the desired number of whitespace characters.
+     * 
+     * @param indent
+     *            the length of the String to return.
+     * @return the string composed of the desired number of whitespace
+     *         characters.
+     */
+    String getIndentStr(int indent) {
+        char[] ind = new char[indent];
+        for (int i = 0; i < indent; ind[i++] = ' ') {
+            ;
+        }
+        return new String(ind);
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintStream.
+     * 
+     * @param out
+     *            the output PrintStream object.
+     */
+    public void list(PrintStream out) {
+        toolkit.lockAWT();
+        try {
+            // default indent = 1
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the standard system output stream.
+     */
+    public void list() {
+        toolkit.lockAWT();
+        try {
+            list(System.out);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints this component.
+     * 
+     * @param g
+     *            the Graphics to be used for painting.
+     */
+    public void print(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints the component and all of its subcomponents.
+     * 
+     * @param g
+     *            the Graphics to be used for painting.
+     */
+    public void printAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paintAll(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by width and height parameters.
+     * 
+     * @param width
+     *            the width of the Component.
+     * @param height
+     *            the height of the Component.
+     */
+    public void setSize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            resize(width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by Dimension object.
+     * 
+     * @param d
+     *            the new size of the Component.
+     */
+    public void setSize(Dimension d) {
+        toolkit.lockAWT();
+        try {
+            resize(d);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
+            setBounds(x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param size
+     *            the size.
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(Dimension size) {
+        toolkit.lockAWT();
+        try {
+            setSize(size.width, size.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is completely opaque.
+     * 
+     * @return true, if this component is completely opaque, false by default.
+     */
+    public boolean isOpaque() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isOpaque();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Disables.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void disable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // ???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, false);
+    }
+
+    /**
+     * Enables this component.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void enable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(true);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // ???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, true);
+    }
+
+    /**
+     * Enables or disable this component.
+     * 
+     * @param b
+     *            the boolean parameter.
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void enable(boolean b) {
+        toolkit.lockAWT();
+        try {
+            if (b) {
+                enable();
+            } else {
+                disable();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the location of this component to the specified Point object;
+     * returns the point of the component's top-left corner.
+     * 
+     * @param rv
+     *            the Point object where the component's top-left corner
+     *            position will be stored.
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation(Point rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Point();
+            }
+            rv.setLocation(getX(), getY());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component on the form; returns the point of the
+     * component's top-left corner.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation() {
+        toolkit.lockAWT();
+        try {
+            return location();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the size of this Component.
+     * 
+     * @return the size of this Component.
+     */
+    public Dimension getSize() {
+        toolkit.lockAWT();
+        try {
+            return size();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the size of this Component to the specified Dimension object.
+     * 
+     * @param rv
+     *            the Dimension object where the size of the Component will be
+     *            stored.
+     * @return the Dimension of this Component.
+     */
+    public Dimension getSize(Dimension rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Dimension();
+            }
+            rv.setSize(getWidth(), getHeight());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is valid. A component is valid if it
+     * is correctly sized and positioned within its parent container and all its
+     * children are also valid.
+     * 
+     * @return true, if the Component is valid, false otherwise.
+     */
+    public boolean isValid() {
+        toolkit.lockAWT();
+        try {
+            return valid && behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @return the Point.
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Point location() {
+        toolkit.lockAWT();
+        try {
+            return new Point(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Connects this Component to a native screen resource and makes it
+     * displayable. This method not be called directly by user applications.
+     */
+    public void addNotify() {
+        toolkit.lockAWT();
+        try {
+            prepare4HierarchyChange();
+            behaviour.addNotify();
+            // ???AWT
+            // finishHierarchyChange(this, parent, 0);
+            // if (dropTarget != null) {
+            // dropTarget.addNotify(peer);
+            // }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Map to display.
+     * 
+     * @param b
+     *            the b.
+     */
+    void mapToDisplay(boolean b) {
+        // ???AWT
+        /*
+         * if (b && !isDisplayable()) { if ((this instanceof Window) || ((parent
+         * != null) && parent.isDisplayable())) { addNotify(); } } else if (!b
+         * && isDisplayable()) { removeNotify(); }
+         */
+    }
+
+    /**
+     * Gets the toolkit.
+     * 
+     * @return accessible context specific for particular component.
+     */
+    // ???AWT
+    /*
+     * AccessibleContext createAccessibleContext() { return null; } public
+     * AccessibleContext getAccessibleContext() { toolkit.lockAWT(); try { if
+     * (accessibleContext == null) { accessibleContext =
+     * createAccessibleContext(); } return accessibleContext; } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Gets Toolkit for the current Component.
+     * 
+     * @return the Toolkit of this Component.
+     */
+    public Toolkit getToolkit() {
+        return toolkit;
+    }
+
+    /**
+     * Gets this component's locking object for AWT component tree and layout
+     * operations.
+     * 
+     * @return the tree locking object.
+     */
+    public final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * Handles the event. Use ActionListener instead of this.
+     * 
+     * @param evt
+     *            the Event.
+     * @param what
+     *            the event's key.
+     * @return true, if successful.
+     * @deprecated Use ActionListener class for registering event listener.
+     */
+    @Deprecated
+    public boolean action(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Gets the property change support.
+     * 
+     * @return the property change support.
+     */
+    private PropertyChangeSupport getPropertyChangeSupport() {
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                propertyChangeSupport = new PropertyChangeSupport(this);
+            }
+            return propertyChangeSupport;
+        }
+    }
+
+    // ???AWT
+    /*
+     * public void addPropertyChangeListener(PropertyChangeListener listener) {
+     * getPropertyChangeSupport().addPropertyChangeListener(listener); } public
+     * void addPropertyChangeListener(String propertyName,
+     * PropertyChangeListener listener) {
+     * getPropertyChangeSupport().addPropertyChangeListener(propertyName,
+     * listener); } public void applyComponentOrientation(ComponentOrientation
+     * orientation) { toolkit.lockAWT(); try {
+     * setComponentOrientation(orientation); } finally { toolkit.unlockAWT(); }
+     * }
+     */
+
+    /**
+     * Returns true if the set of focus traversal keys for the given focus
+     * traversal operation has been explicitly defined for this Component.
+     * 
+     * @param id
+     *            the ID of traversal key.
+     * @return true, if the set of focus traversal keys for the given focus.
+     *         traversal operation has been explicitly defined for this
+     *         Component, false otherwise.
+     */
+    public boolean areFocusTraversalKeysSet(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer Id = new Integer(id);
+            if (traversalKeys.containsKey(Id)) {
+                return traversalKeys.get(Id) != null;
+            }
+            // awt.14F=invalid focus traversal key identifier
+            throw new IllegalArgumentException(Messages.getString("awt.14F")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounds of the Component.
+     * 
+     * @return the rectangle bounds of the Component.
+     * @deprecated Use getBounds() methood.
+     */
+    @Deprecated
+    public Rectangle bounds() {
+        toolkit.lockAWT();
+        try {
+            return new Rectangle(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image with the specified
+     * width and height that is being created.
+     * 
+     * @param image
+     *            the image to be checked.
+     * @param width
+     *            the width of scaled image which status is being checked, or
+     *            -1.
+     * @param height
+     *            the height of scaled image which status is being checked, or
+     *            -1.
+     * @param observer
+     *            the ImageObserver object to be notified while the image is
+     *            being prepared.
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image that is being
+     * created.
+     * 
+     * @param image
+     *            the image to be checked.
+     * @param observer
+     *            the ImageObserver object to be notified while the image is
+     *            being prepared.
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Coalesces the existed event with new event.
+     * 
+     * @param existingEvent
+     *            the existing event in the EventQueue.
+     * @param newEvent
+     *            the new event to be posted to the EventQueue.
+     * @return the coalesced AWTEvent, or null if there is no coalescing done.
+     */
+    protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) {
+        toolkit.lockAWT();
+        try {
+            // Nothing to do:
+            // 1. Mouse events coalesced at WTK level
+            // 2. Paint events handled by RedrawManager
+            // This method is for overriding only
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component is a coalescer.
+     * 
+     * @return true, if is coalescer.
+     */
+    boolean isCoalescer() {
+        return coalescer;
+    }
+
+    /**
+     * Gets the relative event.
+     * 
+     * @param id
+     *            the id.
+     * @return the relative event.
+     */
+    AWTEvent getRelativeEvent(int id) {
+        Integer idWrapper = new Integer(id);
+        eventsList = eventsTable.get(idWrapper);
+        if (eventsList == null) {
+            eventsList = new LinkedList<AWTEvent>();
+            eventsTable.put(idWrapper, eventsList);
+            return null;
+        }
+        if (eventsList.isEmpty()) {
+            return null;
+        }
+        return eventsList.getLast();
+    }
+
+    /**
+     * Adds the new event.
+     * 
+     * @param event
+     *            the event.
+     */
+    void addNewEvent(AWTEvent event) {
+        eventsList.addLast(event);
+    }
+
+    /**
+     * Removes the relative event.
+     */
+    void removeRelativeEvent() {
+        eventsList.removeLast();
+    }
+
+    /**
+     * Removes the next event.
+     * 
+     * @param id
+     *            the id.
+     */
+    void removeNextEvent(int id) {
+        eventsTable.get(new Integer(id)).removeFirst();
+    }
+
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param producer
+     *            the ImageProducer to be used for image creation.
+     * @return the image with the specified ImageProducer.
+     */
+    public Image createImage(ImageProducer producer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.createImage(producer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image to be used for double buffering.
+     * 
+     * @param width
+     *            the width of the image.
+     * @param height
+     *            the height of the image.
+     * @return the off-screen drawable image or null if the component is not
+     *         displayable or GraphicsEnvironment.isHeadless() method returns
+     *         true.
+     */
+    public Image createImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            ColorModel cm = gc.getColorModel(Transparency.OPAQUE);
+            WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+            Image image = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image with the specified width, height and
+     * ImageCapabilities.
+     * 
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     * @param caps
+     *            the ImageCapabilities.
+     * @return the volatile image.
+     * @throws AWTException
+     *             if an image with the specified capabilities cannot be
+     *             created.
+     */
+    public VolatileImage createVolatileImage(int width, int height, ImageCapabilities caps)
+            throws AWTException {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height, caps);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates a volatile off-screen drawable image which is used for double
+     * buffering.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @return the volatile image a volatile off-screen drawable image which is
+     *         used for double buffering or null if the component is not
+     *         displayable, or GraphicsEnvironment.isHeadless() method returns
+     *         true.
+     */
+    public VolatileImage createVolatileImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Fill the image being created by createImage() or createVolatileImage()
+     * with the component's background color to prepare it for double-buffered
+     * painting.
+     * 
+     * @param image
+     *            the image.
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     */
+    private void fillImageBackground(Image image, int width, int height) {
+        Graphics gr = image.getGraphics();
+        gr.setColor(getBackground());
+        gr.fillRect(0, 0, width, height);
+        gr.dispose();
+    }
+
+    /**
+     * Delivers event.
+     * 
+     * @param evt
+     *            the event.
+     * @deprecated Replaced by dispatchEvent(AWTEvent e) method.
+     */
+    @Deprecated
+    public void deliverEvent(Event evt) {
+        postEvent(evt);
+    }
+
+    /**
+     * Prompts the layout manager to lay out this component.
+     */
+    public void doLayout() {
+        toolkit.lockAWT();
+        try {
+            layout();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // Implemented in Container
+    }
+
+    /**
+     * Fire property change impl.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old value.
+     * @param newValue
+     *            the new value.
+     */
+    private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
+        PropertyChangeSupport pcs;
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                return;
+            }
+            pcs = propertyChangeSupport;
+        }
+        pcs.firePropertyChange(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Reports a bound property changes for int properties.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
+        firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
+    }
+
+    /**
+     * Report a bound property change for a boolean-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the property's old value.
+     * @param newValue
+     *            the property's new value.
+     */
+    protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
+        firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+    }
+
+    /**
+     * Reports a bound property change for an Object-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the property's old value.
+     * @param newValue
+     *            the property's new value.
+     */
+    protected void firePropertyChange(final String propertyName, final Object oldValue,
+            final Object newValue) {
+        firePropertyChangeImpl(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Report a bound property change for a byte-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the property's old value.
+     * @param newValue
+     *            the property's new value.
+     */
+    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
+        firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
+    }
+
+    /**
+     * Report a bound property change for a char-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    public void firePropertyChange(String propertyName, char oldValue, char newValue) {
+        firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
+    }
+
+    /**
+     * Report a bound property change for a short-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    public void firePropertyChange(String propertyName, short oldValue, short newValue) {
+        firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
+    }
+
+    /**
+     * Report a bound property change for a long-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    public void firePropertyChange(String propertyName, long oldValue, long newValue) {
+        firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
+    }
+
+    /**
+     * Report a bound property change for a float-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    public void firePropertyChange(String propertyName, float oldValue, float newValue) {
+        firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
+    }
+
+    /**
+     * Report a bound property change for a double-valued property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old property's value.
+     * @param newValue
+     *            the new property's value.
+     */
+    public void firePropertyChange(String propertyName, double oldValue, double newValue) {
+        firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
+    }
+
+    /**
+     * Gets the alignment along the x axis.
+     * 
+     * @return the alignment along the x axis.
+     */
+    public float getAlignmentX() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the alignment along the y axis.
+     * 
+     * @return the alignment along y axis.
+     */
+    public float getAlignmentY() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the background color for this component.
+     * 
+     * @return the background color for this component.
+     */
+    public Color getBackground() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT
+            /*
+             * if ((backColor == null) && (parent != null)) { return
+             * parent.getBackground(); }
+             */
+            return backColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of this component.
+     * 
+     * @return the bounding rectangle of this component.
+     */
+    public Rectangle getBounds() {
+        toolkit.lockAWT();
+        try {
+            return bounds();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Writes the data of the bounding rectangle to the specified Rectangle
+     * object.
+     * 
+     * @param rv
+     *            the Rectangle object where the bounding rectangle's data is
+     *            stored.
+     * @return the bounding rectangle.
+     */
+    public Rectangle getBounds(Rectangle rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Rectangle();
+            }
+            rv.setBounds(x, y, w, h);
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the color model of the Component.
+     * 
+     * @return the color model of the Component.
+     */
+    public ColorModel getColorModel() {
+        toolkit.lockAWT();
+        try {
+            return getToolkit().getColorModel();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the specified Point.
+     * 
+     * @param p
+     *            the Point.
+     * @return the Component which contains the specified Point.
+     */
+    public Component getComponentAt(Point p) {
+        toolkit.lockAWT();
+        try {
+            return getComponentAt(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the point with the specified
+     * coordinates.
+     * 
+     * @param x
+     *            the x coordinate of the point.
+     * @param y
+     *            the y coordinate of the point.
+     * @return the Component which contains the point with the specified
+     *         coordinates.
+     */
+    public Component getComponentAt(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return locate(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the component's orientation.
+     * 
+     * @return the component's orientation.
+     */
+    public ComponentOrientation getComponentOrientation() {
+        toolkit.lockAWT();
+        try {
+            return orientation;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the cursor of the Component.
+     * 
+     * @return the Cursor.
+     */
+    public Cursor getCursor() {
+        toolkit.lockAWT();
+        try {
+            if (cursor != null) {
+                return cursor;
+                // ???AWT
+                /*
+                 * } else if (parent != null) { return parent.getCursor();
+                 */
+            }
+            return Cursor.getDefaultCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * public DropTarget getDropTarget() { toolkit.lockAWT(); try { return
+     * dropTarget; } finally { toolkit.unlockAWT(); } } public Container
+     * getFocusCycleRootAncestor() { toolkit.lockAWT(); try { for (Container c =
+     * parent; c != null; c = c.getParent()) { if (c.isFocusCycleRoot()) {
+     * return c; } } return null; } finally { toolkit.unlockAWT(); } }
+     * @SuppressWarnings("unchecked") public Set<AWTKeyStroke>
+     * getFocusTraversalKeys(int id) { toolkit.lockAWT(); try { Integer kId =
+     * new Integer(id); KeyboardFocusManager.checkTraversalKeysID(traversalKeys,
+     * kId); Set<? extends AWTKeyStroke> keys = traversalKeys.get(kId); if (keys
+     * == null && parent != null) { keys = parent.getFocusTraversalKeys(id); }
+     * if (keys == null) { keys =
+     * KeyboardFocusManager.getCurrentKeyboardFocusManager()
+     * .getDefaultFocusTraversalKeys(id); } return (Set<AWTKeyStroke>) keys; }
+     * finally { toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Checks if the the focus traversal keys are enabled for this component.
+     * 
+     * @return true, if the the focus traversal keys are enabled for this
+     *         component, false otherwise.
+     */
+    public boolean getFocusTraversalKeysEnabled() {
+        toolkit.lockAWT();
+        try {
+            return focusTraversalKeysEnabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the font metrics of the specified Font.
+     * 
+     * @param f
+     *            the Font.
+     * @return the FontMetrics of the specified Font.
+     */
+    @SuppressWarnings("deprecation")
+    public FontMetrics getFontMetrics(Font f) {
+        return toolkit.getFontMetrics(f);
+    }
+
+    /**
+     * Gets the foreground color of the Component.
+     * 
+     * @return the foreground color of the Component.
+     */
+    public Color getForeground() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT
+            /*
+             * if (foreColor == null && parent != null) { return
+             * parent.getForeground(); }
+             */
+            return foreColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Graphics of the Component or null if this Component is not
+     * displayable.
+     * 
+     * @return the Graphics of the Component or null if this Component is not
+     *         displayable.
+     */
+    public Graphics getGraphics() {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            Graphics g = behaviour.getGraphics(0, 0, w, h);
+            g.setColor(foreColor);
+            g.setFont(font);
+            return g;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the GraphicsConfiguration associated with this Component.
+     * 
+     * @return the GraphicsConfiguration associated with this Component.
+     */
+    public GraphicsConfiguration getGraphicsConfiguration() {
+        // ???AWT
+        /*
+         * toolkit.lockAWT(); try { Window win = getWindowAncestor(); if (win ==
+         * null) { return null; } return win.getGraphicsConfiguration(); }
+         * finally { toolkit.unlockAWT(); }
+         */
+        return null;
+    }
+
+    /**
+     * Gets the height of the Component.
+     * 
+     * @return the height of the Component.
+     */
+    public int getHeight() {
+        toolkit.lockAWT();
+        try {
+            return h;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if paint messages received from the operating system should
+     * be ignored.
+     * 
+     * @return true if paint messages received from the operating system should
+     *         be ignored, false otherwise.
+     */
+    public boolean getIgnoreRepaint() {
+        toolkit.lockAWT();
+        try {
+            return ignoreRepaint;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input context of this component for handling the communication
+     * with input methods when text is entered in this component.
+     * 
+     * @return the InputContext used by this Component or null if no context is
+     *         specifined.
+     */
+    public InputContext getInputContext() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT
+            /*
+             * Container parent = getParent(); if (parent != null) { return
+             * parent.getInputContext(); }
+             */
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input method request handler which supports requests from input
+     * methods for this component, or null for default.
+     * 
+     * @return the input method request handler which supports requests from
+     *         input methods for this component, or null for default.
+     */
+    public InputMethodRequests getInputMethodRequests() {
+        return null;
+    }
+
+    /**
+     * Gets the locale of this Component.
+     * 
+     * @return the locale of this Component.
+     */
+    public Locale getLocale() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT
+            /*
+             * if (locale == null) { if (parent == null) { if (this instanceof
+             * Window) { return Locale.getDefault(); } // awt.150=no parent
+             * throw new
+             * IllegalComponentStateException(Messages.getString("awt.150"));
+             * //$NON-NLS-1$ } return getParent().getLocale(); }
+             */
+            return locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component in the form of a point specifying the
+     * component's top-left corner in the screen's coordinate space.
+     * 
+     * @return the Point giving the component's location in the screen's
+     *         coordinate space.
+     * @throws IllegalComponentStateException
+     *             if the component is not shown on the screen.
+     */
+    public Point getLocationOnScreen() throws IllegalComponentStateException {
+        toolkit.lockAWT();
+        try {
+            Point p = new Point();
+            if (isShowing()) {
+                // ???AWT
+                /*
+                 * Component comp; for (comp = this; comp != null && !(comp
+                 * instanceof Window); comp = comp .getParent()) {
+                 * p.translate(comp.getX(), comp.getY()); } if (comp instanceof
+                 * Window) { p.translate(comp.getX(), comp.getY()); }
+                 */
+                return p;
+            }
+            // awt.151=component must be showing on the screen to determine its
+            // location
+            throw new IllegalComponentStateException(Messages.getString("awt.151")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the peer. This method should not be called directly by user
+     * applications.
+     * 
+     * @return the ComponentPeer.
+     * @deprecated Replaced by isDisplayable().
+     */
+    @Deprecated
+    public ComponentPeer getPeer() {
+        toolkit.lockAWT();
+        try {
+            if (behaviour.isDisplayable()) {
+                return peer;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of the property change listeners registered to this
+     * Component.
+     * 
+     * @return an array of the PropertyChangeListeners registered to this
+     *         Component.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return getPropertyChangeSupport().getPropertyChangeListeners();
+    }
+
+    /**
+     * Gets an array of PropertyChangeListener objects registered to this
+     * Component for the specified property.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @return an array of PropertyChangeListener objects registered to this
+     *         Component for the specified property.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+        return getPropertyChangeSupport().getPropertyChangeListeners(propertyName);
+    }
+
+    /**
+     * Gets the width of the Component.
+     * 
+     * @return the width of the Component.
+     */
+    public int getWidth() {
+        toolkit.lockAWT();
+        try {
+            return w;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the x coordinate of the component's top-left corner.
+     * 
+     * @return the x coordinate of the component's top-left corner.
+     */
+    public int getX() {
+        toolkit.lockAWT();
+        try {
+            return x;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the y coordinate of the component's top-left corner.
+     * 
+     * @return the y coordinate of the component's top-left corner.
+     */
+    public int getY() {
+        toolkit.lockAWT();
+        try {
+            return y;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Got the focus.
+     * 
+     * @param evt
+     *            the Event.
+     * @param what
+     *            the Object.
+     * @return true, if successful.
+     * @deprecated Replaced by processFocusEvent(FocusEvent) method.
+     */
+    @Deprecated
+    public boolean gotFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Handles event.
+     * 
+     * @param evt
+     *            the Event.
+     * @return true, if successful.
+     * @deprecated Replaced by processEvent(AWTEvent) method.
+     */
+    @Deprecated
+    public boolean handleEvent(Event evt) {
+        switch (evt.id) {
+            case Event.ACTION_EVENT:
+                return action(evt, evt.arg);
+            case Event.GOT_FOCUS:
+                return gotFocus(evt, null);
+            case Event.LOST_FOCUS:
+                return lostFocus(evt, null);
+            case Event.MOUSE_DOWN:
+                return mouseDown(evt, evt.x, evt.y);
+            case Event.MOUSE_DRAG:
+                return mouseDrag(evt, evt.x, evt.y);
+            case Event.MOUSE_ENTER:
+                return mouseEnter(evt, evt.x, evt.y);
+            case Event.MOUSE_EXIT:
+                return mouseExit(evt, evt.x, evt.y);
+            case Event.MOUSE_MOVE:
+                return mouseMove(evt, evt.x, evt.y);
+            case Event.MOUSE_UP:
+                return mouseUp(evt, evt.x, evt.y);
+            case Event.KEY_ACTION:
+            case Event.KEY_PRESS:
+                return keyDown(evt, evt.key);
+            case Event.KEY_ACTION_RELEASE:
+            case Event.KEY_RELEASE:
+                return keyUp(evt, evt.key);
+        }
+        return false;// event not handled
+    }
+
+    /**
+     * Checks whether the Component is the focus owner or not.
+     * 
+     * @return true, if the Component is the focus owner, false otherwise.
+     */
+    public boolean hasFocus() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT: return isFocusOwner();
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Hides the Component.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void hide() {
+        toolkit.lockAWT();
+        try {
+            if (!visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            visible = false;
+            moveFocusOnHide();
+            behaviour.setVisible(false);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
+            // ???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(null);
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the point with the specified coordinates belongs to
+     * the Commponent.
+     * 
+     * @param x
+     *            the x coordinate of the Point.
+     * @param y
+     *            the y coordinate of the Point.
+     * @return true, if the point with the specified coordinates belongs to the
+     *         Commponent, false otherwise.
+     * @deprecated Replaced by contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Invalidates the component, this component and all parents above it are
+     * marked as needing to be laid out.
+     */
+    public void invalidate() {
+        toolkit.lockAWT();
+        try {
+            valid = false;
+            resetDefaultSize();
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the background color is set to this Component.
+     * 
+     * @return true, if the background color is set to this Component, false
+     *         otherwise.
+     */
+    public boolean isBackgroundSet() {
+        toolkit.lockAWT();
+        try {
+            return backColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not a cursor is set for the Component.
+     * 
+     * @return true, if a cursor is set for the Component, false otherwise.
+     */
+    public boolean isCursorSet() {
+        toolkit.lockAWT();
+        try {
+            return cursor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is displayable.
+     * 
+     * @return true, if this Component is displayable, false otherwise.
+     */
+    public boolean isDisplayable() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is painted to an buffer which is
+     * copied to the screen later.
+     * 
+     * @return true, if this component is painted to an buffer which is copied
+     *         to the screen later, false otherwise.
+     */
+    public boolean isDoubleBuffered() {
+        toolkit.lockAWT();
+        try {
+            // false by default
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is enabled.
+     * 
+     * @return true, if this Component is enabled, false otherwise.
+     */
+    public boolean isEnabled() {
+        toolkit.lockAWT();
+        try {
+            return enabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * "Recursive" isEnabled().
+     * 
+     * @return true if not only component itself is enabled but its heavyweight
+     *         parent is also "indirectly" enabled.
+     */
+    boolean isIndirectlyEnabled() {
+        Component comp = this;
+        while (comp != null) {
+            if (!comp.isLightweight() && !comp.isEnabled()) {
+                return false;
+            }
+            // ???AWT: comp = comp.getRealParent();
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the component is key enabled.
+     * 
+     * @return true, if the component is enabled and indirectly enabled.
+     */
+    boolean isKeyEnabled() {
+        if (!isEnabled()) {
+            return false;
+        }
+        return isIndirectlyEnabled();
+    }
+
+    /**
+     * Gets only parent of a child component, but not owner of a window.
+     * 
+     * @return parent of child component, null if component is a top-level
+     *         (Window instance).
+     */
+    // ???AWT
+    /*
+     * Container getRealParent() { return (!(this instanceof Window) ?
+     * getParent() : null); } public boolean isFocusCycleRoot(Container
+     * container) { toolkit.lockAWT(); try { return getFocusCycleRootAncestor()
+     * == container; } finally { toolkit.unlockAWT(); } } public boolean
+     * isFocusOwner() { toolkit.lockAWT(); try { return
+     * KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() ==
+     * this; } finally { toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Checks whether or not this Component can be focusable.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     * @deprecated Replaced by isFocusable().
+     */
+    @Deprecated
+    public boolean isFocusTraversable() {
+        toolkit.lockAWT();
+        try {
+            overridenIsFocusable = false;
+            return focusable; // a Component must either be both focusable and
+            // focus traversable, or neither
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component can be focusable or not.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     */
+    public boolean isFocusable() {
+        toolkit.lockAWT();
+        try {
+            return isFocusTraversable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the Font is set for this Component or not.
+     * 
+     * @return true, if the Font is set, false otherwise.
+     */
+    public boolean isFontSet() {
+        toolkit.lockAWT();
+        try {
+            return font != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if foreground color is set for the Component or not.
+     * 
+     * @return true, if is foreground color is set for the Component, false
+     *         otherwise.
+     */
+    public boolean isForegroundSet() {
+        toolkit.lockAWT();
+        try {
+            return foreColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if this component has a lightweight peer.
+     * 
+     * @return true, if this component has a lightweight peer, false if it has a
+     *         native peer or no peer.
+     */
+    public boolean isLightweight() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isLightweight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is shown.
+     * 
+     * @return true, if this Component is shown, false otherwise.
+     */
+    public boolean isShowing() {
+        // ???AWT
+        /*
+         * toolkit.lockAWT(); try { return (isVisible() && isDisplayable() &&
+         * (parent != null) && parent.isShowing()); } finally {
+         * toolkit.unlockAWT(); }
+         */
+        return false;
+    }
+
+    /**
+     * Checks whether or not this Component is visible.
+     * 
+     * @return true, if the Component is visible, false otherwise.
+     */
+    public boolean isVisible() {
+        toolkit.lockAWT();
+        try {
+            return visible;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param key
+     *            the key code.
+     * @return true, if successful.
+     * @deprecated Replaced by replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyDown(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param key
+     *            the key code.
+     * @return true, if successful.
+     * @deprecated Replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyUp(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: Replaced by doLayout() method.
+     * 
+     * @deprecated Replaced by doLayout() method.
+     */
+    @Deprecated
+    public void layout() {
+        toolkit.lockAWT();
+        try {
+            // Implemented in Container
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return The component.
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Component locate(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            if (contains(x, y)) {
+                return this;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processFocusEvent(FocusEvent).
+     * 
+     * @param evt
+     *            the Event.
+     * @param what
+     *            the Object.
+     * @return true, if successful.
+     * @deprecated Replaced by processFocusEvent(FocusEvent).
+     */
+    @Deprecated
+    public boolean lostFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt
+     *            the MouseEvent.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if successful.
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseDown(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if successful.
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public boolean mouseDrag(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if successful.
+     * @deprecated replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseEnter(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if successful.
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseExit(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     * @return true, if successful.
+     */
+    @Deprecated
+    public boolean mouseMove(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt
+     *            the Event.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @return true, if successful.
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseUp(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by setLocation(int, int) method.
+     * 
+     * @param x
+     *            the x coordinates.
+     * @param y
+     *            the y coordinates.
+     * @deprecated Replaced by setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
+            setBounds(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * @Deprecated public void nextFocus() { toolkit.lockAWT(); try {
+     * transferFocus(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Returns a string representation of the component's state.
+     * 
+     * @return the string representation of the component's state.
+     */
+    protected String paramString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code: Component c = new Component(){};
+         * c.setVisible(false); System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getName() + "," + getX() + "," + getY() + "," + getWidth() + "x" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                    + getHeight() + (!isVisible() ? ",hidden" : ""); //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public boolean postEvent(Event evt) {
+        boolean handled = handleEvent(evt);
+        if (handled) {
+            return true;
+        }
+        // ???AWT
+        /*
+         * // propagate non-handled events up to parent Component par = parent;
+         * // try to call postEvent only on components which // override any of
+         * deprecated method handlers // while (par != null &&
+         * !par.deprecatedEventHandler) { // par = par.parent; // } // translate
+         * event coordinates before posting it to parent if (par != null) {
+         * evt.translate(x, y); par.postEvent(evt); }
+         */
+        return false;
+    }
+
+    /**
+     * Prepares an image for rendering on the Component.
+     * 
+     * @param image
+     *            the Image to be prepared.
+     * @param observer
+     *            the ImageObserver object to be notified as soon as the image
+     *            is prepared.
+     * @return true if the image has been fully prepared, false otherwise.
+     */
+    public boolean prepareImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares an image for rendering on the Component with the specified
+     * width, height, and ImageObserver.
+     * 
+     * @param image
+     *            the Image to be prepared.
+     * @param width
+     *            the width of scaled image.
+     * @param height
+     *            the height of scaled height.
+     * @param observer
+     *            the ImageObserver object to be notified as soon as the image
+     *            is prepared.
+     * @return true if the image is been fully prepared, false otherwise.
+     */
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Makes this Component undisplayable.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+            // ???AWT
+            /*
+             * if (dropTarget != null) { dropTarget.removeNotify(peer); }
+             */
+            prepare4HierarchyChange();
+            // /???AWT: moveFocus();
+            behaviour.removeNotify();
+            // ???AWT: finishHierarchyChange(this, parent, 0);
+            removeNotifyInputContext();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Calls InputContext.removeNotify.
+     */
+    private void removeNotifyInputContext() {
+        if (!inputMethodsEnabled) {
+            return;
+        }
+        InputContext ic = getInputContext();
+        if (ic != null) {
+            // ???AWT: ic.removeNotify(this);
+        }
+    }
+
+    /**
+     * This method is called when some property of a component changes, making
+     * it unfocusable, e. g. hide(), removeNotify(), setEnabled(false),
+     * setFocusable(false) is called, and therefore automatic forward focus
+     * traversal is necessary
+     */
+    // ???AWT
+    /*
+     * void moveFocus() { // don't use transferFocus(), but query focus
+     * traversal policy directly // and if it returns null, transfer focus up
+     * cycle // and find next focusable component there KeyboardFocusManager kfm
+     * = KeyboardFocusManager.getCurrentKeyboardFocusManager(); Container root =
+     * kfm.getCurrentFocusCycleRoot(); Component nextComp = this; boolean
+     * success = !isFocusOwner(); while (!success) { if (root !=
+     * nextComp.getFocusCycleRootAncestor()) { // component was probably removed
+     * from container // so focus will be lost in some time return; } nextComp =
+     * root.getFocusTraversalPolicy().getComponentAfter(root, nextComp); if
+     * (nextComp == this) { nextComp = null; // avoid looping } if (nextComp !=
+     * null) { success = nextComp.requestFocusInWindow(); } else { nextComp =
+     * root; root = root.getFocusCycleRootAncestor(); // if no acceptable
+     * component is found at all - clear global // focus owner if (root == null)
+     * { if (nextComp instanceof Window) { Window wnd = (Window) nextComp;
+     * wnd.setFocusOwner(null); wnd.setRequestedFocus(null); }
+     * kfm.clearGlobalFocusOwner(); return; } } } }
+     */
+
+    /**
+     * For Container there's a difference between moving focus when being made
+     * invisible or made unfocusable in some other way, because when container
+     * is made invisible, component still remains visible, i. e. its hide() or
+     * setVisible() is not called.
+     */
+    void moveFocusOnHide() {
+        // ???AWT: moveFocus();
+    }
+
+    /**
+     * Removes the property change listener registered for this component.
+     * 
+     * @param listener
+     *            the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Removes the property change listener registered fot this component for
+     * the specified propertyy.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param listener
+     *            the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(propertyName, listener);
+    }
+
+    /**
+     * Repaints the specified rectangle of this component within tm
+     * milliseconds.
+     * 
+     * @param tm
+     *            the time in milliseconds before updating.
+     * @param x
+     *            the x coordinate of Rectangle.
+     * @param y
+     *            the y coordinate of Rectangle.
+     * @param width
+     *            the width of Rectangle.
+     * @param height
+     *            the height of Rectangle.
+     */
+    public void repaint(long tm, int x, int y, int width, int height) {
+        // ???AWT
+        /*
+         * toolkit.lockAWT(); try { if (width <= 0 || height <= 0 ||
+         * (redrawManager == null) || !isShowing()) { return; } if (behaviour
+         * instanceof LWBehavior) { if (parent == null || !parent.visible ||
+         * !parent.behaviour.isDisplayable()) { return; } if (repaintRegion ==
+         * null) { repaintRegion = new MultiRectArea(new Rectangle(x, y, width,
+         * height)); } repaintRegion.intersect(new Rectangle(0, 0, this.w,
+         * this.h)); repaintRegion.translate(this.x, this.y);
+         * parent.repaintRegion = repaintRegion; repaintRegion = null;
+         * parent.repaint(tm, x + this.x, y + this.y, width, height); } else {
+         * if (repaintRegion != null) { redrawManager.addUpdateRegion(this,
+         * repaintRegion); repaintRegion = null; } else {
+         * redrawManager.addUpdateRegion(this, new Rectangle(x, y, width,
+         * height)); }
+         * toolkit.getSystemEventQueueCore().notifyEventMonitor(toolkit); } }
+         * finally { toolkit.unlockAWT(); }
+         */
+    }
+
+    /**
+     * Post event.
+     * 
+     * @param e
+     *            the e.
+     */
+    void postEvent(AWTEvent e) {
+        getToolkit().getSystemEventQueueImpl().postEvent(e);
+    }
+
+    /**
+     * Repaints the specified Rectangle of this Component.
+     * 
+     * @param x
+     *            the x coordinate of Rectangle.
+     * @param y
+     *            the y coordinate of Rectangle.
+     * @param width
+     *            the width of Rectangle.
+     * @param height
+     *            the height of Rectangle.
+     */
+    public void repaint(int x, int y, int width, int height) {
+        toolkit.lockAWT();
+        try {
+            repaint(0, x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints this component.
+     */
+    public void repaint() {
+        toolkit.lockAWT();
+        try {
+            if (w > 0 && h > 0) {
+                repaint(0, 0, 0, w, h);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints the component within tm milliseconds.
+     * 
+     * @param tm
+     *            the time in milliseconds before updating.
+     */
+    public void repaint(long tm) {
+        toolkit.lockAWT();
+        try {
+            repaint(tm, 0, 0, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Requests that this Component get the input focus temporarily. This
+     * component must be displayable, visible, and focusable.
+     * 
+     * @param temporary
+     *            this parameter is true if the focus change is temporary, when
+     *            the window loses the focus.
+     * @return true if the focus change request is succeeded, false otherwise.
+     */
+    protected boolean requestFocus(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            // ???AWT: return requestFocusImpl(temporary, true, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // ???AWT
+        return false;
+    }
+
+    /**
+     * Requests that this Component get the input focus. This component must be
+     * displayable, visible, and focusable.
+     */
+    public void requestFocus() {
+        toolkit.lockAWT();
+        try {
+            requestFocus(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * protected boolean requestFocusInWindow(boolean temporary) {
+     * toolkit.lockAWT(); try { Window wnd = getWindowAncestor(); if ((wnd ==
+     * null) || !wnd.isFocused()) { return false; } return
+     * requestFocusImpl(temporary, false, false); } finally {
+     * toolkit.unlockAWT(); } } boolean requestFocusImpl(boolean temporary,
+     * boolean crossWindow, boolean rejectionRecovery) { if (!rejectionRecovery
+     * && isFocusOwner()) { return true; } Window wnd = getWindowAncestor();
+     * Container par = getRealParent(); if ((par != null) && par.isRemoved) {
+     * return false; } if (!isShowing() || !isFocusable() ||
+     * !wnd.isFocusableWindow()) { return false; } return
+     * KeyboardFocusManager.getCurrentKeyboardFocusManager().requestFocus(this,
+     * temporary, crossWindow, true); } public boolean requestFocusInWindow() {
+     * toolkit.lockAWT(); try { return requestFocusInWindow(false); } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Deprecated: replaced by setBounds(int, int, int, int) method.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @param w
+     *            the width.
+     * @param h
+     *            the height.
+     * @deprecated Replaced by setBounds(int, int, int, int) method.
+     */
+    @Deprecated
+    public void reshape(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            setBounds(x, y, w, h, boundsMaskParam, true);
+            boundsMaskParam = 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified
+     * x,y coordinates of the top-left corner and the width and height.
+     * 
+     * @param x
+     *            the x coordinate of the rectangle's top-left corner.
+     * @param y
+     *            the y coordinate of the rectangle's top-left corner.
+     * @param w
+     *            the width of rectangle.
+     * @param h
+     *            the height of rectangle.
+     */
+    public void setBounds(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            reshape(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified
+     * x,y coordinates of the top-left corner and the width and height and posts
+     * the appropriate events.
+     * 
+     * @param x
+     *            the x coordinate of the rectangle's top-left corner.
+     * @param y
+     *            the y coordinate of the rectangle's top-left corner.
+     * @param w
+     *            the width of rectangle.
+     * @param h
+     *            the height of rectangle.
+     * @param bMask
+     *            the bitmask of bounds options.
+     * @param updateBehavior
+     *            the whether to update the behavoir's bounds as well.
+     */
+    void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
+        int oldX = this.x;
+        int oldY = this.y;
+        int oldW = this.w;
+        int oldH = this.h;
+        setBoundsFields(x, y, w, h, bMask);
+        // Moved
+        if ((oldX != this.x) || (oldY != this.y)) {
+            // ???AWT: invalidateRealParent();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
+        }
+        // Resized
+        if ((oldW != this.w) || (oldH != this.h)) {
+            invalidate();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
+        }
+        if (updateBehavior) {
+            behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
+        }
+        notifyInputMethod(new Rectangle(x, y, w, h));
+    }
+
+    /**
+     * Calls InputContextImpl.notifyClientWindowChanged.
+     * 
+     * @param bounds
+     *            the bounds.
+     */
+    void notifyInputMethod(Rectangle bounds) {
+        // only Window actually notifies IM of bounds change
+    }
+
+    /**
+     * Sets the bounds fields.
+     * 
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     * @param w
+     *            the w.
+     * @param h
+     *            the h.
+     * @param bMask
+     *            the b mask.
+     */
+    private void setBoundsFields(int x, int y, int w, int h, int bMask) {
+        if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
+            this.w = w;
+            this.h = h;
+        }
+        if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
+            this.x = x;
+            this.y = y;
+        }
+    }
+
+    /**
+     * Gets the native insets.
+     * 
+     * @return the native insets.
+     */
+    Insets getNativeInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Gets the insets.
+     * 
+     * @return the insets.
+     */
+    Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Checks if is mouse exited expected.
+     * 
+     * @return true, if is mouse exited expected.
+     */
+    boolean isMouseExitedExpected() {
+        return mouseExitedExpected;
+    }
+
+    /**
+     * Sets the mouse exited expected.
+     * 
+     * @param expected
+     *            the new mouse exited expected.
+     */
+    void setMouseExitedExpected(boolean expected) {
+        mouseExitedExpected = expected;
+    }
+
+    /**
+     * Sets the new bounding rectangle for this Component.
+     * 
+     * @param r
+     *            the new bounding rectangle.
+     */
+    public void setBounds(Rectangle r) {
+        toolkit.lockAWT();
+        try {
+            setBounds(r.x, r.y, r.width, r.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the component orientation which affects the component's elements and
+     * text within this component.
+     * 
+     * @param o
+     *            the ComponentOrientation object.
+     */
+    public void setComponentOrientation(ComponentOrientation o) {
+        ComponentOrientation oldOrientation;
+        toolkit.lockAWT();
+        try {
+            oldOrientation = orientation;
+            orientation = o;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
+        invalidate();
+    }
+
+    /**
+     * Sets the specified cursor for this Component.
+     * 
+     * @param cursor
+     *            the new Cursor.
+     */
+    public void setCursor(Cursor cursor) {
+        toolkit.lockAWT();
+        try {
+            this.cursor = cursor;
+            setCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Set current cursor shape to Component's Cursor.
+     */
+    void setCursor() {
+        if (isDisplayable() && isShowing()) {
+            Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
+            Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
+            // ???AWT
+            /*
+             * if (absRect.contains(absPointerPos)) { // set Cursor only on
+             * top-level Windows(on X11) Window topLevelWnd =
+             * getWindowAncestor(); if (topLevelWnd != null) { Point pointerPos
+             * = MouseDispatcher.convertPoint(null, absPointerPos, topLevelWnd);
+             * Component compUnderCursor =
+             * topLevelWnd.findComponentAt(pointerPos); // if (compUnderCursor
+             * == this || // compUnderCursor.getCursorAncestor() == this) {
+             * NativeWindow wnd = topLevelWnd.getNativeWindow(); if
+             * (compUnderCursor != null && wnd != null) {
+             * compUnderCursor.getRealCursor().getNativeCursor()
+             * .setCursor(wnd.getId()); } // } } }
+             */
+        }
+    }
+
+    /**
+     * Gets the ancestor Cursor if Component is disabled (directly or via an
+     * ancestor) even if Cursor is explicitly set.
+     * 
+     * @param value
+     *            the value.
+     * @return the actual Cursor to be displayed.
+     */
+    // ???AWT
+    /*
+     * Cursor getRealCursor() { Component cursorAncestor = getCursorAncestor();
+     * return cursorAncestor != null ? cursorAncestor.getCursor() :
+     * Cursor.getDefaultCursor(); }
+     */
+
+    /**
+     * Gets the ancestor(or component itself) whose cursor is set when pointer
+     * is inside component
+     * 
+     * @return the actual Cursor to be displayed.
+     */
+    // ???AWT
+    /*
+     * Component getCursorAncestor() { Component comp; for (comp = this; comp !=
+     * null; comp = comp.getParent()) { if (comp instanceof Window ||
+     * comp.isCursorSet() && comp.isKeyEnabled()) { return comp; } } return
+     * null; } public void setDropTarget(DropTarget dt) { toolkit.lockAWT(); try
+     * { if (dropTarget == dt) { return; } DropTarget oldDropTarget =
+     * dropTarget; dropTarget = dt; if (oldDropTarget != null) { if
+     * (behaviour.isDisplayable()) { oldDropTarget.removeNotify(peer); }
+     * oldDropTarget.setComponent(null); } if (dt != null) {
+     * dt.setComponent(this); if (behaviour.isDisplayable()) {
+     * dt.addNotify(peer); } } } finally { toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Sets this component to the "enabled" or "disabled" state depending on the
+     * specified boolean parameter.
+     * 
+     * @param value
+     *            true if this component should be enabled; false if this
+     *            component should be disabled.
+     */
+    public void setEnabled(boolean value) {
+        toolkit.lockAWT();
+        try {
+            enable(value);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the enabled impl.
+     * 
+     * @param value
+     *            the new enabled impl.
+     */
+    void setEnabledImpl(boolean value) {
+        if (enabled != value) {
+            enabled = value;
+            setCursor();
+            if (!enabled) {
+                moveFocusOnHide();
+            }
+            behaviour.setEnabled(value);
+        }
+    }
+
+    // ???AWT
+    /*
+     * private void fireAccessibleStateChange(AccessibleState state, boolean
+     * value) { if (behaviour.isLightweight()) { return; } AccessibleContext ac
+     * = getAccessibleContext(); if (ac != null) { AccessibleState oldValue =
+     * null; AccessibleState newValue = null; if (value) { newValue = state; }
+     * else { oldValue = state; }
+     * ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+     * oldValue, newValue); } }
+     */
+
+    // ???AWT
+    /*
+     * public void setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke>
+     * keystrokes) { Set<? extends AWTKeyStroke> oldTraversalKeys; String
+     * propName = "FocusTraversalKeys"; //$NON-NLS-1$ toolkit.lockAWT(); try {
+     * Integer kId = new Integer(id);
+     * KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+     * Map<Integer, Set<? extends AWTKeyStroke>> keys = new HashMap<Integer,
+     * Set<? extends AWTKeyStroke>>(); for (int kid : traversalIDs) { Integer
+     * key = new Integer(kid); keys.put(key, getFocusTraversalKeys(kid)); }
+     * KeyboardFocusManager.checkKeyStrokes(traversalIDs, keys, kId,
+     * keystrokes); oldTraversalKeys = traversalKeys.get(new Integer(id)); //
+     * put a copy of keystrokes object into map: Set<? extends AWTKeyStroke>
+     * newKeys = keystrokes; if (keystrokes != null) { newKeys = new
+     * HashSet<AWTKeyStroke>(keystrokes); } traversalKeys.put(kId, newKeys);
+     * String direction = ""; //$NON-NLS-1$ switch (id) { case
+     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: direction = "forward";
+     * //$NON-NLS-1$ break; case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+     * direction = "backward"; //$NON-NLS-1$ break; case
+     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS: direction = "upCycle";
+     * //$NON-NLS-1$ break; case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+     * direction = "downCycle"; //$NON-NLS-1$ break; } propName = direction +
+     * propName; } finally { toolkit.unlockAWT(); } firePropertyChange(propName,
+     * oldTraversalKeys, keystrokes); }
+     */
+
+    /**
+     * Sets the focus traversal keys state for this component.
+     * 
+     * @param value
+     *            true if the focus traversal keys state is enabled, false if
+     *            the focus traversal keys state is disabled.
+     */
+    public void setFocusTraversalKeysEnabled(boolean value) {
+        boolean oldFocusTraversalKeysEnabled;
+        toolkit.lockAWT();
+        try {
+            oldFocusTraversalKeysEnabled = focusTraversalKeysEnabled;
+            focusTraversalKeysEnabled = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusTraversalKeysEnabled", oldFocusTraversalKeysEnabled, //$NON-NLS-1$
+                focusTraversalKeysEnabled);
+    }
+
+    // ???AWT
+    /*
+     * public void setFocusable(boolean focusable) { boolean oldFocusable;
+     * toolkit.lockAWT(); try { calledSetFocusable = true; oldFocusable =
+     * this.focusable; this.focusable = focusable; if (!focusable) {
+     * moveFocus(); } } finally { toolkit.unlockAWT(); }
+     * firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$ }
+     * public Font getFont() { toolkit.lockAWT(); try { return (font == null) &&
+     * (parent != null) ? parent.getFont() : font; } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Sets the font for this Component.
+     * 
+     * @param f
+     *            the new font of the Component.
+     */
+    public void setFont(Font f) {
+        Font oldFont;
+        toolkit.lockAWT();
+        try {
+            oldFont = font;
+            setFontImpl(f);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("font", oldFont, font); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the font impl.
+     * 
+     * @param f
+     *            the new font impl.
+     */
+    void setFontImpl(Font f) {
+        font = f;
+        invalidate();
+        if (isShowing()) {
+            repaint();
+        }
+    }
+
+    /**
+     * Invalidate the component if it inherits the font from the parent. This
+     * method is overridden in Container.
+     * 
+     * @return true if the component was invalidated, false otherwise.
+     */
+    boolean propagateFont() {
+        if (font == null) {
+            invalidate();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the foreground color for this Component.
+     * 
+     * @param c
+     *            the new foreground color.
+     */
+    public void setForeground(Color c) {
+        Color oldFgColor;
+        toolkit.lockAWT();
+        try {
+            oldFgColor = foreColor;
+            foreColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the background color for the Component.
+     * 
+     * @param c
+     *            the new background color for this component.
+     */
+    public void setBackground(Color c) {
+        Color oldBkColor;
+        toolkit.lockAWT();
+        try {
+            oldBkColor = backColor;
+            backColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the flag for whether paint messages received from the operating
+     * system should be ignored or not.
+     * 
+     * @param value
+     *            true if paint messages received from the operating system
+     *            should be ignored, false otherwise.
+     */
+    public void setIgnoreRepaint(boolean value) {
+        toolkit.lockAWT();
+        try {
+            ignoreRepaint = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locale of the component.
+     * 
+     * @param locale
+     *            the new Locale.
+     */
+    public void setLocale(Locale locale) {
+        Locale oldLocale;
+        toolkit.lockAWT();
+        try {
+            oldLocale = this.locale;
+            this.locale = locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("locale", oldLocale, locale); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the location of the Component to the specified point.
+     * 
+     * @param p
+     *            the new location of the Component.
+     */
+    public void setLocation(Point p) {
+        toolkit.lockAWT();
+        try {
+            setLocation(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the location of the Component to the specified x, y coordinates.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     */
+    public void setLocation(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            move(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the visibility state of the component.
+     * 
+     * @param b
+     *            true if the component is visible, false if the component is
+     *            not shown.
+     */
+    public void setVisible(boolean b) {
+        // show() & hide() are not deprecated for Window,
+        // so have to call them from setVisible()
+        show(b);
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show() {
+        toolkit.lockAWT();
+        try {
+            if (visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            mapToDisplay(true);
+            validate();
+            visible = true;
+            behaviour.setVisible(true);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
+            // ???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(new Rectangle(x, y, w, h));
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @param b
+     *            the visibility's state.
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show(boolean b) {
+        if (b) {
+            show();
+        } else {
+            hide();
+        }
+    }
+
+    // ???AWT
+    /*
+     * void transferFocus(int dir) { Container root = null; if (this instanceof
+     * Container) { Container cont = (Container) this; if
+     * (cont.isFocusCycleRoot()) { root = cont.getFocusTraversalRoot(); } } if
+     * (root == null) { root = getFocusCycleRootAncestor(); } // transfer focus
+     * up cycle if root is unreachable Component comp = this; while ((root !=
+     * null) && !(root.isFocusCycleRoot() && root.isShowing() &&
+     * root.isEnabled() && root .isFocusable())) { comp = root; root =
+     * root.getFocusCycleRootAncestor(); } if (root == null) { return; }
+     * FocusTraversalPolicy policy = root.getFocusTraversalPolicy(); Component
+     * nextComp = null; switch (dir) { case
+     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: nextComp =
+     * policy.getComponentAfter(root, comp); break; case
+     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS: nextComp =
+     * policy.getComponentBefore(root, comp); break; } if (nextComp != null) {
+     * nextComp.requestFocus(false); } } public void transferFocus() {
+     * toolkit.lockAWT(); try { nextFocus(); } finally { toolkit.unlockAWT(); }
+     * } public void transferFocusBackward() { toolkit.lockAWT(); try {
+     * transferFocus(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); } finally {
+     * toolkit.unlockAWT(); } } public void transferFocusUpCycle() {
+     * toolkit.lockAWT(); try { KeyboardFocusManager kfm =
+     * KeyboardFocusManager.getCurrentKeyboardFocusManager(); Container root =
+     * kfm.getCurrentFocusCycleRoot(); if(root == null) { return; } boolean
+     * success = false; Component nextComp = null; Container newRoot = root; do
+     * { nextComp = newRoot instanceof Window ?
+     * newRoot.getFocusTraversalPolicy() .getDefaultComponent(newRoot) :
+     * newRoot; newRoot = newRoot.getFocusCycleRootAncestor(); if (nextComp ==
+     * null) { break; } success = nextComp.requestFocusInWindow(); if (newRoot
+     * == null) { break; } kfm.setGlobalCurrentFocusCycleRoot(newRoot); } while
+     * (!success); if (!success && root != newRoot) {
+     * kfm.setGlobalCurrentFocusCycleRoot(root); } } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Validates that this component has a valid layout.
+     */
+    public void validate() {
+        toolkit.lockAWT();
+        try {
+            if (!behaviour.isDisplayable()) {
+                return;
+            }
+            validateImpl();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Validate impl.
+     */
+    void validateImpl() {
+        valid = true;
+    }
+
+    /**
+     * Gets the native window.
+     * 
+     * @return the native window.
+     */
+    NativeWindow getNativeWindow() {
+        return behaviour.getNativeWindow();
+    }
+
+    /**
+     * Checks whether or not a maximum size is set for the Component.
+     * 
+     * @return true, if the maximum size is set for the Component, false
+     *         otherwise.
+     */
+    public boolean isMaximumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return maximumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the minimum size is set for the component.
+     * 
+     * @return true, if the minimum size is set for the component, false
+     *         otherwise.
+     */
+    public boolean isMinimumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the preferred size is set for the Component.
+     * 
+     * @return true, if the preferred size is set for the Component, false
+     *         otherwise.
+     */
+    public boolean isPreferredSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the maximum size of the Component.
+     * 
+     * @return the maximum size of the Component.
+     */
+    public Dimension getMaximumSize() {
+        toolkit.lockAWT();
+        try {
+            return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(Short.MAX_VALUE,
+                    Short.MAX_VALUE);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the minimum size of the Component.
+     * 
+     * @return the minimum size of the Component.
+     */
+    public Dimension getMinimumSize() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @return the Dimension.
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public Dimension minimumSize() {
+        toolkit.lockAWT();
+        try {
+            if (isMinimumSizeSet()) {
+                return (Dimension)minimumSize.clone();
+            }
+            Dimension defSize = getDefaultMinimumSize();
+            if (defSize != null) {
+                return (Dimension)defSize.clone();
+            }
+            return isDisplayable() ? new Dimension(1, 1) : new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the preferred size of the Component.
+     * 
+     * @return the preferred size of the Component.
+     */
+    public Dimension getPreferredSize() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getPreferredSize() method.
+     * 
+     * @return the Dimension.
+     * @deprecated Replaced by getPreferredSize() method.
+     */
+    @Deprecated
+    public Dimension preferredSize() {
+        toolkit.lockAWT();
+        try {
+            if (isPreferredSizeSet()) {
+                return new Dimension(preferredSize);
+            }
+            Dimension defSize = getDefaultPreferredSize();
+            if (defSize != null) {
+                return new Dimension(defSize);
+            }
+            return new Dimension(getMinimumSize());
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the maximum size of the Component.
+     * 
+     * @param maximumSize
+     *            the new maximum size of the Component.
+     */
+    public void setMaximumSize(Dimension maximumSize) {
+        Dimension oldMaximumSize;
+        toolkit.lockAWT();
+        try {
+            oldMaximumSize = this.maximumSize;
+            if (oldMaximumSize != null) {
+                oldMaximumSize = oldMaximumSize.getSize();
+            }
+            if (this.maximumSize == null) {
+                if (maximumSize != null) {
+                    this.maximumSize = new Dimension(maximumSize);
+                }
+            } else {
+                if (maximumSize != null) {
+                    this.maximumSize.setSize(maximumSize);
+                } else {
+                    this.maximumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the minimum size of the Component.
+     * 
+     * @param minimumSize
+     *            the new minimum size of the Component.
+     */
+    public void setMinimumSize(Dimension minimumSize) {
+        Dimension oldMinimumSize;
+        toolkit.lockAWT();
+        try {
+            oldMinimumSize = this.minimumSize;
+            if (oldMinimumSize != null) {
+                oldMinimumSize = oldMinimumSize.getSize();
+            }
+            if (this.minimumSize == null) {
+                if (minimumSize != null) {
+                    this.minimumSize = new Dimension(minimumSize);
+                }
+            } else {
+                if (minimumSize != null) {
+                    this.minimumSize.setSize(minimumSize);
+                } else {
+                    this.minimumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the preferred size of the Component.
+     * 
+     * @param preferredSize
+     *            the new preferred size of the Component.
+     */
+    public void setPreferredSize(Dimension preferredSize) {
+        Dimension oldPreferredSize;
+        toolkit.lockAWT();
+        try {
+            oldPreferredSize = this.preferredSize;
+            if (oldPreferredSize != null) {
+                oldPreferredSize = oldPreferredSize.getSize();
+            }
+            if (this.preferredSize == null) {
+                if (preferredSize != null) {
+                    this.preferredSize = new Dimension(preferredSize);
+                }
+            } else {
+                if (preferredSize != null) {
+                    this.preferredSize.setSize(preferredSize);
+                } else {
+                    this.preferredSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            // ???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * RedrawManager getRedrawManager() { if (parent == null) { return null; }
+     * return parent.getRedrawManager(); }
+     */
+
+    /**
+     * Checks if is focusability explicitly set.
+     * 
+     * @return true if component has a focusable peer.
+     */
+    // ???AWT
+    /*
+     * boolean isPeerFocusable() { // The recommendations for Windows and Unix
+     * are that // Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows,
+     * // and lightweight Components have non-focusable peers, // and all other
+     * Components have focusable peers. if (this instanceof Canvas || this
+     * instanceof Label || this instanceof Panel || this instanceof Scrollbar ||
+     * this instanceof ScrollPane || this instanceof Window || isLightweight())
+     * { return false; } return true; }
+     */
+
+    /**
+     * @return true if focusability was explicitly set via a call to
+     *         setFocusable() or via overriding isFocusable() or
+     *         isFocusTraversable().
+     */
+    boolean isFocusabilityExplicitlySet() {
+        return calledSetFocusable || overridenIsFocusable;
+    }
+
+    /**
+     * Paints the component and all of its subcomponents.
+     * 
+     * @param g
+     *            the Graphics to be used for painting.
+     */
+    public void paintAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Updates this Component.
+     * 
+     * @param g
+     *            the Graphics to be used for updating.
+     */
+    public void update(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            if (!isLightweight() && !isPrepainter()) {
+                g.setColor(getBackground());
+                g.fillRect(0, 0, w, h);
+                g.setColor(getForeground());
+            }
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Paints this component.
+     * 
+     * @param g
+     *            the Graphics to be used for painting.
+     */
+    public void paint(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            // Just to nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares the component to be painted.
+     * 
+     * @param g
+     *            the Graphics to be used for painting.
+     */
+    void prepaint(Graphics g) {
+        // Just to nothing. For overriding.
+    }
+
+    /**
+     * Checks if is prepainter.
+     * 
+     * @return true, if is prepainter.
+     */
+    boolean isPrepainter() {
+        return false;
+    }
+
+    /**
+     * Prepare4 hierarchy change.
+     */
+    void prepare4HierarchyChange() {
+        if (hierarchyChangingCounter++ == 0) {
+            wasShowing = isShowing();
+            wasDisplayable = isDisplayable();
+            prepareChildren4HierarchyChange();
+        }
+    }
+
+    /**
+     * Prepare children4 hierarchy change.
+     */
+    void prepareChildren4HierarchyChange() {
+        // To be inherited by Container
+    }
+
+    // ???AWT
+    /*
+     * void finishHierarchyChange(Component changed, Container changedParent,
+     * int ancestorFlags) { if (--hierarchyChangingCounter == 0) { int
+     * changeFlags = ancestorFlags; if (wasShowing != isShowing()) { changeFlags
+     * |= HierarchyEvent.SHOWING_CHANGED; } if (wasDisplayable !=
+     * isDisplayable()) { changeFlags |= HierarchyEvent.DISPLAYABILITY_CHANGED;
+     * } if (changeFlags > 0) { postEvent(new HierarchyEvent(this,
+     * HierarchyEvent.HIERARCHY_CHANGED, changed, changedParent, changeFlags));
+     * } finishChildrenHierarchyChange(changed, changedParent, ancestorFlags); }
+     * } void finishChildrenHierarchyChange(Component changed, Container
+     * changedParent, int ancestorFlags) { // To be inherited by Container }
+     * void postHierarchyBoundsEvents(Component changed, int id) { postEvent(new
+     * HierarchyEvent(this, id, changed, null, 0)); }
+     */
+
+    /**
+     * Spread hierarchy bounds events.
+     * 
+     * @param changed
+     *            the changed.
+     * @param id
+     *            the id.
+     */
+    void spreadHierarchyBoundsEvents(Component changed, int id) {
+        // To be inherited by Container
+    }
+
+    /**
+     * Dispatches an event to this component.
+     * 
+     * @param e
+     *            the Event.
+     */
+    public final void dispatchEvent(AWTEvent e) {
+        // ???AWT
+        /*
+         * if (e.isConsumed()) { return; } if (e instanceof PaintEvent) {
+         * toolkit.dispatchAWTEvent(e); processPaintEvent((PaintEvent) e);
+         * return; } KeyboardFocusManager kfm =
+         * KeyboardFocusManager.getCurrentKeyboardFocusManager(); if
+         * (!e.dispatchedByKFM && kfm.dispatchEvent(e)) { return; } if (e
+         * instanceof KeyEvent) { KeyEvent ke = (KeyEvent) e; // consumes
+         * KeyEvent which represents a focus traversal key if
+         * (getFocusTraversalKeysEnabled()) { kfm.processKeyEvent(this, ke); if
+         * (ke.isConsumed()) { return; } } } if (inputMethodsEnabled &&
+         * dispatchToIM && e.isPosted && dispatchEventToIM(e)) { return; } if
+         * (e.getID() == WindowEvent.WINDOW_ICONIFIED) {
+         * notifyInputMethod(null); } AWTEvent.EventDescriptor descriptor =
+         * toolkit.eventTypeLookup.getEventDescriptor(e);
+         * toolkit.dispatchAWTEvent(e); if (descriptor != null) { if
+         * (isEventEnabled(descriptor.eventMask) ||
+         * (getListeners(descriptor.listenerType).length > 0)) {
+         * processEvent(e); } // input events can be consumed by user listeners:
+         * if (!e.isConsumed() && ((enabledAWTEvents & descriptor.eventMask) !=
+         * 0)) { postprocessEvent(e, descriptor.eventMask); } }
+         * postDeprecatedEvent(e);
+         */
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param e
+     *            the e.
+     */
+    private void postDeprecatedEvent(AWTEvent e) {
+        if (deprecatedEventHandler) {
+            Event evt = e.getEvent();
+            if (evt != null) {
+                postEvent(evt);
+            }
+        }
+    }
+
+    /**
+     * Postprocess event.
+     * 
+     * @param e
+     *            the e.
+     * @param eventMask
+     *            the event mask.
+     */
+    void postprocessEvent(AWTEvent e, long eventMask) {
+        toolkit.lockAWT();
+        try {
+            // call system listeners under AWT lock
+            if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+                preprocessFocusEvent((FocusEvent)e);
+            } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+                preprocessKeyEvent((KeyEvent)e);
+            } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+                preprocessMouseEvent((MouseEvent)e);
+            } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+                preprocessMouseMotionEvent((MouseEvent)e);
+            } else if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+                preprocessComponentEvent((ComponentEvent)e);
+            } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+                preprocessMouseWheelEvent((MouseWheelEvent)e);
+            } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+                preprocessInputMethodEvent((InputMethodEvent)e);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Preprocess input method event.
+     * 
+     * @param e
+     *            the e.
+     */
+    private void preprocessInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse wheel event.
+     * 
+     * @param e
+     *            the e.
+     */
+    private void preprocessMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getSystemListeners());
+    }
+
+    /**
+     * Process mouse wheel event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processMouseWheelEventImpl(MouseWheelEvent e, Collection<MouseWheelListener> c) {
+        for (MouseWheelListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_WHEEL:
+                    listener.mouseWheelMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Preprocess component event.
+     * 
+     * @param e
+     *            the e.
+     */
+    private void preprocessComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse motion event.
+     * 
+     * @param e
+     *            the e.
+     */
+    void preprocessMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse event.
+     * 
+     * @param e
+     *            the e
+     */
+    void preprocessMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess key event.
+     * 
+     * @param e
+     *            the e.
+     */
+    void preprocessKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess focus event.
+     * 
+     * @param e
+     *            the e.
+     */
+    void preprocessFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getSystemListeners());
+    }
+
+    /**
+     * Processes AWTEvent occurred on this component.
+     * 
+     * @param e
+     *            the AWTEvent.
+     */
+    protected void processEvent(AWTEvent e) {
+        long eventMask = toolkit.eventTypeLookup.getEventMask(e);
+        if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+            processComponentEvent((ComponentEvent)e);
+        } else if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+            processFocusEvent((FocusEvent)e);
+        } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+            processKeyEvent((KeyEvent)e);
+        } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+            processMouseEvent((MouseEvent)e);
+        } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+            processMouseWheelEvent((MouseWheelEvent)e);
+        } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+            processMouseMotionEvent((MouseEvent)e);
+        } else if (eventMask == AWTEvent.HIERARCHY_EVENT_MASK) {
+            processHierarchyEvent((HierarchyEvent)e);
+        } else if (eventMask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
+            processHierarchyBoundsEvent((HierarchyEvent)e);
+        } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+            processInputMethodEvent((InputMethodEvent)e);
+        }
+    }
+
+    /**
+     * Gets an array of all listener's objects based on the specified listener
+     * type and registered to this Component.
+     * 
+     * @param listenerType
+     *            the listener type.
+     * @return an array of all listener's objects based on the specified
+     *         listener type and registered to this Component.
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
+        if (ComponentListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getComponentListeners();
+        } else if (FocusListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getFocusListeners();
+        } else if (HierarchyBoundsListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getHierarchyBoundsListeners();
+        } else if (HierarchyListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getHierarchyListeners();
+        } else if (InputMethodListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getInputMethodListeners();
+        } else if (KeyListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getKeyListeners();
+        } else if (MouseWheelListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getMouseWheelListeners();
+        } else if (MouseMotionListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getMouseMotionListeners();
+        } else if (MouseListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getMouseListeners();
+        } else if (PropertyChangeListener.class.isAssignableFrom(listenerType)) {
+            return (T[])getPropertyChangeListeners();
+        }
+        return (T[])Array.newInstance(listenerType, 0);
+    }
+
+    /**
+     * Process paint event.
+     * 
+     * @param event
+     *            the event.
+     */
+    private void processPaintEvent(PaintEvent event) {
+        if (redrawManager == null) {
+            return;
+        }
+        Rectangle clipRect = event.getUpdateRect();
+        if ((clipRect.width <= 0) || (clipRect.height <= 0)) {
+            return;
+        }
+        Graphics g = getGraphics();
+        if (g == null) {
+            return;
+        }
+        initGraphics(g, event);
+        if (!getIgnoreRepaint()) {
+            if (event.getID() == PaintEvent.PAINT) {
+                paint(g);
+            } else {
+                update(g);
+            }
+        }
+        g.dispose();
+    }
+
+    /**
+     * Inits the graphics.
+     * 
+     * @param g
+     *            the g.
+     * @param e
+     *            the e.
+     */
+    void initGraphics(Graphics g, PaintEvent e) {
+        Rectangle clip = e.getUpdateRect();
+        if (clip instanceof ClipRegion) {
+            g.setClip(((ClipRegion)clip).getClip());
+        } else {
+            g.setClip(clip);
+        }
+        if (isPrepainter()) {
+            prepaint(g);
+        } else if (!isLightweight() && (e.getID() == PaintEvent.PAINT)) {
+            g.setColor(getBackground());
+            g.fillRect(0, 0, w, h);
+        }
+        g.setFont(getFont());
+        g.setColor(getForeground());
+    }
+
+    /**
+     * Enables the events with the specified event mask to be delivered to this
+     * component.
+     * 
+     * @param eventsToEnable
+     *            the events mask which specifies the types of events to enable.
+     */
+    protected final void enableEvents(long eventsToEnable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents |= eventsToEnable;
+            deprecatedEventHandler = false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Enable awt events.
+     * 
+     * @param eventsToEnable
+     *            the events to enable.
+     */
+    private void enableAWTEvents(long eventsToEnable) {
+        enabledAWTEvents |= eventsToEnable;
+    }
+
+    /**
+     * Disables the events with types specified by the specified event mask from
+     * being delivered to this component.
+     * 
+     * @param eventsToDisable
+     *            the event mask specifying the event types.
+     */
+    protected final void disableEvents(long eventsToDisable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents &= ~eventsToDisable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /*
+     * For use in MouseDispatcher only. Really it checks not only mouse events.
+     */
+    /**
+     * Checks if is mouse event enabled.
+     * 
+     * @param eventMask
+     *            the event mask.
+     * @return true, if is mouse event enabled.
+     */
+    boolean isMouseEventEnabled(long eventMask) {
+        return (isEventEnabled(eventMask) || (enabledAWTEvents & eventMask) != 0);
+    }
+
+    /**
+     * Checks if is event enabled.
+     * 
+     * @param eventMask
+     *            the event mask.
+     * @return true, if is event enabled.
+     */
+    boolean isEventEnabled(long eventMask) {
+        return ((enabledEvents & eventMask) != 0);
+    }
+
+    /**
+     * Enables or disables input method support for this component.
+     * 
+     * @param enable
+     *            true to enable input method support, false to disable it.
+     */
+    public void enableInputMethods(boolean enable) {
+        toolkit.lockAWT();
+        try {
+            if (!enable) {
+                removeNotifyInputContext();
+            }
+            inputMethodsEnabled = enable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of all component's listeners registered for this component.
+     * 
+     * @return an array of all component's listeners registered for this
+     *         component.
+     */
+    public ComponentListener[] getComponentListeners() {
+        return componentListeners.getUserListeners(new ComponentListener[0]);
+    }
+
+    /**
+     * Adds the specified component listener to the Component for receiving
+     * component's event.
+     * 
+     * @param l
+     *            the ComponentListener.
+     */
+    public void addComponentListener(ComponentListener l) {
+        componentListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the component listener registered for this Component.
+     * 
+     * @param l
+     *            the ComponentListener.
+     */
+    public void removeComponentListener(ComponentListener l) {
+        componentListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a component event that has occurred on this component by
+     * dispatching them to any registered ComponentListener objects.
+     * 
+     * @param e
+     *            the ComponentEvent.
+     */
+    protected void processComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getUserListeners());
+    }
+
+    /**
+     * Process component event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processComponentEventImpl(ComponentEvent e, Collection<ComponentListener> c) {
+        for (ComponentListener listener : c) {
+            switch (e.getID()) {
+                case ComponentEvent.COMPONENT_HIDDEN:
+                    listener.componentHidden(e);
+                    break;
+                case ComponentEvent.COMPONENT_MOVED:
+                    listener.componentMoved(e);
+                    break;
+                case ComponentEvent.COMPONENT_RESIZED:
+                    listener.componentResized(e);
+                    break;
+                case ComponentEvent.COMPONENT_SHOWN:
+                    listener.componentShown(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of focus listeners registered for this Component.
+     * 
+     * @return the array of focus listeners registered for this Component.
+     */
+    public FocusListener[] getFocusListeners() {
+        return focusListeners.getUserListeners(new FocusListener[0]);
+    }
+
+    /**
+     * Adds the specified focus listener to the Component for receiving focus
+     * events.
+     * 
+     * @param l
+     *            the FocusListener.
+     */
+    public void addFocusListener(FocusListener l) {
+        focusListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt focus listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTFocusListener(FocusListener l) {
+        enableAWTEvents(AWTEvent.FOCUS_EVENT_MASK);
+        focusListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the focus listener registered for this Component.
+     * 
+     * @param l
+     *            the FocusListener.
+     */
+    public void removeFocusListener(FocusListener l) {
+        focusListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a FocusEvent that has occurred on this component by dispatching
+     * it to the registered listeners.
+     * 
+     * @param e
+     *            the FocusEvent.
+     */
+    protected void processFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getUserListeners());
+    }
+
+    /**
+     * Process focus event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processFocusEventImpl(FocusEvent e, Collection<FocusListener> c) {
+        for (FocusListener listener : c) {
+            switch (e.getID()) {
+                case FocusEvent.FOCUS_GAINED:
+                    listener.focusGained(e);
+                    break;
+                case FocusEvent.FOCUS_LOST:
+                    listener.focusLost(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of registered HierarchyListeners for this Component.
+     * 
+     * @return an array of registered HierarchyListeners for this Component.
+     */
+    public HierarchyListener[] getHierarchyListeners() {
+        return hierarchyListeners.getUserListeners(new HierarchyListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy listener.
+     * 
+     * @param l
+     *            the HierarchyListener.
+     */
+    public void addHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy listener registered for this component.
+     * 
+     * @param l
+     *            the HierarchyListener.
+     */
+    public void removeHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the HierarchyEvent.
+     */
+    protected void processHierarchyEvent(HierarchyEvent e) {
+        for (HierarchyListener listener : hierarchyListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.HIERARCHY_CHANGED:
+                    listener.hierarchyChanged(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of HierarchyBoundsListener objects registered to this
+     * Component.
+     * 
+     * @return an array of HierarchyBoundsListener objects.
+     */
+    public HierarchyBoundsListener[] getHierarchyBoundsListeners() {
+        return hierarchyBoundsListeners.getUserListeners(new HierarchyBoundsListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy bounds listener.
+     * 
+     * @param l
+     *            the HierarchyBoundsListener.
+     */
+    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy bounds listener registered for this Component.
+     * 
+     * @param l
+     *            the HierarchyBoundsListener.
+     */
+    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy bounds event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the HierarchyBoundsEvent.
+     */
+    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
+        for (HierarchyBoundsListener listener : hierarchyBoundsListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.ANCESTOR_MOVED:
+                    listener.ancestorMoved(e);
+                    break;
+                case HierarchyEvent.ANCESTOR_RESIZED:
+                    listener.ancestorResized(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the key listeners registered to the Component.
+     * 
+     * @return an array of the key listeners registered to the Component.
+     */
+    public KeyListener[] getKeyListeners() {
+        return keyListeners.getUserListeners(new KeyListener[0]);
+    }
+
+    /**
+     * Adds the specified key listener.
+     * 
+     * @param l
+     *            the KeyListener.
+     */
+    public void addKeyListener(KeyListener l) {
+        keyListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt key listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTKeyListener(KeyListener l) {
+        enableAWTEvents(AWTEvent.KEY_EVENT_MASK);
+        keyListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the key listener registered for this Component.
+     * 
+     * @param l
+     *            the KeyListener.
+     */
+    public void removeKeyListener(KeyListener l) {
+        keyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a key event that has occurred on this component by dispatching
+     * it to the registered listeners.
+     * 
+     * @param e
+     *            the KeyEvent.
+     */
+    protected void processKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getUserListeners());
+    }
+
+    /**
+     * Process key event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processKeyEventImpl(KeyEvent e, Collection<KeyListener> c) {
+        for (KeyListener listener : c) {
+            switch (e.getID()) {
+                case KeyEvent.KEY_PRESSED:
+                    listener.keyPressed(e);
+                    break;
+                case KeyEvent.KEY_RELEASED:
+                    listener.keyReleased(e);
+                    break;
+                case KeyEvent.KEY_TYPED:
+                    listener.keyTyped(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse listeners registered to the Component.
+     * 
+     * @return an array of the mouse listeners registered to the Component.
+     */
+    public MouseListener[] getMouseListeners() {
+        return mouseListeners.getUserListeners(new MouseListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse listener.
+     * 
+     * @param l
+     *            the MouseListener.
+     */
+    public void addMouseListener(MouseListener l) {
+        mouseListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt mouse listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTMouseListener(MouseListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_EVENT_MASK);
+        mouseListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse motion listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTMouseMotionListener(MouseMotionListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+        mouseMotionListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt component listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTComponentListener(ComponentListener l) {
+        enableAWTEvents(AWTEvent.COMPONENT_EVENT_MASK);
+        componentListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt input method listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTInputMethodListener(InputMethodListener l) {
+        enableAWTEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+        inputMethodListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse wheel listener.
+     * 
+     * @param l
+     *            the l.
+     */
+    void addAWTMouseWheelListener(MouseWheelListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+        mouseWheelListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the mouse listener registered for this Component.
+     * 
+     * @param l
+     *            the MouseListener.
+     */
+    public void removeMouseListener(MouseListener l) {
+        mouseListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the MouseEvent.
+     */
+    protected void processMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getUserListeners());
+    }
+
+    /**
+     * Process mouse event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processMouseEventImpl(MouseEvent e, Collection<MouseListener> c) {
+        for (MouseListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_CLICKED:
+                    listener.mouseClicked(e);
+                    break;
+                case MouseEvent.MOUSE_ENTERED:
+                    listener.mouseEntered(e);
+                    break;
+                case MouseEvent.MOUSE_EXITED:
+                    listener.mouseExited(e);
+                    break;
+                case MouseEvent.MOUSE_PRESSED:
+                    listener.mousePressed(e);
+                    break;
+                case MouseEvent.MOUSE_RELEASED:
+                    listener.mouseReleased(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Process mouse motion event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processMouseMotionEventImpl(MouseEvent e, Collection<MouseMotionListener> c) {
+        for (MouseMotionListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_DRAGGED:
+                    listener.mouseDragged(e);
+                    break;
+                case MouseEvent.MOUSE_MOVED:
+                    listener.mouseMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse motion listeners registered to the Component.
+     * 
+     * @return an array of the MouseMotionListeners registered to the Component.
+     */
+    public MouseMotionListener[] getMouseMotionListeners() {
+        return mouseMotionListeners.getUserListeners(new MouseMotionListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse motion listener.
+     * 
+     * @param l
+     *            the MouseMotionListener.
+     */
+    public void addMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse motion listener registered for this component.
+     * 
+     * @param l
+     *            the MouseMotionListener.
+     */
+    public void removeMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse motion event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the MouseEvent.
+     */
+    protected void processMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the mouse wheel listeners registered to the Component.
+     * 
+     * @return an array of the MouseWheelListeners registered to the Component.
+     */
+    public MouseWheelListener[] getMouseWheelListeners() {
+        return mouseWheelListeners.getUserListeners(new MouseWheelListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse wheel listener.
+     * 
+     * @param l
+     *            the MouseWheelListener.
+     */
+    public void addMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse wheel listener registered for this component.
+     * 
+     * @param l
+     *            the MouseWheelListener.
+     */
+    public void removeMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse wheel event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the MouseWheelEvent.
+     */
+    protected void processMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the InputMethodListener listeners registered to the
+     * Component.
+     * 
+     * @return an array of the InputMethodListener listeners registered to the
+     *         Component.
+     */
+    public InputMethodListener[] getInputMethodListeners() {
+        return inputMethodListeners.getUserListeners(new InputMethodListener[0]);
+    }
+
+    /**
+     * Adds the specified input method listener.
+     * 
+     * @param l
+     *            the InputMethodListener.
+     */
+    public void addInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the input method listener registered for this component.
+     * 
+     * @param l
+     *            the InputMethodListener.
+     */
+    public void removeInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes an input method event that has occurred on this component by
+     * dispatching it to the registered listeners.
+     * 
+     * @param e
+     *            the InputMethodEvent.
+     */
+    protected void processInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getUserListeners());
+    }
+
+    /**
+     * Process input method event impl.
+     * 
+     * @param e
+     *            the e.
+     * @param c
+     *            the c.
+     */
+    private void processInputMethodEventImpl(InputMethodEvent e, Collection<InputMethodListener> c) {
+        for (InputMethodListener listener : c) {
+            switch (e.getID()) {
+                case InputMethodEvent.CARET_POSITION_CHANGED:
+                    listener.caretPositionChanged(e);
+                    break;
+                case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+                    listener.inputMethodTextChanged(e);
+                    break;
+            }
+        }
+    }
+
+    // ???AWT
+    /*
+     * public Point getMousePosition() throws HeadlessException { Point
+     * absPointerPos = MouseInfo.getPointerInfo().getLocation(); Window
+     * winUnderPtr =
+     * toolkit.dispatcher.mouseDispatcher.findWindowAt(absPointerPos); Point
+     * pointerPos = MouseDispatcher.convertPoint(null, absPointerPos,
+     * winUnderPtr); boolean isUnderPointer = false; if (winUnderPtr == null) {
+     * return null; } isUnderPointer = winUnderPtr.isComponentAt(this,
+     * pointerPos); if (isUnderPointer) { return
+     * MouseDispatcher.convertPoint(null, absPointerPos, this); } return null; }
+     */
+
+    /**
+     * Set native caret at the given position <br>
+     * Note: this method takes AWT lock inside because it walks through the
+     * component hierarchy.
+     * 
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     */
+    void setCaretPos(final int x, final int y) {
+        Runnable r = new Runnable() {
+            public void run() {
+                toolkit.lockAWT();
+                try {
+                    setCaretPosImpl(x, y);
+                } finally {
+                    toolkit.unlockAWT();
+                }
+            }
+        };
+        if (Thread.currentThread() instanceof EventDispatchThread) {
+            r.run();
+        } else {
+            toolkit.getSystemEventQueueImpl().postEvent(new InvocationEvent(this, r));
+        }
+    }
+
+    /**
+     * This method should be called only at event dispatch thread.
+     * 
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     */
+    void setCaretPosImpl(int x, int y) {
+        Component c = this;
+        while ((c != null) && c.behaviour.isLightweight()) {
+            x += c.x;
+            y += c.y;
+            // ???AWT: c = c.getParent();
+        }
+        if (c == null) {
+            return;
+        }
+        // ???AWT
+        /*
+         * if (c instanceof Window) { Insets insets = c.getNativeInsets(); x -=
+         * insets.left; y -= insets.top; }
+         * toolkit.getWindowFactory().setCaretPosition(x, y);
+         */
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default minimum size.
+     * 
+     * @return the default minimum size.
+     */
+    Dimension getDefaultMinimumSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default preferred size.
+     * 
+     * @return the default preferred size.
+     */
+    Dimension getDefaultPreferredSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Reset default size.
+     */
+    void resetDefaultSize() {
+    }
+
+    // ???AWT
+    /*
+     * ComponentBehavior createBehavior() { return new LWBehavior(this); }
+     */
+
+    /**
+     * Gets the default background.
+     * 
+     * @return the default background.
+     */
+    Color getDefaultBackground() {
+        // ???AWT: return getWindowAncestor().getDefaultBackground();
+        return getBackground();
+    }
+
+    /**
+     * Gets the default foreground.
+     * 
+     * @return the default foreground.
+     */
+    Color getDefaultForeground() {
+        // ???AWT return getWindowAncestor().getDefaultForeground();
+        return getForeground();
+    }
+
+    /**
+     * Called when native resource for this component is created (for
+     * heavyweights only).
+     * 
+     * @param win
+     *            the win.
+     */
+    void nativeWindowCreated(NativeWindow win) {
+        // to be overridden
+    }
+
+    /**
+     * Determine the component's area hidden behind the windows that have higher
+     * Z-order, including windows of other applications.
+     * 
+     * @param image
+     *            the image.
+     * @param destLocation
+     *            the dest location.
+     * @param destSize
+     *            the dest size.
+     * @param source
+     *            the source.
+     * @return the calculated region, or null if it cannot be determined.
+     */
+    // ???AWT
+    /*
+     * MultiRectArea getObscuredRegion(Rectangle part) { if (!visible || parent
+     * == null || !parent.visible) { return null; } Rectangle r = new
+     * Rectangle(0, 0, w, h); if (part != null) { r = r.intersection(part); } if
+     * (r.isEmpty()) { return null; } r.translate(x, y); MultiRectArea ret =
+     * parent.getObscuredRegion(r); if (ret != null) {
+     * parent.addObscuredRegions(ret, this); ret.translate(-x, -y);
+     * ret.intersect(new Rectangle(0, 0, w, h)); } return ret; }
+     */
+
+    // ???AWT
+    /*
+     * private void readObject(ObjectInputStream stream) throws IOException,
+     * ClassNotFoundException { stream.defaultReadObject(); FieldsAccessor
+     * accessor = new FieldsAccessor(Component.class, this);
+     * accessor.set("toolkit", Toolkit.getDefaultToolkit()); //$NON-NLS-1$
+     * accessor.set("behaviour", createBehavior()); //$NON-NLS-1$
+     * accessor.set("componentLock", new Object()); // $NON-LOCK-1$
+     * //$NON-NLS-1$ }
+     */
+
+    final void onDrawImage(Image image, Point destLocation, Dimension destSize, Rectangle source) {
+        ImageParameters imageParams;
+        if (updatedImages == null) {
+            updatedImages = new HashMap<Image, ImageParameters>();
+        }
+        imageParams = updatedImages.get(image);
+        if (imageParams == null) {
+            imageParams = new ImageParameters();
+            updatedImages.put(image, imageParams);
+        }
+        imageParams.addDrawing(destLocation, destSize, source);
+    }
+
+    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            boolean done = false;
+            if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
+                done = true;
+            } else if ((infoflags & SOMEBITS) != 0 && incrementalImageUpdate) {
+                done = true;
+            }
+            if (done) {
+                repaint();
+            }
+            return (infoflags & (ABORT | ALLBITS)) == 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * private void invalidateRealParent() { Container realParent =
+     * getRealParent(); if ((realParent != null) && realParent.isValid()) {
+     * realParent.invalidate(); } }
+     */
+
+    /**
+     * The Class ImageParameters.
+     */
+    private class ImageParameters {
+
+        /**
+         * The drawing params.
+         */
+        private final LinkedList<DrawingParameters> drawingParams = new LinkedList<DrawingParameters>();
+
+        /**
+         * The size.
+         */
+        Dimension size = new Dimension(Component.this.w, Component.this.h);
+
+        /**
+         * Adds the drawing.
+         * 
+         * @param destLocation
+         *            the dest location.
+         * @param destSize
+         *            the dest size.
+         * @param source
+         *            the source.
+         */
+        void addDrawing(Point destLocation, Dimension destSize, Rectangle source) {
+            drawingParams.add(new DrawingParameters(destLocation, destSize, source));
+        }
+
+        /**
+         * Drawing parameters iterator.
+         * 
+         * @return the iterator< drawing parameters>.
+         */
+        Iterator<DrawingParameters> drawingParametersIterator() {
+            return drawingParams.iterator();
+        }
+
+        /**
+         * The Class DrawingParameters.
+         */
+        class DrawingParameters {
+
+            /**
+             * The dest location.
+             */
+            Point destLocation;
+
+            /**
+             * The dest size.
+             */
+            Dimension destSize;
+
+            /**
+             * The source.
+             */
+            Rectangle source;
+
+            /**
+             * Instantiates a new drawing parameters.
+             * 
+             * @param destLocation
+             *            the dest location.
+             * @param destSize
+             *            the dest size.
+             * @param source
+             *            the source.
+             */
+            DrawingParameters(Point destLocation, Dimension destSize, Rectangle source) {
+                this.destLocation = new Point(destLocation);
+                if (destSize != null) {
+                    this.destSize = new Dimension(destSize);
+                } else {
+                    this.destSize = null;
+                }
+                if (source != null) {
+                    this.source = new Rectangle(source);
+                } else {
+                    this.source = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * TextComponent support.
+     * 
+     * @param e
+     *            the e.
+     * @return true, if dispatch event to im.
+     */
+    // ???AWT
+    /*
+     * private TextKit textKit = null; TextKit getTextKit() { return textKit; }
+     * void setTextKit(TextKit kit) { textKit = kit; }
+     */
+
+    /**
+     * TextField support.
+     */
+    // ???AWT
+    /*
+     * private TextFieldKit textFieldKit = null; TextFieldKit getTextFieldKit()
+     * { return textFieldKit; } void setTextFieldKit(TextFieldKit kit) {
+     * textFieldKit = kit; }
+     */
+
+    /**
+     * Dispatches input & focus events to input method context.
+     * 
+     * @param e
+     *            event to pass to InputContext.dispatchEvent().
+     * @return true if event was consumed by IM, false otherwise.
+     */
+    private boolean dispatchEventToIM(AWTEvent e) {
+        InputContext ic = getInputContext();
+        if (ic == null) {
+            return false;
+        }
+        int id = e.getID();
+        boolean isInputEvent = ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST))
+                || ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST));
+        if (((id >= FocusEvent.FOCUS_FIRST) && (id <= FocusEvent.FOCUS_LAST)) || isInputEvent) {
+            ic.dispatchEvent(e);
+        }
+        return e.isConsumed();
+    }
+}
diff --git a/awt/java/awt/ComponentBehavior.java b/awt/java/awt/ComponentBehavior.java
new file mode 100644
index 0000000..f4e8ffb
--- /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..5acc11a
--- /dev/null
+++ b/awt/java/awt/ComponentOrientation.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 Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * The ComponentOrientation class specifies the language-sensitive orientation
+ * of component's elements or text. It is used to reflect the differences in
+ * this ordering between different writing systems. The ComponentOrientation
+ * class indicates the orientation of the elements/text in the horizontal
+ * direction ("left to right" or "right to left") and in the vertical direction
+ * ("top to bottom" or "bottom to top").
+ * 
+ * @since Android 1.0
+ */
+public final class ComponentOrientation implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -4113291392143563828L;
+
+    /**
+     * The Constant LEFT_TO_RIGHT indicates that items run left to right.
+     */
+    public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
+
+    /**
+     * The Constant RIGHT_TO_LEFT indicates that items run right to left.
+     */
+    public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
+
+    /**
+     * The Constant UNKNOWN indicates that a component's orientation is not set.
+     */
+    public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
+
+    /**
+     * The Constant rlLangs.
+     */
+    private static final Set<String> rlLangs = new HashSet<String>(); // RIGHT_TO_LEFT
+
+    // languages
+
+    /**
+     * The horizontal.
+     */
+    private final boolean horizontal;
+
+    /**
+     * The left2right.
+     */
+    private final boolean left2right;
+
+    static {
+        rlLangs.add("ar"); //$NON-NLS-1$
+        rlLangs.add("fa"); //$NON-NLS-1$
+        rlLangs.add("iw"); //$NON-NLS-1$
+        rlLangs.add("ur"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the orientation for the given ResourceBundle's localization.
+     * 
+     * @param bdl
+     *            the ResourceBundle.
+     * @return the ComponentOrientation.
+     * @deprecated Use getOrientation(java.util.Locale) method.
+     */
+    @Deprecated
+    public static ComponentOrientation getOrientation(ResourceBundle bdl) {
+        Object obj = null;
+        try {
+            obj = bdl.getObject("Orientation"); //$NON-NLS-1$
+        } catch (MissingResourceException mre) {
+            obj = null;
+        }
+        if (obj instanceof ComponentOrientation) {
+            return (ComponentOrientation)obj;
+        }
+        Locale locale = bdl.getLocale();
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return getOrientation(locale);
+    }
+
+    /**
+     * Gets the orientation for the specified locale.
+     * 
+     * @param locale
+     *            the specified Locale.
+     * @return the ComponentOrientation.
+     */
+    public static ComponentOrientation getOrientation(Locale locale) {
+        String lang = locale.getLanguage();
+        return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
+    }
+
+    /**
+     * Instantiates a new component orientation.
+     * 
+     * @param hor
+     *            whether the items should be arranged horizontally.
+     * @param l2r
+     *            whether this orientation specifies a left-to-right flow.
+     */
+    private ComponentOrientation(boolean hor, boolean l2r) {
+        horizontal = hor;
+        left2right = l2r;
+    }
+
+    /**
+     * Returns true if the text of the of writing systems arranged horizontally.
+     * 
+     * @return true, if the text is written horizontally, false for a vertical
+     *         arrangement.
+     */
+    public boolean isHorizontal() {
+        return horizontal;
+    }
+
+    /**
+     * Returns true if the text is arranged from left to right.
+     * 
+     * @return true, for writing systems written from left to right; false for
+     *         right-to-left.
+     */
+    public boolean isLeftToRight() {
+        return left2right;
+    }
+
+}
diff --git a/awt/java/awt/Composite.java b/awt/java/awt/Composite.java
new file mode 100644
index 0000000..d1730fe
--- /dev/null
+++ b/awt/java/awt/Composite.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+
+/**
+ * The Composite interface allows the methods to compose a draw primitive on the
+ * graphics area. The classes implementing this interface provides the rules and
+ * a method to create the context for a particular operation.
+ * 
+ * @since Android 1.0
+ */
+public interface Composite {
+
+    /**
+     * Creates a CompositeContext which defines the encapsulated and optimized
+     * environment for a compositing operation. Several contexts can exist for a
+     * single Composite object.
+     * 
+     * @param srcColorModel
+     *            the source's ColorModel.
+     * @param dstColorModel
+     *            the destination's ColorModel.
+     * @param hints
+     *            the RenderingHints.
+     * @return the CompositeContext object.
+     */
+    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
+            RenderingHints hints);
+
+}
diff --git a/awt/java/awt/CompositeContext.java b/awt/java/awt/CompositeContext.java
new file mode 100644
index 0000000..795640d
--- /dev/null
+++ b/awt/java/awt/CompositeContext.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * The CompositeContext interface specifies the encapsulated and optimized
+ * environment for a compositing operation.
+ * 
+ * @since Android 1.0
+ */
+public interface CompositeContext {
+
+    /**
+     * Composes the two source Raster objects and places the result in the
+     * destination WritableRaster.
+     * 
+     * @param src
+     *            the source Raster.
+     * @param dstIn
+     *            the destination Raster.
+     * @param dstOut
+     *            the WritableRaster object where the result of composing
+     *            operation is stored.
+     */
+    public void compose(Raster src, Raster dstIn, WritableRaster dstOut);
+
+    /**
+     * Releases resources allocated for a context.
+     */
+    public void dispose();
+
+}
diff --git a/awt/java/awt/Cursor.java b/awt/java/awt/Cursor.java
new file mode 100644
index 0000000..0a0cc84
--- /dev/null
+++ b/awt/java/awt/Cursor.java
@@ -0,0 +1,427 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+/**
+ * The Cursor class represents the bitmap of the mouse cursor.
+ * 
+ * @since Android 1.0
+ */
+public class Cursor implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 8028237497568985504L;
+
+    /**
+     * The Constant DEFAULT_CURSOR indicates the default cursor type.
+     */
+    public static final int DEFAULT_CURSOR = 0;
+
+    /**
+     * The Constant CROSSHAIR_CURSOR cursor type.
+     */
+    public static final int CROSSHAIR_CURSOR = 1;
+
+    /**
+     * The Constant TEXT_CURSOR cursor type.
+     */
+    public static final int TEXT_CURSOR = 2;
+
+    /**
+     * The Constant WAIT_CURSOR cursor type.
+     */
+    public static final int WAIT_CURSOR = 3;
+
+    /**
+     * The Constant SW_RESIZE_CURSOR cursor type.
+     */
+    public static final int SW_RESIZE_CURSOR = 4;
+
+    /**
+     * The Constant SE_RESIZE_CURSOR cursor type.
+     */
+    public static final int SE_RESIZE_CURSOR = 5;
+
+    /**
+     * The Constant NW_RESIZE_CURSOR cursor type.
+     */
+    public static final int NW_RESIZE_CURSOR = 6;
+
+    /**
+     * The Constant NE_RESIZE_CURSOR cursor type.
+     */
+    public static final int NE_RESIZE_CURSOR = 7;
+
+    /**
+     * The Constant N_RESIZE_CURSOR cursor type.
+     */
+    public static final int N_RESIZE_CURSOR = 8;
+
+    /**
+     * The Constant S_RESIZE_CURSOR cursor type.
+     */
+    public static final int S_RESIZE_CURSOR = 9;
+
+    /**
+     * The Constant W_RESIZE_CURSOR cursor type.
+     */
+    public static final int W_RESIZE_CURSOR = 10;
+
+    /**
+     * The Constant E_RESIZE_CURSOR cursor type.
+     */
+    public static final int E_RESIZE_CURSOR = 11;
+
+    /**
+     * The Constant HAND_CURSOR cursor type.
+     */
+    public static final int HAND_CURSOR = 12;
+
+    /**
+     * The Constant MOVE_CURSOR cursor type.
+     */
+    public static final int MOVE_CURSOR = 13;
+
+    /**
+     * A mapping from names to system custom cursors.
+     */
+    static Map<String, Cursor> systemCustomCursors;
+
+    /**
+     * The cursor props.
+     */
+    static Properties cursorProps;
+
+    /**
+     * The Constant predefinedNames.
+     */
+    static final String[] predefinedNames = {
+            "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
+
+    };
+
+    /**
+     * The predefined set of cursors.
+     */
+    protected static Cursor[] predefined = {
+            new Cursor(DEFAULT_CURSOR), null, null, null, null, null, null, null, null, null, null,
+            null, null, null
+    };
+
+    /**
+     * The Constant CUSTOM_CURSOR is associated with all custom cursor types.
+     * (Those which are not predefined)
+     */
+    public static final int CUSTOM_CURSOR = -1;
+
+    /**
+     * The name of the cursor.
+     */
+    protected String name;
+
+    /**
+     * The type of the cursor, chosen from the list of cursor type constants.
+     */
+    private final int type;
+
+    /**
+     * The native cursor.
+     */
+    private transient NativeCursor nativeCursor;
+
+    /**
+     * The exact point on the cursor image that indicates which point the cursor
+     * is selecting (pointing to). The coordinates are given with respect the
+     * origin of the Image (its upper left corner).
+     */
+    private Point hotSpot;
+
+    /**
+     * The image to draw on the screen representing the cursor.
+     */
+    private Image image;
+
+    /**
+     * Instantiates a new cursor with the specified name.
+     * 
+     * @param name
+     *            the name of cursor.
+     */
+    protected Cursor(String name) {
+        this(name, null, new Point());
+    }
+
+    /**
+     * Instantiates a new cursor of the specified type.
+     * 
+     * @param type
+     *            the type of cursor.
+     */
+    public Cursor(int type) {
+        checkType(type);
+        this.type = type;
+        if ((type >= 0) && (type < predefinedNames.length)) {
+            name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Instantiates a new cursor.
+     * 
+     * @param name
+     *            the name.
+     * @param img
+     *            the img.
+     * @param hotSpot
+     *            the hot spot.
+     */
+    Cursor(String name, Image img, Point hotSpot) {
+        this.name = name;
+        type = CUSTOM_CURSOR;
+        this.hotSpot = hotSpot;
+        image = img;
+    }
+
+    /**
+     * Finalize method overrides the finalize method from Object class.
+     * 
+     * @throws Throwable
+     *             if the native cursor is not null and throws a Throwable when
+     *             destroyed.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (nativeCursor != null) {
+            nativeCursor.destroyCursor();
+        }
+    }
+
+    /**
+     * Gets the name of the cursor.
+     * 
+     * @return the name of the cursor.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the String representation of the cursor.
+     * 
+     * @return the String representation of the cursor.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the cursor type.
+     * 
+     * @return the cursor type.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the predefined cursor with the specified type.
+     * 
+     * @param type
+     *            the type of cursor.
+     * @return the predefined cursor with the specified type.
+     */
+    public static Cursor getPredefinedCursor(int type) {
+        checkType(type);
+        Cursor cursor = predefined[type];
+        if (cursor == null) {
+            cursor = new Cursor(type);
+            predefined[type] = cursor;
+        }
+        return cursor;
+    }
+
+    /**
+     * Gets the default cursor.
+     * 
+     * @return the default cursor.
+     */
+    public static Cursor getDefaultCursor() {
+        return getPredefinedCursor(DEFAULT_CURSOR);
+    }
+
+    /**
+     * Gets the specified system custom cursor.
+     * 
+     * @param name
+     *            the name of the desired system cursor.
+     * @return the specific system cursor with the specified name.
+     * @throws AWTException
+     *             if the desired cursor has malformed data such as an
+     *             incorrectly defined hot spot.
+     * @throws HeadlessException
+     *             if the isHeadless method of the GraphicsEnvironment returns
+     *             true.
+     */
+    public static Cursor getSystemCustomCursor(String name) throws AWTException, HeadlessException {
+        Toolkit.checkHeadless();
+        return getSystemCustomCursorFromMap(name);
+    }
+
+    /**
+     * Gets the specified system custom cursor from the map of system custom
+     * cursors.
+     * 
+     * @param name
+     *            the name of the desired cursor.
+     * @return the desired system custom cursor from the map of system custom
+     *         cursors.
+     * @throws AWTException
+     *             the AWT exception.
+     */
+    private static Cursor getSystemCustomCursorFromMap(String name) throws AWTException {
+        loadCursorProps();
+        if (systemCustomCursors == null) {
+            systemCustomCursors = new HashMap<String, Cursor>();
+        }
+        Cursor cursor = systemCustomCursors.get(name);
+        if (cursor != null) {
+            return cursor;
+        }
+        // awt.141=failed to parse hotspot property for cursor:
+        String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
+        String nm = "Cursor." + name; //$NON-NLS-1$
+        String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
+        String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
+        String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
+        int idx = hotSpotStr.indexOf(',');
+        if (idx < 0) {
+            throw new AWTException(exMsg);
+        }
+        int x, y;
+        try {
+            x = new Integer(hotSpotStr.substring(0, idx)).intValue();
+            y = new Integer(hotSpotStr.substring(idx + 1, hotSpotStr.length())).intValue();
+        } catch (NumberFormatException nfe) {
+            throw new AWTException(exMsg);
+        }
+        Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
+        cursor = new Cursor(nameStr, img, new Point(x, y));
+        systemCustomCursors.put(name, cursor);
+
+        return cursor;
+    }
+
+    /**
+     * Load cursor props.
+     * 
+     * @throws AWTException
+     *             the AWT exception.
+     */
+    private static void loadCursorProps() throws AWTException {
+        if (cursorProps != null) {
+            return;
+        }
+        String sep = File.separator;
+        String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
+                cursorsDir;
+        String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
+        String cursorPropsFullFileName = (cursorsAbsDir + sep + cursorPropsFileName);
+        cursorProps = new Properties();
+        try {
+            cursorProps.load(new FileInputStream(new File(cursorPropsFullFileName)));
+        } catch (FileNotFoundException e) {
+            // awt.142=Exception: class {0} {1} occurred while loading: {2}
+            throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
+                    new Object[] {
+                            e.getClass(), e.getMessage(), cursorPropsFullFileName
+                    }));
+        } catch (IOException e) {
+            throw new AWTException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * Check type.
+     * 
+     * @param type
+     *            the type.
+     */
+    static void checkType(int type) {
+        // can't use predefined array here because it may not have been
+        // initialized yet
+        if ((type < 0) || (type >= predefinedNames.length)) {
+            // awt.143=illegal cursor type
+            throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
+        }
+    }
+
+    // "lazily" create native cursors:
+    /**
+     * Gets the native cursor.
+     * 
+     * @return the native cursor.
+     */
+    NativeCursor getNativeCursor() {
+        if (nativeCursor != null) {
+            return nativeCursor;
+        }
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        if (type != CUSTOM_CURSOR) {
+            nativeCursor = toolkit.createNativeCursor(type);
+        } else {
+            nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot, name);
+        }
+        return nativeCursor;
+    }
+
+    /**
+     * Sets the native cursor.
+     * 
+     * @param nativeCursor
+     *            the new native cursor.
+     */
+    void setNativeCursor(NativeCursor nativeCursor) {
+        this.nativeCursor = nativeCursor;
+    }
+}
diff --git a/awt/java/awt/Dimension.java b/awt/java/awt/Dimension.java
new file mode 100644
index 0000000..6777962
--- /dev/null
+++ b/awt/java/awt/Dimension.java
@@ -0,0 +1,201 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.Dimension2D;
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Dimension represents the size (width and height) of a component. The
+ * width and height values can be negative, but in that case the behavior of
+ * some methods is unexpected.
+ * 
+ * @since Android 1.0
+ */
+public class Dimension extends Dimension2D implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 4723952579491349524L;
+
+    /**
+     * The width dimension.
+     */
+    public int width;
+
+    /**
+     * The height dimension.
+     */
+    public int height;
+
+    /**
+     * Instantiates a new Dimension with the same data as the specified
+     * Dimension.
+     * 
+     * @param d
+     *            the Dimension to copy the data from when creating the new
+     *            Dimension object.
+     */
+    public Dimension(Dimension d) {
+        this(d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new Dimension with zero width and height.
+     */
+    public Dimension() {
+        this(0, 0);
+    }
+
+    /**
+     * Instantiates a new Dimension with the specified width and height.
+     * 
+     * @param width
+     *            the width of the new Dimension.
+     * @param height
+     *            the height of the new Dimension.
+     */
+    public Dimension(int width, int height) {
+        setSize(width, height);
+    }
+
+    /**
+     * Returns the hash code of the Dimension.
+     * 
+     * @return the hash code of the Dimension.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(height);
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this Dimension object with the specified object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified Object is a Dimension with the same width
+     *         and height data as this Dimension.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Dimension) {
+            Dimension d = (Dimension)obj;
+            return (d.width == width && d.height == height);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the String associated to this Dimension object.
+     * 
+     * @return the String associated to this Dimension object.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be
+        // obtained in the following way
+        // System.out.println(new Dimension().toString())
+        return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified width and
+     * height.
+     * 
+     * @param width
+     *            the width of the Dimension.
+     * @param height
+     *            the height of the Dimension.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of this Dimension object by copying the data from the
+     * specified Dimension object.
+     * 
+     * @param d
+     *            the Dimension that gives the new size values.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified double width
+     * and height.
+     * 
+     * @param width
+     *            the width of the Dimension.
+     * @param height
+     *            the height of the Dimension.
+     * @see java.awt.geom.Dimension2D#setSize(double, double)
+     */
+    @Override
+    public void setSize(double width, double height) {
+        setSize((int)Math.ceil(width), (int)Math.ceil(height));
+    }
+
+    /**
+     * Gets the size of the Dimension.
+     * 
+     * @return the size of the Dimension.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Gets the height of the Dimension.
+     * 
+     * @return the height of the Dimension.
+     * @see java.awt.geom.Dimension2D#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the Dimension.
+     * 
+     * @return the width of the Dimension.
+     * @see java.awt.geom.Dimension2D#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+}
diff --git a/awt/java/awt/Dispatcher.java b/awt/java/awt/Dispatcher.java
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..8021010
--- /dev/null
+++ b/awt/java/awt/DisplayMode.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The DisplayMode class contains the bit depth, height, width and refresh rate
+ * of a GraphicsDevice.
+ * 
+ * @since Android 1.0
+ */
+public final class DisplayMode {
+
+    /**
+     * The width.
+     */
+    private final int width;
+
+    /**
+     * The height.
+     */
+    private final int height;
+
+    /**
+     * The bit depth.
+     */
+    private final int bitDepth;
+
+    /**
+     * The refresh rate.
+     */
+    private final int refreshRate;
+
+    /**
+     * The Constant Value BIT_DEPTH_MULTI indicates the bit depth
+     */
+
+    public static final int BIT_DEPTH_MULTI = -1;
+
+    /**
+     * The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate.
+     */
+    public static final int REFRESH_RATE_UNKNOWN = 0;
+
+    /**
+     * Creates a new DisplayMode object with the specified parameters.
+     * 
+     * @param width
+     *            the width of the display.
+     * @param height
+     *            the height of the display.
+     * @param bitDepth
+     *            the bit depth of the display.
+     * @param refreshRate
+     *            the refresh rate of the display.
+     */
+
+    public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
+        this.width = width;
+        this.height = height;
+        this.bitDepth = bitDepth;
+        this.refreshRate = refreshRate;
+    }
+
+    /**
+     * Compares if this DisplayMode is equal to the specified object or not.
+     * 
+     * @param dm
+     *            the Object to be compared.
+     * @return true, if the specified object is a DisplayMode with the same data
+     *         values as this DisplayMode, false otherwise.
+     */
+
+    @Override
+    public boolean equals(Object dm) {
+        if (dm instanceof DisplayMode) {
+            return equals((DisplayMode)dm);
+        }
+        return false;
+    }
+
+    /**
+     * Compares if this DisplayMode is equal to the specified DisplayMode object
+     * or not.
+     * 
+     * @param dm
+     *            the DisplayMode to be compared.
+     * @return true, if all of the data values of this DisplayMode are equal to
+     *         the values of the specified DisplayMode object, false otherwise.
+     */
+    public boolean equals(DisplayMode dm) {
+        if (dm == null) {
+            return false;
+        }
+        if (dm.bitDepth != bitDepth) {
+            return false;
+        }
+        if (dm.refreshRate != refreshRate) {
+            return false;
+        }
+        if (dm.width != width) {
+            return false;
+        }
+        if (dm.height != height) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value if
+     * multiple bit depths are supported in this display mode.
+     * 
+     * @return the bit depth of the DisplayMode.
+     */
+    public int getBitDepth() {
+        return bitDepth;
+    }
+
+    /**
+     * Gets the height of the DisplayMode.
+     * 
+     * @return the height of the DisplayMode.
+     */
+    public int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
+     * value if the information is not available.
+     * 
+     * @return the refresh rate of the DisplayMode.
+     */
+    public int getRefreshRate() {
+        return refreshRate;
+    }
+
+    /**
+     * Gets the width of the DisplayMode.
+     * 
+     * @return the width of the DisplayMode.
+     */
+    public int getWidth() {
+        return width;
+    }
+}
diff --git a/awt/java/awt/Event.java b/awt/java/awt/Event.java
new file mode 100644
index 0000000..226a61f
--- /dev/null
+++ b/awt/java/awt/Event.java
@@ -0,0 +1,596 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * The Event class is obsolete and has been replaced by AWTEvent class.
+ * 
+ * @since Android 1.0
+ */
+public class Event implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 5488922509400504703L;
+
+    /**
+     * The Constant SHIFT_MASK indicates that the Shift key is down when the
+     * event occurred.
+     */
+    public static final int SHIFT_MASK = 1;
+
+    /**
+     * The Constant CTRL_MASK indicates that the Control key is down when the
+     * event occurred.
+     */
+    public static final int CTRL_MASK = 2;
+
+    /**
+     * The Constant META_MASK indicates that the Meta key is down when t he
+     * event occurred (or the right mouse button).
+     */
+    public static final int META_MASK = 4;
+
+    /**
+     * The Constant ALT_MASK indicates that the Alt key is down when the event
+     * occurred (or the middle mouse button).
+     */
+    public static final int ALT_MASK = 8;
+
+    /**
+     * The Constant HOME indicates Home key.
+     */
+    public static final int HOME = 1000;
+
+    /**
+     * The Constant END indicates End key.
+     */
+    public static final int END = 1001;
+
+    /**
+     * The Constant PGUP indicates Page Up key.
+     */
+    public static final int PGUP = 1002;
+
+    /**
+     * The Constant PGDN indicates Page Down key.
+     */
+    public static final int PGDN = 1003;
+
+    /**
+     * The Constant UP indicates Up key.
+     */
+    public static final int UP = 1004;
+
+    /**
+     * The Constant DOWN indicates Down key.
+     */
+    public static final int DOWN = 1005;
+
+    /**
+     * The Constant LEFT indicates Left key.
+     */
+    public static final int LEFT = 1006;
+
+    /**
+     * The Constant RIGHT indicates Right key.
+     */
+    public static final int RIGHT = 1007;
+
+    /**
+     * The Constant F1 indicates F1 key.
+     */
+    public static final int F1 = 1008;
+
+    /**
+     * The Constant F2 indicates F2 key.
+     */
+    public static final int F2 = 1009;
+
+    /**
+     * The Constant F3 indicates F3 key.
+     */
+    public static final int F3 = 1010;
+
+    /**
+     * The Constant F4 indicates F4 key.
+     */
+    public static final int F4 = 1011;
+
+    /**
+     * The Constant F5 indicates F5 key.
+     */
+    public static final int F5 = 1012;
+
+    /**
+     * The Constant F6 indicates F6 key.
+     */
+    public static final int F6 = 1013;
+
+    /**
+     * The Constant F7 indicates F7 key.
+     */
+    public static final int F7 = 1014;
+
+    /**
+     * The Constant F8 indicates F8 key.
+     */
+    public static final int F8 = 1015;
+
+    /**
+     * The Constant F9 indicates F9 key.
+     */
+    public static final int F9 = 1016;
+
+    /**
+     * The Constant F10 indicates F10 key.
+     */
+    public static final int F10 = 1017;
+
+    /**
+     * The Constant F11 indicates F11 key.
+     */
+    public static final int F11 = 1018;
+
+    /**
+     * The Constant F12 indicates F12 key.
+     */
+    public static final int F12 = 1019;
+
+    /**
+     * The Constant PRINT_SCREEN indicates Print Screen key.
+     */
+    public static final int PRINT_SCREEN = 1020;
+
+    /**
+     * The Constant SCROLL_LOCK indicates Scroll Lock key.
+     */
+    public static final int SCROLL_LOCK = 1021;
+
+    /**
+     * The Constant CAPS_LOCK indicates Caps Lock key.
+     */
+    public static final int CAPS_LOCK = 1022;
+
+    /**
+     * The Constant NUM_LOCK indicates Num Lock key.
+     */
+    public static final int NUM_LOCK = 1023;
+
+    /**
+     * The Constant PAUSE indicates Pause key.
+     */
+    public static final int PAUSE = 1024;
+
+    /**
+     * The Constant INSERT indicates Insert key.
+     */
+    public static final int INSERT = 1025;
+
+    /**
+     * The Constant ENTER indicates Enter key.
+     */
+    public static final int ENTER = 10;
+
+    /**
+     * The Constant BACK_SPACE indicates Back Space key.
+     */
+    public static final int BACK_SPACE = 8;
+
+    /**
+     * The Constant TAB indicates TAb key.
+     */
+    public static final int TAB = 9;
+
+    /**
+     * The Constant ESCAPE indicates Escape key.
+     */
+    public static final int ESCAPE = 27;
+
+    /**
+     * The Constant DELETE indicates Delete key.
+     */
+    public static final int DELETE = 127;
+
+    /**
+     * The Constant WINDOW_DESTROY indicates an event when the user has asked
+     * the window manager to kill the window.
+     */
+    public static final int WINDOW_DESTROY = 201;
+
+    /**
+     * The Constant WINDOW_EXPOSE indicates an event when the user has asked the
+     * window manager to expose the window.
+     */
+    public static final int WINDOW_EXPOSE = 202;
+
+    /**
+     * The Constant WINDOW_ICONIFY indicates an event when the user has asked
+     * the window manager to iconify the window.
+     */
+    public static final int WINDOW_ICONIFY = 203;
+
+    /**
+     * The Constant WINDOW_DEICONIFY indicates an event when the user has asked
+     * the window manager to deiconify the window.
+     */
+    public static final int WINDOW_DEICONIFY = 204;
+
+    /**
+     * The Constant WINDOW_MOVED indicates an event when the user has asked the
+     * window manager to move the window.
+     */
+    public static final int WINDOW_MOVED = 205;
+
+    /**
+     * The Constant KEY_PRESS indicates an event when the user presses a normal
+     * key.
+     */
+    public static final int KEY_PRESS = 401;
+
+    /**
+     * The Constant KEY_RELEASE indicates an event when the user releases a
+     * normal key.
+     */
+    public static final int KEY_RELEASE = 402;
+
+    /**
+     * The Constant KEY_ACTION indicates an event when the user pressed a
+     * non-ASCII action key.
+     */
+    public static final int KEY_ACTION = 403;
+
+    /**
+     * The Constant KEY_ACTION_RELEASE indicates an event when the user released
+     * a non-ASCII action key.
+     */
+    public static final int KEY_ACTION_RELEASE = 404;
+
+    /**
+     * The Constant MOUSE_DOWN indicates an event when the user has pressed the
+     * mouse button.
+     */
+    public static final int MOUSE_DOWN = 501;
+
+    /**
+     * The Constant MOUSE_UP indicates an event when the user has released the
+     * mouse button.
+     */
+    public static final int MOUSE_UP = 502;
+
+    /**
+     * The Constant MOUSE_MOVE indicates an event when the user has moved the
+     * mouse with no button pressed.
+     */
+    public static final int MOUSE_MOVE = 503;
+
+    /**
+     * The Constant MOUSE_ENTER indicates an event when the mouse has entered a
+     * component.
+     */
+    public static final int MOUSE_ENTER = 504;
+
+    /**
+     * The Constant MOUSE_EXIT indicates an event when the mouse has exited a
+     * component.
+     */
+    public static final int MOUSE_EXIT = 505;
+
+    /**
+     * The Constant MOUSE_DRAG indicates an event when the user has moved a
+     * mouse with the pressed button.
+     */
+    public static final int MOUSE_DRAG = 506;
+
+    /**
+     * The Constant SCROLL_LINE_UP indicates an event when the user has
+     * activated line-up area of scrollbar.
+     */
+    public static final int SCROLL_LINE_UP = 601;
+
+    /**
+     * The Constant SCROLL_LINE_DOWN indicates an event when the user has
+     * activated line-down area of scrollbar.
+     */
+    public static final int SCROLL_LINE_DOWN = 602;
+
+    /**
+     * The Constant SCROLL_PAGE_UP indicates an event when the user has
+     * activated page up area of scrollbar.
+     */
+    public static final int SCROLL_PAGE_UP = 603;
+
+    /**
+     * The Constant SCROLL_PAGE_DOWN indicates an event when the user has
+     * activated page down area of scrollbar.
+     */
+    public static final int SCROLL_PAGE_DOWN = 604;
+
+    /**
+     * The Constant SCROLL_ABSOLUTE indicates an event when the user has moved
+     * the bubble in a scroll bar.
+     */
+    public static final int SCROLL_ABSOLUTE = 605;
+
+    /**
+     * The Constant SCROLL_BEGIN indicates a scroll begin event.
+     */
+    public static final int SCROLL_BEGIN = 606;
+
+    /**
+     * The Constant SCROLL_END indicates a scroll end event.
+     */
+    public static final int SCROLL_END = 607;
+
+    /**
+     * The Constant LIST_SELECT indicates that an item in a list has been
+     * selected.
+     */
+    public static final int LIST_SELECT = 701;
+
+    /**
+     * The Constant LIST_DESELECT indicates that an item in a list has been
+     * unselected.
+     */
+    public static final int LIST_DESELECT = 702;
+
+    /**
+     * The Constant ACTION_EVENT indicates that the user wants some action to
+     * occur.
+     */
+    public static final int ACTION_EVENT = 1001;
+
+    /**
+     * The Constant LOAD_FILE indicates a file loading event.
+     */
+    public static final int LOAD_FILE = 1002;
+
+    /**
+     * The Constant SAVE_FILE indicates a file saving event.
+     */
+    public static final int SAVE_FILE = 1003;
+
+    /**
+     * The Constant GOT_FOCUS indicates that a component got the focus.
+     */
+    public static final int GOT_FOCUS = 1004;
+
+    /**
+     * The Constant LOST_FOCUS indicates that the component lost the focus.
+     */
+    public static final int LOST_FOCUS = 1005;
+
+    /**
+     * The target is the component with which the event is associated.
+     */
+    public Object target;
+
+    /**
+     * The when is timestamp when event has occured.
+     */
+    public long when;
+
+    /**
+     * The id indicates the type of the event.
+     */
+    public int id;
+
+    /**
+     * The x coordinate of event.
+     */
+    public int x;
+
+    /**
+     * The y coordinate of event.
+     */
+    public int y;
+
+    /**
+     * The key code of key event.
+     */
+    public int key;
+
+    /**
+     * The state of the modifier keys (given by a bitmask).
+     */
+    public int modifiers;
+
+    /**
+     * The click count indicates the number of consecutive clicks.
+     */
+    public int clickCount;
+
+    /**
+     * The argument of the event.
+     */
+    public Object arg;
+
+    /**
+     * The next event.
+     */
+    public Event evt;
+
+    /**
+     * Instantiates a new event with the specified target component, event type,
+     * and argument.
+     * 
+     * @param target
+     *            the target component.
+     * @param id
+     *            the event type.
+     * @param arg
+     *            the argument.
+     */
+    public Event(Object target, int id, Object arg) {
+        this(target, 0l, id, 0, 0, 0, 0, arg);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument set to null.
+     * 
+     * @param target
+     *            the target component.
+     * @param when
+     *            the time stamp.
+     * @param id
+     *            the event type.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @param key
+     *            the key.
+     * @param modifiers
+     *            the modifier keys state.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
+        this(target, when, id, x, y, key, modifiers, null);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument.
+     * 
+     * @param target
+     *            the target component.
+     * @param when
+     *            the time stamp.
+     * @param id
+     *            the event type.
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @param key
+     *            the key.
+     * @param modifiers
+     *            the modifier keys state.
+     * @param arg
+     *            the specified argument.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg) {
+        this.target = target;
+        this.when = when;
+        this.id = id;
+        this.x = x;
+        this.y = y;
+        this.key = key;
+        this.modifiers = modifiers;
+        this.arg = arg;
+    }
+
+    /**
+     * Returns a string representation of this Event.
+     * 
+     * @return a string representation of this Event.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code: Event e = new Event(new Button(), 0l,
+         * Event.KEY_PRESS, 0, 0, Event.TAB, Event.SHIFT_MASK, "arg");
+         * System.out.println(e);
+         */
+
+        return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns a string representing the state of this Event.
+     * 
+     * @return a string representing the state of this Event.
+     */
+    protected String paramString() {
+        return "id=" + id + ",x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                (key != 0 ? ",key=" + key + getModifiersString() : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",target=" + target + //$NON-NLS-1$
+                (arg != null ? ",arg=" + arg : ""); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets a string representation of the modifiers.
+     * 
+     * @return a string representation of the modifiers.
+     */
+    private String getModifiersString() {
+        String strMod = ""; //$NON-NLS-1$
+        if (shiftDown()) {
+            strMod += ",shift"; //$NON-NLS-1$
+        }
+        if (controlDown()) {
+            strMod += ",control"; //$NON-NLS-1$
+        }
+        if (metaDown()) {
+            strMod += ",meta"; //$NON-NLS-1$
+        }
+        return strMod;
+    }
+
+    /**
+     * Translates x and y coordinates of his event to the x+dx and x+dy
+     * coordinates.
+     * 
+     * @param dx
+     *            the distance by which the event's x coordinate is increased.
+     * @param dy
+     *            the distance by which the event's y coordinate is increased.
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+    /**
+     * Checks if Control key is down or not.
+     * 
+     * @return true, if Control key is down; false otherwise.
+     */
+    public boolean controlDown() {
+        return (modifiers & CTRL_MASK) != 0;
+    }
+
+    /**
+     * Checks if Meta key is down or not.
+     * 
+     * @return true, if Meta key is down; false otherwise.
+     */
+    public boolean metaDown() {
+        return (modifiers & META_MASK) != 0;
+    }
+
+    /**
+     * Checks if Shift key is down or not.
+     * 
+     * @return true, if Shift key is down; false otherwise.
+     */
+    public boolean shiftDown() {
+        return (modifiers & SHIFT_MASK) != 0;
+    }
+
+}
diff --git a/awt/java/awt/EventDispatchThread.java b/awt/java/awt/EventDispatchThread.java
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..126a593
--- /dev/null
+++ b/awt/java/awt/EventQueue.java
@@ -0,0 +1,320 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.event.InvocationEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EmptyStackException;
+
+/**
+ * The EventQueue class manages events. It is a platform-independent class that
+ * queues events both from the underlying peer classes and from trusted
+ * application classes.
+ * 
+ * @since Android 1.0
+ */
+public class EventQueue {
+
+    /**
+     * The core ref.
+     */
+    private final EventQueueCoreAtomicReference coreRef = new EventQueueCoreAtomicReference();
+
+    /**
+     * The Class EventQueueCoreAtomicReference.
+     */
+    private static final class EventQueueCoreAtomicReference {
+
+        /**
+         * The core.
+         */
+        private EventQueueCore core;
+
+        /* synchronized */
+        /**
+         * Gets the.
+         * 
+         * @return the event queue core.
+         */
+        EventQueueCore get() {
+            return core;
+        }
+
+        /* synchronized */
+        /**
+         * Sets the.
+         * 
+         * @param newCore
+         *            the new core.
+         */
+        void set(EventQueueCore newCore) {
+            core = newCore;
+        }
+    }
+
+    /**
+     * Returns true if the calling thread is the current AWT EventQueue's
+     * dispatch thread.
+     * 
+     * @return true, if the calling thread is the current AWT EventQueue's
+     *         dispatch thread; false otherwise.
+     */
+    public static boolean isDispatchThread() {
+        return Thread.currentThread() instanceof EventDispatchThread;
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable
+     * when dispatched by the AWT event dispatcher thread.
+     * 
+     * @param runnable
+     *            the Runnable whose run method should be executed synchronously
+     *            on the EventQueue.
+     */
+    public static void invokeLater(Runnable runnable) {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        InvocationEvent event = new InvocationEvent(toolkit, runnable);
+        toolkit.getSystemEventQueueImpl().postEvent(event);
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable
+     * when dispatched by the AWT event dispatcher thread and the notifyAll
+     * method is called on it immediately after run returns.
+     * 
+     * @param runnable
+     *            the Runnable whose run method should be executed synchronously
+     *            on the EventQueue.
+     * @throws InterruptedException
+     *             if another thread has interrupted this thread.
+     * @throws InvocationTargetException
+     *             if an error occurred while running the runnable.
+     */
+    public static void invokeAndWait(Runnable runnable) throws InterruptedException,
+            InvocationTargetException {
+
+        if (isDispatchThread()) {
+            throw new Error();
+        }
+
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        final Object notifier = new Object(); // $NON-LOCK-1$
+        InvocationEvent event = new InvocationEvent(toolkit, runnable, notifier, true);
+
+        synchronized (notifier) {
+            toolkit.getSystemEventQueueImpl().postEvent(event);
+            notifier.wait();
+        }
+
+        Exception exception = event.getException();
+
+        if (exception != null) {
+            throw new InvocationTargetException(exception);
+        }
+    }
+
+    /**
+     * Gets the system event queue.
+     * 
+     * @return the system event queue.
+     */
+    private static EventQueue getSystemEventQueue() {
+        Thread th = Thread.currentThread();
+        if (th instanceof EventDispatchThread) {
+            return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the most recent event's timestamp. This event was dispatched from
+     * the EventQueue associated with the calling thread.
+     * 
+     * @return the timestamp of the last Event to be dispatched, or
+     *         System.currentTimeMillis() if this method is invoked from a
+     *         thread other than an event-dispatching thread.
+     */
+    public static long getMostRecentEventTime() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
+    }
+
+    /**
+     * Gets the most recent event time impl.
+     * 
+     * @return the most recent event time impl.
+     */
+    private long getMostRecentEventTimeImpl() {
+        return getCore().getMostRecentEventTime();
+    }
+
+    /**
+     * Returns the the currently dispatched event by the EventQueue associated
+     * with the calling thread.
+     * 
+     * @return the currently dispatched event or null if this method is invoked
+     *         from a thread other than an event-dispatching thread.
+     */
+    public static AWTEvent getCurrentEvent() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? eq.getCurrentEventImpl() : null;
+    }
+
+    /**
+     * Gets the current event impl.
+     * 
+     * @return the current event impl.
+     */
+    private AWTEvent getCurrentEventImpl() {
+        return getCore().getCurrentEvent();
+    }
+
+    /**
+     * Instantiates a new event queue.
+     */
+    public EventQueue() {
+        setCore(new EventQueueCore(this));
+    }
+
+    /**
+     * Instantiates a new event queue.
+     * 
+     * @param t
+     *            the t.
+     */
+    EventQueue(Toolkit t) {
+        setCore(new EventQueueCore(this, t));
+    }
+
+    /**
+     * Posts a event to the EventQueue.
+     * 
+     * @param event
+     *            AWTEvent.
+     */
+    public void postEvent(AWTEvent event) {
+        event.isPosted = true;
+        getCore().postEvent(event);
+    }
+
+    /**
+     * Returns an event from the EventQueue and removes it from this queue.
+     * 
+     * @return the next AWTEvent.
+     * @throws InterruptedException
+     *             is thrown if another thread interrupts this thread.
+     */
+    public AWTEvent getNextEvent() throws InterruptedException {
+        return getCore().getNextEvent();
+    }
+
+    /**
+     * Gets the next event no wait.
+     * 
+     * @return the next event no wait.
+     */
+    AWTEvent getNextEventNoWait() {
+        return getCore().getNextEventNoWait();
+    }
+
+    /**
+     * Returns the first event of the EventQueue (without removing it from the
+     * queue).
+     * 
+     * @return the the first AWT event of the EventQueue.
+     */
+    public AWTEvent peekEvent() {
+        return getCore().peekEvent();
+    }
+
+    /**
+     * Returns the first event of the EventQueue with the specified ID (without
+     * removing it from the queue).
+     * 
+     * @param id
+     *            the type ID of event.
+     * @return the first event of the EventQueue with the specified ID.
+     */
+    public AWTEvent peekEvent(int id) {
+        return getCore().peekEvent(id);
+    }
+
+    /**
+     * Replaces the existing EventQueue with the specified EventQueue. Any
+     * pending events are transferred to the new EventQueue.
+     * 
+     * @param newEventQueue
+     *            the new event queue.
+     */
+    public void push(EventQueue newEventQueue) {
+        getCore().push(newEventQueue);
+    }
+
+    /**
+     * Stops dispatching events using this EventQueue. Any pending events are
+     * transferred to the previous EventQueue.
+     * 
+     * @throws EmptyStackException
+     *             is thrown if no previous push was made on this EventQueue.
+     */
+    protected void pop() throws EmptyStackException {
+        getCore().pop();
+    }
+
+    /**
+     * Dispatches the specified event.
+     * 
+     * @param event
+     *            the AWTEvent.
+     */
+    protected void dispatchEvent(AWTEvent event) {
+        getCore().dispatchEventImpl(event);
+    }
+
+    /**
+     * Checks if the queue is empty.
+     * 
+     * @return true, if is empty.
+     */
+    boolean isEmpty() {
+        return getCore().isEmpty();
+    }
+
+    /**
+     * Gets the core.
+     * 
+     * @return the core.
+     */
+    EventQueueCore getCore() {
+        return coreRef.get();
+    }
+
+    /**
+     * Sets the core.
+     * 
+     * @param newCore
+     *            the new core.
+     */
+    void setCore(EventQueueCore newCore) {
+        coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
+    }
+}
diff --git a/awt/java/awt/EventQueueCore.java b/awt/java/awt/EventQueueCore.java
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..4ed9343
--- /dev/null
+++ b/awt/java/awt/Font.java
@@ -0,0 +1,1541 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TransformAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.luni.util.NotImplementedException;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Font class represents fonts for rendering text. This class allow to map
+ * characters to glyphs.
+ * <p>
+ * A glyph is a shape used to render a character or a sequence of characters.
+ * For example one character of Latin writing system represented by one glyph,
+ * but in complex writing system such as South and South-East Asian there is
+ * more complicated correspondence between characters and glyphs.
+ * <p>
+ * The Font object is identified by two types of names. The logical font name is
+ * the name that is used to construct the font. The font name is the name of a
+ * particular font face (for example, Arial Bold). The family name is the font's
+ * family name that specifies the typographic design across several faces (for
+ * example, Arial). In all the Font is identified by three attributes: the
+ * family name, the style (such as bold or italic), and the size.
+ * 
+ * @since Android 1.0
+ */
+public class Font implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -4206021311591459213L;
+
+    // Identity Transform attribute
+    /**
+     * The Constant IDENTITY_TRANSFORM.
+     */
+    private static final TransformAttribute IDENTITY_TRANSFORM = new TransformAttribute(
+            new AffineTransform());
+
+    /**
+     * The Constant PLAIN indicates font's plain style.
+     */
+    public static final int PLAIN = 0;
+
+    /**
+     * The Constant BOLD indicates font's bold style.
+     */
+    public static final int BOLD = 1;
+
+    /**
+     * The Constant ITALIC indicates font's italic style.
+     */
+    public static final int ITALIC = 2;
+
+    /**
+     * The Constant ROMAN_BASELINE indicated roman baseline.
+     */
+    public static final int ROMAN_BASELINE = 0;
+
+    /**
+     * The Constant CENTER_BASELINE indicates center baseline.
+     */
+    public static final int CENTER_BASELINE = 1;
+
+    /**
+     * The Constant HANGING_BASELINE indicates hanging baseline.
+     */
+    public static final int HANGING_BASELINE = 2;
+
+    /**
+     * The Constant TRUETYPE_FONT indicates a font resource of type TRUETYPE.
+     */
+    public static final int TRUETYPE_FONT = 0;
+
+    /**
+     * The Constant TYPE1_FONT indicates a font resource of type TYPE1.
+     */
+    public static final int TYPE1_FONT = 1;
+
+    /**
+     * The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is left to right.
+     */
+    public static final int LAYOUT_LEFT_TO_RIGHT = 0;
+
+    /**
+     * The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is right to left.
+     */
+    public static final int LAYOUT_RIGHT_TO_LEFT = 1;
+
+    /**
+     * The Constant LAYOUT_NO_START_CONTEXT indicates that the text in the char
+     * array before the indicated start should not be examined.
+     */
+    public static final int LAYOUT_NO_START_CONTEXT = 2;
+
+    /**
+     * The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in the char
+     * array after the indicated limit should not be examined.
+     */
+    public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+
+    /**
+     * The Constant DEFAULT_FONT.
+     */
+    static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
+
+    /**
+     * The name of the Font.
+     */
+    protected String name;
+
+    /**
+     * The style of the Font.
+     */
+    protected int style;
+
+    /**
+     * The size of the Font.
+     */
+    protected int size;
+
+    /**
+     * The point size of the Font.
+     */
+    protected float pointSize;
+
+    // Flag if the Font object transformed
+    /**
+     * The transformed.
+     */
+    private boolean transformed;
+
+    // Set of font attributes
+    /**
+     * The requested attributes.
+     */
+    private Hashtable<Attribute, Object> fRequestedAttributes;
+
+    // font peer object corresponding to this Font
+    /**
+     * The font peer.
+     */
+    private transient FontPeerImpl fontPeer;
+
+    // number of glyphs in this Font
+    /**
+     * The num glyphs.
+     */
+    private transient int numGlyphs = -1;
+
+    // code for missing glyph for this Font
+    /**
+     * The missing glyph code.
+     */
+    private transient int missingGlyphCode = -1;
+
+    /**
+     * Writes object to ObjectOutputStream.
+     * 
+     * @param out
+     *            ObjectOutputStream.
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Reads object from ObjectInputStream object and set native platform
+     * dependent fields to default values.
+     * 
+     * @param in
+     *            ObjectInputStream object.
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException
+     *             the class not found exception.
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException,
+            ClassNotFoundException {
+        in.defaultReadObject();
+
+        numGlyphs = -1;
+        missingGlyphCode = -1;
+
+    }
+
+    /**
+     * Instantiates a new Font with the specified attributes. The Font will be
+     * created with default attributes if the attribute's parameter is null.
+     * 
+     * @param attributes
+     *            the attributes to be assigned to the new Font, or null.
+     */
+    public Font(Map<? extends Attribute, ?> attributes) {
+        Object currAttr;
+
+        // Default values are taken from the documentation of the Font class.
+        // See Font constructor, decode and getFont sections.
+
+        this.name = "default"; //$NON-NLS-1$
+        this.size = 12;
+        this.pointSize = 12;
+        this.style = Font.PLAIN;
+
+        if (attributes != null) {
+
+            fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
+
+            currAttr = attributes.get(TextAttribute.SIZE);
+            if (currAttr != null) {
+                this.pointSize = ((Float)currAttr).floatValue();
+                this.size = (int)Math.ceil(this.pointSize);
+            }
+
+            currAttr = attributes.get(TextAttribute.POSTURE);
+            if (currAttr != null && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
+                this.style |= Font.ITALIC;
+            }
+
+            currAttr = attributes.get(TextAttribute.WEIGHT);
+            if ((currAttr != null)
+                    && (((Float)currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD).floatValue())) {
+                this.style |= Font.BOLD;
+            }
+
+            currAttr = attributes.get(TextAttribute.FAMILY);
+            if (currAttr != null) {
+                this.name = (String)currAttr;
+            }
+
+            currAttr = attributes.get(TextAttribute.TRANSFORM);
+            if (currAttr != null) {
+                if (currAttr instanceof TransformAttribute) {
+                    this.transformed = !((TransformAttribute)currAttr).getTransform().isIdentity();
+                } else if (currAttr instanceof AffineTransform) {
+                    this.transformed = !((AffineTransform)currAttr).isIdentity();
+                }
+            }
+
+        } else {
+            fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+            fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
+
+            this.transformed = false;
+
+            fRequestedAttributes.put(TextAttribute.FAMILY, name);
+
+            fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+            if ((this.style & Font.BOLD) != 0) {
+                fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+            } else {
+                fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
+            }
+            if ((this.style & Font.ITALIC) != 0) {
+                fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+            } else {
+                fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+            }
+
+        }
+    }
+
+    /**
+     * Instantiates a new Font with the specified name, style and size.
+     * 
+     * @param name
+     *            the name of font.
+     * @param style
+     *            the style of font.
+     * @param size
+     *            the size of font.
+     */
+    public Font(String name, int style, int size) {
+
+        this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
+        this.size = (size >= 0) ? size : 0;
+        this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
+        this.pointSize = this.size;
+
+        fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+
+        fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
+
+        this.transformed = false;
+
+        fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
+        fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+        if ((this.style & Font.BOLD) != 0) {
+            fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+        } else {
+            fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
+        }
+        if ((this.style & Font.ITALIC) != 0) {
+            fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+        } else {
+            fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+        }
+    }
+
+    /**
+     * Returns true if this Font has a glyph for the specified character.
+     * 
+     * @param c
+     *            the character.
+     * @return true if this Font has a glyph for the specified character, false
+     *         otherwise.
+     */
+    public boolean canDisplay(char c) {
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+        return peer.canDisplay(c);
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the the specified
+     * text from the specified start position to the specified limit position.
+     * 
+     * @param text
+     *            the text.
+     * @param start
+     *            the start offset (in the character array).
+     * @param limit
+     *            the limit offset (in the character array).
+     * @return the a character's position in the text that this Font can not
+     *         display, or -1 if this Font can display all characters in this
+     *         text.
+     */
+    public int canDisplayUpTo(char[] text, int start, int limit) {
+        int st = start;
+        int result;
+        while ((st < limit) && canDisplay(text[st])) {
+            st++;
+        }
+
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the the specified
+     * CharacterIterator from the specified start position and the specified
+     * limit position.
+     * 
+     * @param iter
+     *            the CharacterIterator.
+     * @param start
+     *            the start offset.
+     * @param limit
+     *            the limit offset.
+     * @return the a character's position in the CharacterIterator that this
+     *         Font can not display, or -1 if this Font can display all
+     *         characters in this text.
+     */
+    public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+        int st = start;
+        char c = iter.setIndex(start);
+        int result;
+
+        while ((st < limit) && (canDisplay(c))) {
+            st++;
+            c = iter.next();
+        }
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if this Font can display a specified String.
+     * 
+     * @param str
+     *            the String.
+     * @return the a character's position in the String that this Font can not
+     *         display, or -1 if this Font can display all characters in this
+     *         text.
+     */
+    public int canDisplayUpTo(String str) {
+        char[] chars = str.toCharArray();
+        return canDisplayUpTo(chars, 0, chars.length);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on the
+     * Unicode map of this Font.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param chars
+     *            the characters array.
+     * @return the GlyphVector of associating characters to glyphs based on the
+     *         Unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
+        return new AndroidGlyphVector(chars, frc, this, 0);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters contained in the
+     * specified CharacterIterator to glyphs based on the Unicode map of this
+     * Font.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param iter
+     *            the CharacterIterator.
+     * @return the GlyphVector of associating characters contained in the
+     *         specified CharacterIterator to glyphs based on the Unicode map of
+     *         this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, CharacterIterator iter) {
+        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$    
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on the
+     * Unicode map of this Font.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param glyphCodes
+     *            the specified integer array of glyph codes.
+     * @return the GlyphVector of associating characters to glyphs based on the
+     *         Unicode map of this Font.
+     * @throws NotImplementedException
+     *             if this method is not implemented by a subclass.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, int[] glyphCodes)
+            throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on the
+     * Unicode map of this Font.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param str
+     *            the specified String.
+     * @return the GlyphVector of associating characters to glyphs based on the
+     *         Unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, String str) {
+        return new AndroidGlyphVector(str.toCharArray(), frc, this, 0);
+
+    }
+
+    /**
+     * Returns the font style constant value corresponding to one of the font
+     * style names ("BOLD", "ITALIC", "BOLDITALIC"). This method returns
+     * Font.PLAIN if the argument is not one of the predefined style names.
+     * 
+     * @param fontStyleName
+     *            font style name.
+     * @return font style constant value corresponding to the font style name
+     *         specified.
+     */
+    private static int getFontStyle(String fontStyleName) {
+        int result = Font.PLAIN;
+
+        if (fontStyleName.toUpperCase().equals("BOLDITALIC")) { //$NON-NLS-1$
+            result = Font.BOLD | Font.ITALIC;
+        } else if (fontStyleName.toUpperCase().equals("BOLD")) { //$NON-NLS-1$
+            result = Font.BOLD;
+        } else if (fontStyleName.toUpperCase().equals("ITALIC")) { //$NON-NLS-1$
+            result = Font.ITALIC;
+        }
+
+        return result;
+    }
+
+    /**
+     * Decodes the specified string which described the Font. The string should
+     * have the following format: fontname-style-pointsize. The style can be
+     * PLAIN, BOLD, BOLDITALIC, or ITALIC.
+     * 
+     * @param str
+     *            the string which describes the font.
+     * @return the Font from the specified string.
+     */
+    public static Font decode(String str) {
+        // XXX: Documentation doesn't describe all cases, e.g. fonts face names
+        // with
+        // symbols that are suggested as delimiters in the documentation.
+        // In this decode implementation only ***-***-*** format is used with
+        // '-'
+        // as the delimiter to avoid unexpected parse results of font face names
+        // with spaces.
+
+        if (str == null) {
+            return DEFAULT_FONT;
+        }
+
+        StringTokenizer strTokens;
+        String delim = "-"; //$NON-NLS-1$
+        String substr;
+
+        int fontSize = DEFAULT_FONT.size;
+        int fontStyle = DEFAULT_FONT.style;
+        String fontName = DEFAULT_FONT.name;
+
+        strTokens = new StringTokenizer(str.trim(), delim);
+
+        // Font Name
+        if (strTokens.hasMoreTokens()) {
+            fontName = strTokens.nextToken(); // first token is the font name
+        }
+
+        // Font Style or Size (if the style is undefined)
+        if (strTokens.hasMoreTokens()) {
+            substr = strTokens.nextToken();
+
+            try {
+                // if second token is the font size
+                fontSize = Integer.parseInt(substr);
+            } catch (NumberFormatException e) {
+                // then second token is the font style
+                fontStyle = getFontStyle(substr);
+            }
+
+        }
+
+        // Font Size
+        if (strTokens.hasMoreTokens()) {
+            try {
+                fontSize = Integer.parseInt(strTokens.nextToken());
+            } catch (NumberFormatException e) {
+            }
+        }
+
+        return new Font(fontName, fontStyle, fontSize);
+    }
+
+    /**
+     * Performs the specified affine transform to the Font and returns a new
+     * Font.
+     * 
+     * @param trans
+     *            the AffineTransform.
+     * @return the Font object.
+     * @throws IllegalArgumentException
+     *             if affine transform parameter is null.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM, new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font modified so that
+     * the size is the specified size.
+     * 
+     * @param size
+     *            the size of font.
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font modified so that
+     * the style is the specified style.
+     * 
+     * @param style
+     *            the style of font.
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+
+        if ((style & Font.BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & Font.ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font modified to match
+     * the specified style and with the specified affine transform applied to
+     * its glyphs.
+     * 
+     * @param style
+     *            the style of font.
+     * @param trans
+     *            the AffineTransform.
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM, new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font modified so that
+     * the size and style are the specified size and style.
+     * 
+     * @param style
+     *            the style of font.
+     * @param size
+     *            the size of font.
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font object with a new set of font attributes.
+     * 
+     * @param attributes
+     *            the map of attributes.
+     * @return the Font.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(Map<? extends Attribute, ?> attributes) {
+        Attribute[] avalAttributes = this.getAvailableAttributes();
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>)fRequestedAttributes
+                .clone();
+        Object currAttribute;
+        for (Attribute element : avalAttributes) {
+            currAttribute = attributes.get(element);
+            if (currAttribute != null) {
+                derivefRequestedAttributes.put(element, currAttribute);
+            }
+        }
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Compares the specified Object with the current Font.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified Object is an instance of Font with the
+     *         same family, size, and style as this Font, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                Font font = (Font)obj;
+
+                return ((this.style == font.style) && (this.size == font.size)
+                        && this.name.equals(font.name) && (this.pointSize == font.pointSize) && (this
+                        .getTransform()).equals(font.getTransform()));
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Gets the map of font's attributes.
+     * 
+     * @return the map of font's attributes.
+     */
+    @SuppressWarnings("unchecked")
+    public Map<TextAttribute, ?> getAttributes() {
+        return (Map<TextAttribute, ?>)fRequestedAttributes.clone();
+    }
+
+    /**
+     * Gets the keys of all available attributes.
+     * 
+     * @return the keys array of all available attributes.
+     */
+    public Attribute[] getAvailableAttributes() {
+        Attribute[] attrs = {
+                TextAttribute.FAMILY, TextAttribute.POSTURE, TextAttribute.SIZE,
+                TextAttribute.TRANSFORM, TextAttribute.WEIGHT, TextAttribute.SUPERSCRIPT,
+                TextAttribute.WIDTH
+        };
+        return attrs;
+    }
+
+    /**
+     * Gets the baseline for this character.
+     * 
+     * @param c
+     *            the character.
+     * @return the baseline for this character.
+     */
+    public byte getBaselineFor(char c) {
+        // TODO: implement using TT BASE table data
+        return 0;
+    }
+
+    /**
+     * Gets the family name of the Font.
+     * 
+     * @return the family name of the Font.
+     */
+    public String getFamily() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the family name of this Font associated with the specified
+     * locale.
+     * 
+     * @param l
+     *            the locale.
+     * @return the family name of this Font associated with the specified
+     *         locale.
+     */
+    public String getFamily(Locale l) {
+        if (l == null) {
+            // awt.01='{0}' parameter is null
+            throw new NullPointerException(Messages.getString("awt.01", "Locale")); //$NON-NLS-1$ //$NON-NLS-2$ 
+        }
+        return getFamily();
+    }
+
+    /**
+     * Gets a Font with the specified attribute set.
+     * 
+     * @param attributes
+     *            the attributes to be assigned to the new Font.
+     * @return the Font.
+     */
+    public static Font getFont(Map<? extends Attribute, ?> attributes) {
+        Font fnt = (Font)attributes.get(TextAttribute.FONT);
+        if (fnt != null) {
+            return fnt;
+        }
+        return new Font(attributes);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified
+     * name or returns the specified Font if there is no such property.
+     * 
+     * @param sp
+     *            the specified property name.
+     * @param f
+     *            the Font.
+     * @return the Font object from the system properties list with the
+     *         specified name or the specified Font if there is no such
+     *         property.
+     */
+    public static Font getFont(String sp, Font f) {
+        String pr = System.getProperty(sp);
+        if (pr == null) {
+            return f;
+        }
+        return decode(pr);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified
+     * name.
+     * 
+     * @param sp
+     *            the system property name.
+     * @return the Font, or null if there is no such property with the specified
+     *         name.
+     */
+    public static Font getFont(String sp) {
+        return getFont(sp, null);
+    }
+
+    /**
+     * Gets the font name.
+     * 
+     * @return the font name.
+     */
+    public String getFontName() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the font name associated with the specified locale.
+     * 
+     * @param l
+     *            the locale.
+     * @return the font name associated with the specified locale.
+     */
+    public String getFontName(Locale l) {
+        return getFamily();
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param chars
+     *            the chars array.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int start, int end, FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        // FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {
+                fm.getAscent(), fm.getDescent(), fm.getLeading()
+        };
+        return new LineMetricsImpl(chars.length, fmet, null);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param iter
+     *            the CharacterIterator.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator iter, int start, int end,
+            FontRenderContext frc) {
+
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        String resultString;
+        int iterCount;
+
+        iterCount = end - start;
+        if (iterCount < 0) {
+            resultString = ""; //$NON-NLS-1$
+        } else {
+            char[] chars = new char[iterCount];
+            int i = 0;
+            for (char c = iter.setIndex(start); c != CharacterIterator.DONE && (i < iterCount); c = iter
+                    .next()) {
+                chars[i] = c;
+                i++;
+            }
+            resultString = new String(chars);
+        }
+        return this.getLineMetrics(resultString, frc);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str
+     *            the String.
+     * @param frc
+     *            the FontRenderContext.
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc) {
+        // FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {
+                fm.getAscent(), fm.getDescent(), fm.getLeading()
+        };
+        // Log.i("FONT FMET", fmet.toString());
+        return new LineMetricsImpl(str.length(), fmet, null);
+
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str
+     *            the String.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, int start, int end, FontRenderContext frc) {
+        return this.getLineMetrics(str.substring(start, end), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in the specified
+     * FontRenderContext. The logical bounds contains the origin, ascent,
+     * advance, and height.
+     * 
+     * @param ci
+     *            the specified CharacterIterator.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int start, int end,
+            FontRenderContext frc) {
+        int first = ci.getBeginIndex();
+        int finish = ci.getEndIndex();
+        char[] chars;
+
+        if (start < first) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > finish) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        chars = new char[end - start];
+
+        ci.setIndex(start);
+        for (int i = 0; i < chars.length; i++) {
+            chars[i] = ci.current();
+            ci.next();
+        }
+
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in the specified
+     * FontRenderContext. The logical bounds contains the origin, ascent,
+     * advance, and height.
+     * 
+     * @param str
+     *            the specified String.
+     * @param frc
+     *            the FontRenderContext.
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, FontRenderContext frc) {
+        char[] chars = str.toCharArray();
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in the specified
+     * FontRenderContext. The logical bounds contains the origin, ascent,
+     * advance, and height.
+     * 
+     * @param str
+     *            the specified String.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, int start, int end, FontRenderContext frc) {
+
+        return this.getStringBounds((str.substring(start, end)), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in the specified
+     * FontRenderContext. The logical bounds contains the origin, ascent,
+     * advance, and height.
+     * 
+     * @param chars
+     *            the specified character array.
+     * @param start
+     *            the start offset.
+     * @param end
+     *            the end offset.
+     * @param frc
+     *            the FontRenderContext.
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end, FontRenderContext frc) {
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > chars.length) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+
+        final int TRANSFORM_MASK = AffineTransform.TYPE_GENERAL_ROTATION
+                | AffineTransform.TYPE_GENERAL_TRANSFORM;
+        Rectangle2D bounds;
+
+        AffineTransform transform = getTransform();
+
+        // XXX: for transforms where an angle between basis vectors is not 90
+        // degrees Rectanlge2D class doesn't fit as Logical bounds.
+        if ((transform.getType() & TRANSFORM_MASK) == 0) {
+            int width = 0;
+            for (int i = start; i < end; i++) {
+                width += peer.charWidth(chars[i]);
+            }
+            // LineMetrics nlm = peer.getLineMetrics();
+
+            LineMetrics nlm = getLineMetrics(chars, start, end, frc);
+
+            bounds = transform.createTransformedShape(
+                    new Rectangle2D.Float(0, -nlm.getAscent(), width, nlm.getHeight()))
+                    .getBounds2D();
+        } else {
+            int len = end - start;
+            char[] subChars = new char[len];
+            System.arraycopy(chars, start, subChars, 0, len);
+            bounds = createGlyphVector(frc, subChars).getLogicalBounds();
+        }
+        return bounds;
+    }
+
+    /**
+     * Gets the character's maximum bounds as defined in the specified
+     * FontRenderContext.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @return the character's maximum bounds.
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$ 
+        }
+
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+
+        Rectangle2D bounds = peer.getMaxCharBounds(frc);
+        AffineTransform transform = getTransform();
+        // !! Documentation doesn't describe meaning of max char bounds
+        // for the fonts that have rotate transforms. For all transforms
+        // returned bounds are the bounds of transformed maxCharBounds
+        // Rectangle2D that corresponds to the font with identity transform.
+        // TODO: resolve this issue to return correct bounds
+        bounds = transform.createTransformedShape(bounds).getBounds2D();
+
+        return bounds;
+    }
+
+    /**
+     * Returns a new GlyphVector object performing full layout of the text.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param chars
+     *            the character array to be layout.
+     * @param start
+     *            the start offset of the text to use for the GlyphVector.
+     * @param count
+     *            the count of characters to use for the GlyphVector.
+     * @param flags
+     *            the flag indicating text direction: LAYOUT_RIGHT_TO_LEFT,
+     *            LAYOUT_LEFT_TO_RIGHT.
+     * @return the GlyphVector.
+     */
+    public GlyphVector layoutGlyphVector(FontRenderContext frc, char[] chars, int start, int count,
+            int flags) {
+        // TODO: implement method for bidirectional text.
+        // At the moment only LTR and RTL texts supported.
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.95", //$NON-NLS-1$
+                    start));
+        }
+
+        if (count < 0) {
+            // awt.98=Wrong count value, can not be negative: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.98", //$NON-NLS-1$
+                    count));
+        }
+
+        if (start + count > chars.length) {
+            // awt.99=Wrong [start + count] is out of range: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.99", //$NON-NLS-1$
+                    (start + count)));
+        }
+
+        char[] out = new char[count];
+        System.arraycopy(chars, start, out, 0, count);
+
+        return new CommonGlyphVector(out, frc, this, flags);
+    }
+
+    /**
+     * Returns the String representation of this Font.
+     * 
+     * @return the String representation of this Font.
+     */
+    @Override
+    public String toString() {
+        String stl = "plain"; //$NON-NLS-1$
+        String result;
+
+        if (this.isBold() && this.isItalic()) {
+            stl = "bolditalic"; //$NON-NLS-1$
+        }
+        if (this.isBold() && !this.isItalic()) {
+            stl = "bold"; //$NON-NLS-1$
+        }
+
+        if (!this.isBold() && this.isItalic()) {
+            stl = "italic"; //$NON-NLS-1$
+        }
+
+        result = this.getClass().getName() + "[family=" + this.getFamily() + //$NON-NLS-1$
+                ",name=" + this.name + //$NON-NLS-1$
+                ",style=" + stl + //$NON-NLS-1$
+                ",size=" + this.size + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        return result;
+    }
+
+    /**
+     * Gets the postscript name of this Font.
+     * 
+     * @return the postscript name of this Font.
+     */
+    public String getPSName() {
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+        return peer.getPSName();
+    }
+
+    /**
+     * Gets the logical name of this Font.
+     * 
+     * @return the logical name of this Font.
+     */
+    public String getName() {
+        return (this.name);
+    }
+
+    /**
+     * Gets the peer of this Font.
+     * 
+     * @return the peer of this Font.
+     * @deprecated Font rendering is platform independent now.
+     */
+    @Deprecated
+    public java.awt.peer.FontPeer getPeer() {
+        if (fontPeer == null) {
+            fontPeer = (FontPeerImpl)Toolkit.getDefaultToolkit().getGraphicsFactory().getFontPeer(
+                    this);
+        }
+        return fontPeer;
+
+    }
+
+    /**
+     * Gets the transform acting on this Font (from the Font's attributes).
+     * 
+     * @return the transformation of this Font.
+     */
+    public AffineTransform getTransform() {
+        Object transform = fRequestedAttributes.get(TextAttribute.TRANSFORM);
+
+        if (transform != null) {
+            if (transform instanceof TransformAttribute) {
+                return ((TransformAttribute)transform).getTransform();
+            }
+            if (transform instanceof AffineTransform) {
+                return new AffineTransform((AffineTransform)transform);
+            }
+        } else {
+            transform = new AffineTransform();
+        }
+        return (AffineTransform)transform;
+
+    }
+
+    /**
+     * Checks if this font is transformed or not.
+     * 
+     * @return true, if this font is transformed, false otherwise.
+     */
+    public boolean isTransformed() {
+        return this.transformed;
+    }
+
+    /**
+     * Checks if this font has plain style or not.
+     * 
+     * @return true, if this font has plain style, false otherwise.
+     */
+    public boolean isPlain() {
+        return (this.style == PLAIN);
+    }
+
+    /**
+     * Checks if this font has italic style or not.
+     * 
+     * @return true, if this font has italic style, false otherwise.
+     */
+    public boolean isItalic() {
+        return (this.style & ITALIC) != 0;
+    }
+
+    /**
+     * Checks if this font has bold style or not.
+     * 
+     * @return true, if this font has bold style, false otherwise.
+     */
+    public boolean isBold() {
+        return (this.style & BOLD) != 0;
+    }
+
+    /**
+     * Returns true if this Font has uniform line metrics.
+     * 
+     * @return true if this Font has uniform line metrics, false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+        return peer.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns hash code of this Font object.
+     * 
+     * @return the hash code of this Font object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(this.name);
+        hash.append(this.style);
+        hash.append(this.size);
+
+        return hash.hashCode();
+    }
+
+    /**
+     * Gets the style of this Font.
+     * 
+     * @return the style of this Font.
+     */
+    public int getStyle() {
+        return this.style;
+    }
+
+    /**
+     * Gets the size of this Font.
+     * 
+     * @return the size of this Font.
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Gets the number of glyphs for this Font.
+     * 
+     * @return the number of glyphs for this Font.
+     */
+    public int getNumGlyphs() {
+        if (numGlyphs == -1) {
+            FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+            this.numGlyphs = peer.getNumGlyphs();
+        }
+        return this.numGlyphs;
+    }
+
+    /**
+     * Gets the glyphCode which is used as default glyph when this Font does not
+     * have a glyph for a specified Unicode.
+     * 
+     * @return the missing glyph code.
+     */
+    public int getMissingGlyphCode() {
+        if (missingGlyphCode == -1) {
+            FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+            this.missingGlyphCode = peer.getMissingGlyphCode();
+        }
+        return this.missingGlyphCode;
+    }
+
+    /**
+     * Gets the float value of font's size.
+     * 
+     * @return the float value of font's size.
+     */
+    public float getSize2D() {
+        return this.pointSize;
+    }
+
+    /**
+     * Gets the italic angle of this Font.
+     * 
+     * @return the italic angle of this Font.
+     */
+    public float getItalicAngle() {
+        FontPeerImpl peer = (FontPeerImpl)this.getPeer();
+        return peer.getItalicAngle();
+    }
+
+    /**
+     * Creates the font with the specified font format and font file.
+     * 
+     * @param fontFormat
+     *            the font format.
+     * @param fontFile
+     *            the file object represented the input data for the font.
+     * @return the Font.
+     * @throws FontFormatException
+     *             is thrown if fontFile does not contain the required font
+     *             tables for the specified format.
+     * @throws IOException
+     *             signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, File fontFile) throws FontFormatException,
+            IOException {
+        // ???AWT not supported
+        InputStream is = new FileInputStream(fontFile);
+        try {
+            return createFont(fontFormat, is);
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * Creates the font with the specified font format and input stream.
+     * 
+     * @param fontFormat
+     *            the font format.
+     * @param fontStream
+     *            the input stream represented input data for the font.
+     * @return the Font.
+     * @throws FontFormatException
+     *             is thrown if fontFile does not contain the required font
+     *             tables for the specified format.
+     * @throws IOException
+     *             signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, InputStream fontStream)
+            throws FontFormatException, IOException {
+
+        // ???AWT not supported
+
+        BufferedInputStream buffStream;
+        int bRead = 0;
+        int size = 8192;
+        // memory page size, for the faster reading
+        byte buf[] = new byte[size];
+
+        if (fontFormat != TRUETYPE_FONT) { // awt.9A=Unsupported font format
+            throw new IllegalArgumentException(Messages.getString("awt.9A")); //$NON-NLS-1$ 
+        }
+
+        /* Get font file in system-specific directory */
+
+        File fontFile = Toolkit.getDefaultToolkit().getGraphicsFactory().getFontManager()
+                .getTempFontFile();
+
+        // BEGIN android-modified
+        buffStream = new BufferedInputStream(fontStream, 8192);
+        // END android-modified
+        FileOutputStream fOutStream = new FileOutputStream(fontFile);
+
+        bRead = buffStream.read(buf, 0, size);
+
+        while (bRead != -1) {
+            fOutStream.write(buf, 0, bRead);
+            bRead = buffStream.read(buf, 0, size);
+        }
+
+        buffStream.close();
+        fOutStream.close();
+
+        Font font = null;
+
+        font = Toolkit.getDefaultToolkit().getGraphicsFactory().embedFont(
+                fontFile.getAbsolutePath());
+        if (font == null) { // awt.9B=Can't create font - bad font data
+            throw new FontFormatException(Messages.getString("awt.9B")); //$NON-NLS-1$
+        }
+        return font;
+    }
+
+}
diff --git a/awt/java/awt/FontFormatException.java b/awt/java/awt/FontFormatException.java
new file mode 100644
index 0000000..806711a
--- /dev/null
+++ b/awt/java/awt/FontFormatException.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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The FontFormatException class is used to provide notification and information
+ * that font can't be created.
+ * 
+ * @since Android 1.0
+ */
+public class FontFormatException extends Exception {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -4481290147811361272L;
+
+    /**
+     * Instantiates a new font format exception with detailed message.
+     * 
+     * @param reason
+     *            the detailed message.
+     */
+    public FontFormatException(String reason) {
+        super(reason);
+    }
+
+}
diff --git a/awt/java/awt/FontMetrics.java b/awt/java/awt/FontMetrics.java
new file mode 100644
index 0000000..9082626
--- /dev/null
+++ b/awt/java/awt/FontMetrics.java
@@ -0,0 +1,466 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The FontMetrics class contains information about the rendering of a
+ * particular font on a particular screen.
+ * <p>
+ * Each character in the Font has three values that help define where to place
+ * it: an ascent, a descent, and an advance. The ascent is the distance the
+ * character extends above the baseline. The descent is the distance the
+ * character extends below the baseline. The advance width defines the position
+ * at which the next character should be placed.
+ * <p>
+ * An array of characters or a string has an ascent, a descent, and an advance
+ * width too. The ascent or descent of the array is specified by the maximum
+ * ascent or descent of the characters in the array. The advance width is the
+ * sum of the advance widths of each of the characters in the character array.
+ * </p>
+ * 
+ * @since Android 1.0
+ */
+public abstract class FontMetrics implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 1681126225205050147L;
+
+    /**
+     * The font from which the FontMetrics is created.
+     */
+    protected Font font;
+
+    /**
+     * Instantiates a new font metrics from the specified Font.
+     * 
+     * @param fnt
+     *            the Font.
+     */
+    protected FontMetrics(Font fnt) {
+        this.font = fnt;
+    }
+
+    /**
+     * Returns the String representation of this FontMetrics.
+     * 
+     * @return the string.
+     */
+    @Override
+    public String toString() {
+        return this.getClass().getName() + "[font=" + this.getFont() + //$NON-NLS-1$
+                "ascent=" + this.getAscent() + //$NON-NLS-1$
+                ", descent=" + this.getDescent() + //$NON-NLS-1$
+                ", height=" + this.getHeight() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the font associated with this FontMetrics.
+     * 
+     * @return the font associated with this FontMetrics.
+     */
+    public Font getFont() {
+        return font;
+    }
+
+    /**
+     * Gets the height of the text line in this Font.
+     * 
+     * @return the height of the text line in this Font.
+     */
+    public int getHeight() {
+        return this.getAscent() + this.getDescent() + this.getLeading();
+    }
+
+    /**
+     * Gets the font ascent of the Font associated with this FontMetrics. The
+     * font ascent is the distance from the font's baseline to the top of most
+     * alphanumeric characters.
+     * 
+     * @return the ascent of the Font associated with this FontMetrics.
+     */
+    public int getAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the font descent of the Font associated with this FontMetrics. The
+     * font descent is the distance from the font's baseline to the bottom of
+     * most alphanumeric characters with descenders.
+     * 
+     * @return the descent of the Font associated with this FontMetrics.
+     */
+    public int getDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the leading of the Font associated with this FontMetrics.
+     * 
+     * @return the leading of the Font associated with this FontMetrics.
+     */
+    public int getLeading() {
+        return 0;
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified CharacterIterator in the
+     * specified Graphics.
+     * 
+     * @param ci
+     *            the CharacterIterator.
+     * @param beginIndex
+     *            the offset.
+     * @param limit
+     *            the number of characters to be used.
+     * @param context
+     *            the Graphics.
+     * @return the LineMetrics object for the specified CharacterIterator in the
+     *         specified Graphics.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit,
+            Graphics context) {
+        return font.getLineMetrics(ci, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String in the specified
+     * Graphics.
+     * 
+     * @param str
+     *            the String.
+     * @param context
+     *            the Graphics.
+     * @return the LineMetrics object for the specified String in the specified
+     *         Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, Graphics context) {
+        return font.getLineMetrics(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified character array in the
+     * specified Graphics.
+     * 
+     * @param chars
+     *            the character array.
+     * @param beginIndex
+     *            the offset of array.
+     * @param limit
+     *            the number of characters to be used.
+     * @param context
+     *            the Graphics.
+     * @return the LineMetrics object for the specified character array in the
+     *         specified Graphics.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, Graphics context) {
+        return font.getLineMetrics(chars, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String in the specified
+     * Graphics.
+     * 
+     * @param str
+     *            the String.
+     * @param beginIndex
+     *            the offset.
+     * @param limit
+     *            the number of characters to be used.
+     * @param context
+     *            the Graphics.
+     * @return the LineMetrics object for the specified String in the specified
+     *         Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, int beginIndex, int limit, Graphics context) {
+        return font.getLineMetrics(str, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Returns the character's maximum bounds in the specified Graphics context.
+     * 
+     * @param context
+     *            the Graphics context.
+     * @return the character's maximum bounds in the specified Graphics context.
+     */
+    public Rectangle2D getMaxCharBounds(Graphics context) {
+        return this.font.getMaxCharBounds(this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified CharacterIterator in the specified
+     * Graphics context.
+     * 
+     * @param ci
+     *            the CharacterIterator.
+     * @param beginIndex
+     *            the begin offset of the array.
+     * @param limit
+     *            the number of characters.
+     * @param context
+     *            the Graphics.
+     * @return the bounds of the specified CharacterIterator in the specified
+     *         Graphics context.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(ci, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String in the specified Graphics
+     * context.
+     * 
+     * @param str
+     *            the String.
+     * @param beginIndex
+     *            the begin offset of the array.
+     * @param limit
+     *            the number of characters.
+     * @param context
+     *            the Graphics.
+     * @return the bounds of the specified String in the specified Graphics
+     *         context.
+     */
+    public Rectangle2D getStringBounds(String str, int beginIndex, int limit, Graphics context) {
+        return font.getStringBounds(str, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified characters array in the specified
+     * Graphics context.
+     * 
+     * @param chars
+     *            the characters array.
+     * @param beginIndex
+     *            the begin offset of the array.
+     * @param limit
+     *            the number of characters.
+     * @param context
+     *            the Graphics.
+     * @return the bounds of the specified characters array in the specified
+     *         Graphics context.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit, Graphics context) {
+        return font.getStringBounds(chars, beginIndex, limit, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String in the specified Graphics
+     * context.
+     * 
+     * @param str
+     *            the String.
+     * @param context
+     *            the Graphics.
+     * @return the bounds of the specified String in the specified Graphics
+     *         context.
+     */
+    public Rectangle2D getStringBounds(String str, Graphics context) {
+        return font.getStringBounds(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Checks if the Font has uniform line metrics or not. The Font can contain
+     * characters of other fonts for covering character set. In this case the
+     * Font isn't uniform.
+     * 
+     * @return true, if the Font has uniform line metrics, false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        return this.font.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost point on
+     * the string's baseline showing the specified array of bytes in this Font.
+     * 
+     * @param data
+     *            the array of bytes to be measured.
+     * @param off
+     *            the start offset.
+     * @param len
+     *            the number of bytes to be measured.
+     * @return the advance width of the array.
+     */
+    public int bytesWidth(byte[] data, int off, int len) {
+        int width = 0;
+        if ((off >= data.length) || (off < 0)) {
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off + len > data.length)) {
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off + len; i++) {
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost point on
+     * the string's baseline showing the specified array of characters in this
+     * Font.
+     * 
+     * @param data
+     *            the array of characters to be measured.
+     * @param off
+     *            the start offset.
+     * @param len
+     *            the number of bytes to be measured.
+     * @return the advance width of the array.
+     */
+    public int charsWidth(char[] data, int off, int len) {
+        int width = 0;
+        if ((off >= data.length) || (off < 0)) {
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off + len > data.length)) {
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off + len; i++) {
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost point of
+     * the specified character in this Font.
+     * 
+     * @param ch
+     *            the specified Unicode point code of character to be measured.
+     * @return the advance width of the character.
+     */
+    public int charWidth(int ch) {
+        return 0;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost point of
+     * the specified character in this Font.
+     * 
+     * @param ch
+     *            the specified character to be measured.
+     * @return the advance width of the character.
+     */
+    public int charWidth(char ch) {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum advance width of character in this Font.
+     * 
+     * @return the maximum advance width of character in this Font.
+     */
+    public int getMaxAdvance() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font ascent of the Font associated with this
+     * FontMetrics.
+     * 
+     * @return the maximum font ascent of the Font associated with this
+     *         FontMetrics.
+     */
+    public int getMaxAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     * @deprecated Replaced by getMaxDescent() method.
+     */
+    @Deprecated
+    public int getMaxDecent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     */
+    public int getMaxDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the advance widths of the characters in the Font.
+     * 
+     * @return the advance widths of the characters in the Font.
+     */
+    public int[] getWidths() {
+        return null;
+    }
+
+    /**
+     * Returns the advance width for the specified String in this Font.
+     * 
+     * @param str
+     *            String to be measured.
+     * @return the the advance width for the specified String in this Font.
+     */
+    public int stringWidth(String str) {
+        return 0;
+    }
+
+    /**
+     * Returns a FontRenderContext instance of the Graphics context specified.
+     * 
+     * @param context
+     *            the specified Graphics context.
+     * @return a FontRenderContext of the specified Graphics context.
+     */
+    private FontRenderContext getFRCFromGraphics(Graphics context) {
+        FontRenderContext frc;
+        if (context instanceof Graphics2D) {
+            frc = ((Graphics2D)context).getFontRenderContext();
+        } else {
+            frc = new FontRenderContext(null, false, false);
+        }
+
+        return frc;
+    }
+}
diff --git a/awt/java/awt/GradientPaint.java b/awt/java/awt/GradientPaint.java
new file mode 100644
index 0000000..3b32ef5
--- /dev/null
+++ b/awt/java/awt/GradientPaint.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.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GradientPaint class defines a way to fill a Shape with a linear color
+ * gradient pattern.
+ * <p>
+ * The GradientPaint's fill pattern is determined by two points and two colors,
+ * plus the cyclic mode option. Each of the two points is painted with its
+ * corresponding color, and on the line segment connecting the two points, the
+ * color is proportionally changed between the two colors. For points on the
+ * same line which are not between the two specified points (outside of the
+ * connecting segment) their color is determined by the cyclic mode option. If
+ * the mode is cyclic, then the rest of the line repeats the color pattern of
+ * the connecting segment, cycling back and forth between the two colors. If
+ * not, the mode is acyclic which means that all points on the line outside the
+ * connecting line segment are given the same color as the closest of the two
+ * specified points.
+ * <p>
+ * The color of points that are not on the line connecting the two specified
+ * points are given by perpendicular projection: by taking the set of lines
+ * perpendicular to the connecting line and for each one, the whole line is
+ * colored with the same color.
+ * 
+ * @since Android 1.0
+ */
+public class GradientPaint implements Paint {
+
+    /**
+     * The start point color.
+     */
+    Color color1;
+
+    /**
+     * The end color point.
+     */
+    Color color2;
+
+    /**
+     * The location of the start point.
+     */
+    Point2D point1;
+
+    /**
+     * The location of the end point.
+     */
+    Point2D point2;
+
+    /**
+     * The indicator of cycle filling. If TRUE filling repeated outside points
+     * stripe, if FALSE solid color filling outside.
+     */
+    boolean cyclic;
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode.
+     * 
+     * @param point1
+     *            the first specified point.
+     * @param color1
+     *            the Color of the first specified point.
+     * @param point2
+     *            the second specified point.
+     * @param color2
+     *            the Color of the second specified point.
+     * @param cyclic
+     *            the cyclic mode - true if the gradient pattern should cycle
+     *            repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
+        if (point1 == null || point2 == null) {
+            // awt.6D=Point is null
+            throw new NullPointerException(Messages.getString("awt.6D")); //$NON-NLS-1$
+        }
+        if (color1 == null || color2 == null) {
+            // awt.6E=Color is null
+            throw new NullPointerException(Messages.getString("awt.6E")); //$NON-NLS-1$
+        }
+
+        this.point1 = point1;
+        this.point2 = point2;
+        this.color1 = color1;
+        this.color2 = color2;
+        this.cyclic = cyclic;
+    }
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode; points are
+     * specified by coordinates.
+     * 
+     * @param x1
+     *            the X coordinate of the first point.
+     * @param y1
+     *            the Y coordinate of the first point.
+     * @param color1
+     *            the color of the first point.
+     * @param x2
+     *            the X coordinate of the second point.
+     * @param y2
+     *            the Y coordinate of the second point.
+     * @param color2
+     *            the color of the second point.
+     * @param cyclic
+     *            the cyclic mode - true if the gradient pattern should cycle
+     *            repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2,
+            boolean cyclic) {
+        this(new Point2D.Float(x1, y1), color1, new Point2D.Float(x2, y2), color2, cyclic);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint; points are specified by
+     * coordinates.
+     * 
+     * @param x1
+     *            the X coordinate of the first point.
+     * @param y1
+     *            the Y coordinate of the first point.
+     * @param color1
+     *            the color of the first point.
+     * @param x2
+     *            the X coordinate of the second point.
+     * @param y2
+     *            the Y coordinate of the second point.
+     * @param color2
+     *            the color of the second point.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2) {
+        this(x1, y1, color1, x2, y2, color2, false);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint.
+     * 
+     * @param point1
+     *            the first specified point.
+     * @param color1
+     *            the Color of the first specified point.
+     * @param point2
+     *            the second specified point.
+     * @param color2
+     *            the Color of the second specified point.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2) {
+        this(point1, color1, point2, color2, false);
+    }
+
+    /**
+     * Creates PaintContext for a color pattern generating.
+     * 
+     * @param cm
+     *            the ColorModel of the Paint data.
+     * @param deviceBounds
+     *            the bounding Rectangle of graphics primitives being rendered
+     *            in the device space.
+     * @param userBounds
+     *            the bounding Rectangle of graphics primitives being rendered
+     *            in the user space.
+     * @param t
+     *            the AffineTransform from user space into device space.
+     * @param hints
+     *            the RrenderingHints object.
+     * @return the PaintContext for color pattern generating.
+     * @see java.awt.Paint#createContext(java.awt.image.ColorModel,
+     *      java.awt.Rectangle, java.awt.geom.Rectangle2D,
+     *      java.awt.geom.AffineTransform, java.awt.RenderingHints)
+     */
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform t, RenderingHints hints) {
+        return new GradientPaintContext(cm, t, point1, color1, point2, color2, cyclic);
+    }
+
+    /**
+     * Gets the color of the first point.
+     * 
+     * @return the color of the first point.
+     */
+    public Color getColor1() {
+        return color1;
+    }
+
+    /**
+     * Gets the color of the second point.
+     * 
+     * @return the color of the second point.
+     */
+    public Color getColor2() {
+        return color2;
+    }
+
+    /**
+     * Gets the first point.
+     * 
+     * @return the Point object - the first point.
+     */
+    public Point2D getPoint1() {
+        return point1;
+    }
+
+    /**
+     * Gets the second point.
+     * 
+     * @return the Point object - the second point.
+     */
+    public Point2D getPoint2() {
+        return point2;
+    }
+
+    /**
+     * Gets the transparency mode for the GradientPaint.
+     * 
+     * @return the transparency mode for the GradientPaint.
+     * @see java.awt.Transparency#getTransparency()
+     */
+    public int getTransparency() {
+        int a1 = color1.getAlpha();
+        int a2 = color2.getAlpha();
+        return (a1 == 0xFF && a2 == 0xFF) ? OPAQUE : TRANSLUCENT;
+    }
+
+    /**
+     * Returns the GradientPaint mode: true for cyclic mode, false for acyclic
+     * mode.
+     * 
+     * @return true if the gradient cycles repeatedly between the two colors;
+     *         false otherwise.
+     */
+    public boolean isCyclic() {
+        return cyclic;
+    }
+}
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java
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..2d6e79f
--- /dev/null
+++ b/awt/java/awt/Graphics.java
@@ -0,0 +1,924 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * The abstract Graphics class allows applications to draw on a screen or other
+ * rendering target. There are several properties which define rendering
+ * options: origin point, clipping area, color, font. <br>
+ * <br>
+ * The origin point specifies the beginning of the clipping area coordinate
+ * system. All coordinates used in rendering operations are computed with
+ * respect to this point. The clipping area defines the boundaries where
+ * rendering operations can be performed. Rendering operations can't modify
+ * pixels outside of the clipping area. <br>
+ * <br>
+ * The draw and fill methods allow applications to drawing shapes, text, images
+ * with specified font and color options in the specified part of the screen.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Graphics {
+
+    // Constructors
+
+    /**
+     * Instantiates a new Graphics. This constructor is default for Graphics and
+     * can not be called directly.
+     */
+    protected Graphics() {
+    }
+
+    // Public methods
+
+    /**
+     * Creates a copy of the Graphics object with a new origin and a new
+     * specified clip area. The new clip area is the rectangle defined by the
+     * origin point with coordinates X,Y and the given width and height. The
+     * coordinates of all subsequent rendering operations will be computed with
+     * respect to the new origin and can be performed only within the range of
+     * the clipping area dimensions.
+     * 
+     * @param x
+     *            the X coordinate of the original point.
+     * @param y
+     *            the Y coordinate of the original point.
+     * @param width
+     *            the width of clipping area.
+     * @param height
+     *            the height of clipping area.
+     * @return the Graphics object with new origin point and clipping area.
+     */
+    public Graphics create(int x, int y, int width, int height) {
+        Graphics res = create();
+        res.translate(x, y);
+        res.clipRect(0, 0, width, height);
+        return res;
+    }
+
+    /**
+     * Draws the highlighted outline of a rectangle.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     * @param raised
+     *            a boolean value that determines whether the rectangle is drawn
+     *            as raised or indented.
+     */
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width+1)x(height+1). Stroke and paint
+        // attributes of
+        // the Graphics2D should be reset to the default values.
+        // fillRect is used instead of drawLine to bypass stroke
+        // reset/set and rasterization.
+
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y + 1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x + width, y, 1, height);
+        fillRect(x + 1, y + height, width, 1);
+    }
+
+    /**
+     * Draws the text represented by byte array. This method uses the current
+     * font and color for rendering.
+     * 
+     * @param bytes
+     *            the byte array which contains the text to be drawn.
+     * @param off
+     *            the offset within the byte array of the text to be drawn.
+     * @param len
+     *            the number of bytes of text to draw.
+     * @param x
+     *            the X coordinate where the text is to be drawn.
+     * @param y
+     *            the Y coordinate where the text is to be drawn.
+     */
+    public void drawBytes(byte[] bytes, int off, int len, int x, int y) {
+        drawString(new String(bytes, off, len), x, y);
+    }
+
+    /**
+     * Draws the text represented by character array. This method uses the
+     * current font and color for rendering.
+     * 
+     * @param chars
+     *            the character array.
+     * @param off
+     *            the offset within the character array of the text to be drawn.
+     * @param len
+     *            the number of characters which will be drawn.
+     * @param x
+     *            the X coordinate where the text is to be drawn.
+     * @param y
+     *            the Y coordinate where the text is to be drawn.
+     */
+    public void drawChars(char[] chars, int off, int len, int x, int y) {
+        drawString(new String(chars, off, len), x, y);
+    }
+
+    /**
+     * Draws the outline of a polygon which is defined by Polygon object.
+     * 
+     * @param p
+     *            the Polygon object.
+     */
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Draws the rectangle with the specified width and length and top left
+     * corner coordinates.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     */
+    public void drawRect(int x, int y, int width, int height) {
+        int[] xpoints = {
+                x, x, x + width, x + width
+        };
+        int[] ypoints = {
+                y, y + height, y + height, y
+        };
+
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    /**
+     * Fills the highlighted outline of a rectangle.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     * @param raised
+     *            a boolean value that determines whether the rectangle is drawn
+     *            as raised or indented.
+     */
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width)x(height), same as fillRect.
+        // Stroke and paint attributes of the Graphics2D should be reset
+        // to the default values. fillRect is used instead of drawLine to
+        // bypass stroke reset/set and line rasterization.
+
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x + 1, y + 1, width - 1, height - 1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y + 1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x + width, y, 1, height);
+        fillRect(x + 1, y + height, width, 1);
+    }
+
+    /**
+     * Fills the polygon with the current color.
+     * 
+     * @param p
+     *            the Polygon object.
+     */
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Disposes of the Graphics.
+     */
+    @Override
+    public void finalize() {
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle and copies it
+     * to an existing rectangle.
+     * 
+     * @param r
+     *            a Rectangle object where the current clipping area bounds are
+     *            to be copied.
+     * @return the bounds of the current clipping area.
+     */
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+
+        if (clip != null) {
+            // TODO: Can we get shape bounds without creating Rectangle object?
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+
+        return r;
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     * 
+     * @return a Rectangle object.
+     * @deprecated Use {@link #getClipBounds()}
+     */
+    @Deprecated
+    public Rectangle getClipRect() {
+        return getClipBounds();
+    }
+
+    /**
+     * Gets the font metrics of the current font. The font metrics object
+     * contains information about the rendering of a particular font.
+     * 
+     * @return the font metrics of current font.
+     */
+    public FontMetrics getFontMetrics() {
+        return getFontMetrics(getFont());
+    }
+
+    /**
+     * Determines whether or not the specified rectangle intersects the current
+     * clipping area.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     * @return true, if the specified rectangle intersects the current clipping
+     *         area, false otherwise.
+     */
+    public boolean hitClip(int x, int y, int width, int height) {
+        // TODO: Create package private method Rectangle.intersects(int, int,
+        // int, int);
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+
+    /**
+     * Returns string which represents this Graphics object.
+     * 
+     * @return the string which represents this Graphics object.
+     */
+    @Override
+    public String toString() {
+        // TODO: Think about string representation of Graphics.
+        return "Graphics"; //$NON-NLS-1$
+    }
+
+    // Abstract methods
+
+    /**
+     * Clears the specified rectangle. This method fills specified rectangle
+     * with background color.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     */
+    public abstract void clearRect(int x, int y, int width, int height);
+
+    /**
+     * Intersects the current clipping area with a new rectangle. If the current
+     * clipping area is not defined, the rectangle becomes a new clipping area.
+     * Rendering operations are only allowed within the new the clipping area.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle for intersection.
+     * @param y
+     *            the Y coordinate of the rectangle for intersection.
+     * @param width
+     *            the width of the rectangle for intersection.
+     * @param height
+     *            the height of the rectangle for intersection.
+     */
+    public abstract void clipRect(int x, int y, int width, int height);
+
+    /**
+     * Copies the rectangle area to another area specified by a distance (dx,
+     * dy) from the original rectangle's location. Positive dx and dy values
+     * give a new location defined by translation to the right and down from the
+     * original location, negative dx and dy values - to the left and up.
+     * 
+     * @param sx
+     *            the X coordinate of the rectangle which will be copied.
+     * @param sy
+     *            the Y coordinate of the rectangle which will be copied.
+     * @param width
+     *            the width of the rectangle which will be copied.
+     * @param height
+     *            the height of the rectangle which will be copied.
+     * @param dx
+     *            the horizontal distance from the source rectangle's location
+     *            to the copy's location.
+     * @param dy
+     *            the vertical distance from the source rectangle's location to
+     *            the copy's location.
+     */
+    public abstract void copyArea(int sx, int sy, int width, int height, int dx, int dy);
+
+    /**
+     * Creates a new copy of this Graphics.
+     * 
+     * @return a new Graphics context which is a copy of this Graphics.
+     */
+    public abstract Graphics create();
+
+    /**
+     * Disposes of the Graphics. This Graphics object can not be used after
+     * calling this method.
+     */
+    public abstract void dispose();
+
+    /**
+     * Draws the arc covering the specified rectangle and using the current
+     * color. The rectangle is defined by the origin point (X, Y) and dimensions
+     * (width and height). The arc center is the the center of specified
+     * rectangle. The angle origin is 3 o'clock position, the positive angle is
+     * counted as a counter-clockwise rotation, the negative angle is counted as
+     * clockwise rotation.
+     * 
+     * @param x
+     *            the X origin coordinate of the rectangle which scales the arc.
+     * @param y
+     *            the Y origin coordinate of the rectangle which scales the arc.
+     * @param width
+     *            the width of the rectangle which scales the arc.
+     * @param height
+     *            the height of the rectangle which scales the arc.
+     * @param sa
+     *            start angle - the origin angle of arc.
+     * @param ea
+     *            arc angle - the angular arc value relative to the start angle.
+     */
+    public abstract void drawArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Draws the specified image with the defined background color. The top left
+     * corner of image will be drawn at point (x, y) in current coordinate
+     * system. The image loading process notifies the specified Image Observer.
+     * This method returns true if the image has loaded, otherwise it returns
+     * false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param x
+     *            the X coordinate of the image top left corner.
+     * @param y
+     *            the Y coordinate of the image top left corner.
+     * @param bgcolor
+     *            the background color.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, false
+     *         otherwise.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Draws the specified image. The top left corner of image will be drawn at
+     * point (x, y) in current coordinate system. The image loading process
+     * notifies the specified Image Observer. This method returns true if the
+     * image has loaded, otherwise it returns false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param x
+     *            the X coordinate of the image top left corner.
+     * @param y
+     *            the Y coordinate of the image top left corner.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, otherwise
+     *         false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and draws it
+     * with the defined background color. The top left corner of the image will
+     * be drawn at the point (x, y) in current coordinate system. The non-opaque
+     * pixels will be drawn in the background color. The image loading process
+     * notifies the specified Image Observer. This method returns true if the
+     * image has loaded, otherwise it returns false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param x
+     *            the X coordinate of the image's top left corner.
+     * @param y
+     *            the Y coordinate of the image's top left corner.
+     * @param width
+     *            the width of rectangle which scales the image.
+     * @param height
+     *            the height of rectangle which scales the image.
+     * @param bgcolor
+     *            the background color.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, otherwise
+     *         false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height,
+            Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and draws
+     * it. The top left corner of the image will be drawn at the point (x, y) in
+     * current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image has
+     * loaded, otherwise it returns false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param x
+     *            the X coordinate of the image top left corner.
+     * @param y
+     *            the Y coordinate of the image top left corner.
+     * @param width
+     *            the width of rectangle which scales the image.
+     * @param height
+     *            the height of rectangle which scales the image.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, otherwise
+     *         false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height,
+            ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle
+     * area defined by its corners coordinates and draws the sub-image with the
+     * specified background color. The sub-image to be drawn is defined by its
+     * top left corner coordinates (sx1, sy1) and bottom right corner
+     * coordinates (sx2, sy2) computed with respect to the origin (top left
+     * corner) of the source image. The non opaque pixels will be drawn in the
+     * background color. The image loading process notifies specified Image
+     * Observer. This method returns true if the image has loaded, otherwise it
+     * returns false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param dx1
+     *            the X top left corner coordinate of the destination rectangle
+     *            area.
+     * @param dy1
+     *            the Y top left corner coordinate of the destination rectangle
+     *            area.
+     * @param dx2
+     *            the X bottom right corner coordinate of the destination
+     *            rectangle area.
+     * @param dy2
+     *            the Y bottom right corner coordinate of the destination
+     *            rectangle area.
+     * @param sx1
+     *            the X top left corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sy1
+     *            the Y top left corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sx2
+     *            the X bottom right corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sy2
+     *            the Y bottom right corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param bgcolor
+     *            the background color.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, false
+     *         otherwise.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1,
+            int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle
+     * area defined by its corners coordinates and draws the sub-image. The
+     * sub-image to be drawn is defined by its top left corner coordinates (sx1,
+     * sy1) and bottom right corner coordinates (sx2, sy2) computed with respect
+     * to the origin (top left corner) of the source image. The image loading
+     * process notifies specified Image Observer. This method returns true if
+     * the image has loaded, otherwise it returns false.
+     * 
+     * @param img
+     *            the image which will be drawn.
+     * @param dx1
+     *            the X top left corner coordinate of the destination rectangle
+     *            area.
+     * @param dy1
+     *            the Y top left corner coordinate of the destination rectangle
+     *            area.
+     * @param dx2
+     *            the X bottom right corner coordinate of the destination
+     *            rectangle area.
+     * @param dy2
+     *            the Y bottom right corner coordinate of the destination
+     *            rectangle area.
+     * @param sx1
+     *            the X top left corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sy1
+     *            the Y top left corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sx2
+     *            the X bottom right corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param sy2
+     *            the Y bottom right corner coordinate of the area to be drawn
+     *            within the source image.
+     * @param observer
+     *            the ImageObserver object which should be notified about image
+     *            loading process.
+     * @return true, if loading image is successful or image is null, false
+     *         otherwise.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1,
+            int sy1, int sx2, int sy2, ImageObserver observer);
+
+    /**
+     * Draws a line from the point (x1, y1) to the point (x2, y2). This method
+     * draws the line with current color which can be changed by setColor(Color
+     * c) method.
+     * 
+     * @param x1
+     *            the X coordinate of the first point.
+     * @param y1
+     *            the Y coordinate of the first point.
+     * @param x2
+     *            the X coordinate of the second point.
+     * @param y2
+     *            the Y coordinate of the second point.
+     */
+    public abstract void drawLine(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws the outline of an oval to fit in the rectangle defined by the given
+     * width, height, and top left corner.
+     * 
+     * @param x
+     *            the X top left corner oval coordinate.
+     * @param y
+     *            the Y top left corner oval coordinate.
+     * @param width
+     *            the oval width.
+     * @param height
+     *            the oval height.
+     */
+    public abstract void drawOval(int x, int y, int width, int height);
+
+    /**
+     * Draws the outline of a polygon. The polygon vertices are defined by
+     * points with xpoints[i], ypoints[i] as coordinates. The polygon edges are
+     * the lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates
+     * to the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i <
+     * npoints +1.
+     * 
+     * @param xpoints
+     *            the array of X coordinates of the polygon vertices.
+     * @param ypoints
+     *            the array of Y coordinates of the polygon vertices.
+     * @param npoints
+     *            the number of polygon vertices/points.
+     */
+    public abstract void drawPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws a set of connected lines which are defined by the x and y
+     * coordinate arrays. The polyline is closed if coordinates of the first
+     * point are the same as coordinates of the last point.
+     * 
+     * @param xpoints
+     *            the array of X point coordinates.
+     * @param ypoints
+     *            the array of Y point coordinates.
+     * @param npoints
+     *            the number of points.
+     */
+    public abstract void drawPolyline(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws the outline of a rectangle with round corners.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     * @param arcWidth
+     *            the arc width for the corners.
+     * @param arcHeight
+     *            the arc height for the corners.
+     */
+    public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth,
+            int arcHeight);
+
+    /**
+     * Draws a text defined by an iterator. The iterator should specify the font
+     * for every character.
+     * 
+     * @param iterator
+     *            the iterator.
+     * @param x
+     *            the X coordinate of the first character.
+     * @param y
+     *            the Y coordinate of the first character.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws a text defined by a string. This method draws the text with current
+     * font and color.
+     * 
+     * @param str
+     *            the string.
+     * @param x
+     *            the X coordinate of the first character.
+     * @param y
+     *            the Y coordinate of the first character.
+     */
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the arc covering the rectangle and using the current color. The
+     * rectangle is defined by the origin point (X, Y) and dimensions (width and
+     * height). The arc center is the the center of specified rectangle. The
+     * angle origin is at the 3 o'clock position, and a positive angle gives
+     * counter-clockwise rotation, a negative angle gives clockwise rotation.
+     * 
+     * @param x
+     *            the X origin coordinate of the rectangle which scales the arc.
+     * @param y
+     *            the Y origin coordinate of the rectangle which scales the arc.
+     * @param width
+     *            the width of the rectangle which scales the arc.
+     * @param height
+     *            the height of the rectangle which scales the arc.
+     * @param sa
+     *            start angle - the origin angle of arc.
+     * @param ea
+     *            arc angle - the angular arc value relative to the start angle.
+     */
+    public abstract void fillArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Fills an oval with the current color where the oval is defined by the
+     * bounding rectangle with the given width, height, and top left corner.
+     * 
+     * @param x
+     *            the X top left corner oval coordinate.
+     * @param y
+     *            the Y top left corner oval coordinate.
+     * @param width
+     *            the oval width.
+     * @param height
+     *            the oval height.
+     */
+    public abstract void fillOval(int x, int y, int width, int height);
+
+    /**
+     * Fills a polygon with the current color. The polygon vertices are defined
+     * by the points with xpoints[i], ypoints[i] as coordinates. The polygon
+     * edges are the lines from the points with (xpoints[i-1], ypoints[i-1])
+     * coordinates to the points with (xpoints[i], ypoints[i]) coordinates, for
+     * 0 < i < npoints +1.
+     * 
+     * @param xpoints
+     *            the array of X coordinates of the polygon vertices.
+     * @param ypoints
+     *            the array of Y coordinates of the polygon vertices.
+     * @param npoints
+     *            the number of polygon vertices/points.
+     */
+    public abstract void fillPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Fills a rectangle with the current color. The rectangle is defined by its
+     * width and length and top left corner coordinates.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     */
+    public abstract void fillRect(int x, int y, int width, int height);
+
+    /**
+     * Fills a round cornered rectangle with the current color.
+     * 
+     * @param x
+     *            the X coordinate of the top left corner of the bounding
+     *            rectangle.
+     * @param y
+     *            the Y coordinate of the top left corner of the bounding
+     *            rectangle.
+     * @param width
+     *            the width of the bounding rectangle.
+     * @param height
+     *            the height of the bounding rectangle.
+     * @param arcWidth
+     *            the arc width at the corners.
+     * @param arcHeight
+     *            the arc height at the corners.
+     */
+    public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth,
+            int arcHeight);
+
+    /**
+     * Gets the clipping area. <br>
+     * <br>
+     * 
+     * @return a Shape object of the clipping area or null if it is not set.
+     */
+    public abstract Shape getClip();
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     * 
+     * @return a Rectangle object which represents the bounds of the current
+     *         clipping area.
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Gets the current color of Graphics.
+     * 
+     * @return the current color.
+     */
+    public abstract Color getColor();
+
+    /**
+     * Gets the current font of Graphics.
+     * 
+     * @return the current font.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets the font metrics of the specified font. The font metrics object
+     * contains information about the rendering of a particular font.
+     * 
+     * @param font
+     *            the specified font.
+     * @return the font metrics for the specified font.
+     */
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Sets the new clipping area specified by rectangle. The new clipping area
+     * doesn't depend on the window's visibility. Rendering operations can't be
+     * performed outside new clipping area.
+     * 
+     * @param x
+     *            the X coordinate of the new clipping rectangle.
+     * @param y
+     *            the Y coordinate of the new clipping rectangle.
+     * @param width
+     *            the width of the new clipping rectangle.
+     * @param height
+     *            the height of the new clipping rectangle.
+     */
+    public abstract void setClip(int x, int y, int width, int height);
+
+    /**
+     * Sets the new clipping area to be the area specified by Shape object. The
+     * new clipping area doesn't depend on the window's visibility. Rendering
+     * operations can't be performed outside new clipping area.
+     * 
+     * @param clip
+     *            the Shape object which represents new clipping area.
+     */
+    public abstract void setClip(Shape clip);
+
+    /**
+     * Sets the current Graphics color. All rendering operations with this
+     * Graphics will use this color.
+     * 
+     * @param c
+     *            the new color.
+     */
+    public abstract void setColor(Color c);
+
+    /**
+     * Sets the current Graphics font. All rendering operations with this
+     * Graphics will use this font.
+     * 
+     * @param font
+     *            the new font.
+     */
+    public abstract void setFont(Font font);
+
+    /**
+     * Sets the paint mode for the Graphics which overwrites all rendering
+     * operations with the current color.
+     */
+    public abstract void setPaintMode();
+
+    /**
+     * Sets the XOR mode for the Graphics which changes a pixel from the current
+     * color to the specified XOR color. <br>
+     * <br>
+     * 
+     * @param color
+     *            the new XOR mode.
+     */
+    public abstract void setXORMode(Color color);
+
+    /**
+     * Translates the origin of Graphics current coordinate system to the point
+     * with X, Y coordinates in the current coordinate system. All rendering
+     * operation in this Graphics will be related to the new origin.
+     * 
+     * @param x
+     *            the X coordinate of the origin.
+     * @param y
+     *            the Y coordinate of the origin.
+     */
+    public abstract void translate(int x, int y);
+}
diff --git a/awt/java/awt/Graphics2D.java b/awt/java/awt/Graphics2D.java
new file mode 100644
index 0000000..04a7319
--- /dev/null
+++ b/awt/java/awt/Graphics2D.java
@@ -0,0 +1,513 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.font.GlyphVector;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * The Graphics2D class extends Graphics class and provides more capabilities
+ * for rendering text, images, shapes. This provides methods to perform
+ * transformation of coordinate system, color management, and text layout. The
+ * following attributes exist for rendering:
+ * <ul>
+ * <li>Color - current Graphics2D color;</li>
+ * <li>Font - current Graphics2D font;</li>
+ * <li>Stroke - pen with a width of 1 pixel;</li>
+ * <li>Transform - current Graphics2D Transformation;</li>
+ * <li>Composite - alpha compositing rules for combining source and destination
+ * colors.</li>
+ * </ul>
+ * 
+ * @since Android 1.0
+ */
+public abstract class Graphics2D extends Graphics {
+
+    /**
+     * Instantiates a new Graphics2D object. This constructor should never be
+     * called directly.
+     */
+    protected Graphics2D() {
+        super();
+    }
+
+    /**
+     * Adds preferences for the rendering algorithms. The preferences are
+     * arbitrary and specified by Map objects. All specified by Map object
+     * preferences can be modified.
+     * 
+     * @param hints
+     *            the rendering hints.
+     */
+    public abstract void addRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Intersects the current clipping area with the specified Shape and the
+     * result becomes a new clipping area. If current clipping area is not
+     * defined, the Shape becomes the new clipping area. No rendering operations
+     * are allowed outside the clipping area.
+     * 
+     * @param s
+     *            the specified Shape object which will be intersected with
+     *            current clipping area.
+     */
+    public abstract void clip(Shape s);
+
+    /**
+     * Draws the outline of the specified Shape.
+     * 
+     * @param s
+     *            the Shape which outline is drawn.
+     */
+    public abstract void draw(Shape s);
+
+    /**
+     * Draws the specified GlyphVector object's text at the point x, y.
+     * 
+     * @param g
+     *            the GlyphVector object to be drawn.
+     * @param x
+     *            the X position where the GlyphVector's text should be
+     *            rendered.
+     * @param y
+     *            the Y position where the GlyphVector's text should be
+     *            rendered.
+     */
+    public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+
+    /**
+     * Draws the BufferedImage -- modified according to the operation
+     * BufferedImageOp -- at the point x, y.
+     * 
+     * @param img
+     *            the BufferedImage to be rendered.
+     * @param op
+     *            the filter to be applied to the image before rendering.
+     * @param x
+     *            the X coordinate of the point where the image's upper left
+     *            corner will be placed.
+     * @param y
+     *            the Y coordinate of the point where the image's upper left
+     *            corner will be placed.
+     */
+    public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y);
+
+    /**
+     * Draws BufferedImage transformed from image space into user space
+     * according to the AffineTransform xform and notifies the ImageObserver.
+     * 
+     * @param img
+     *            the BufferedImage to be rendered.
+     * @param xform
+     *            the affine transformation from the image to the user space.
+     * @param obs
+     *            the ImageObserver to be notified about the image conversion.
+     * @return true, if the image is successfully loaded and rendered, or it's
+     *         null, otherwise false.
+     */
+    public abstract boolean drawImage(Image img, AffineTransform xform, ImageObserver obs);
+
+    /**
+     * Draws a RenderableImage which is transformed from image space into user
+     * according to the AffineTransform xform.
+     * 
+     * @param img
+     *            the RenderableImage to be rendered.
+     * @param xform
+     *            the affine transformation from image to user space.
+     */
+    public abstract void drawRenderableImage(RenderableImage img, AffineTransform xform);
+
+    /**
+     * Draws a RenderedImage which is transformed from image space into user
+     * according to the AffineTransform xform.
+     * 
+     * @param img
+     *            the RenderedImage to be rendered.
+     * @param xform
+     *            the affine transformation from image to user space.
+     */
+    public abstract void drawRenderedImage(RenderedImage img, AffineTransform xform);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. The first
+     * character's position is specified by the X, Y parameters.
+     * 
+     * @param iterator
+     *            whose text is drawn.
+     * @param x
+     *            the X position where the first character is drawn.
+     * @param y
+     *            the Y position where the first character is drawn.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, float x, float y);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. The first
+     * character's position is specified by the X, Y parameters.
+     * 
+     * @param iterator
+     *            whose text is drawn.
+     * @param x
+     *            the X position where the first character is drawn.
+     * @param y
+     *            the Y position where the first character is drawn.
+     * @see java.awt.Graphics#drawString(AttributedCharacterIterator, int, int)
+     */
+    @Override
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws the String whose the first character position is specified by the
+     * parameters X, Y.
+     * 
+     * @param s
+     *            the String to be drawn.
+     * @param x
+     *            the X position of the first character.
+     * @param y
+     *            the Y position of the first character.
+     */
+    public abstract void drawString(String s, float x, float y);
+
+    /**
+     * Draws the String whose the first character coordinates are specified by
+     * the parameters X, Y.
+     * 
+     * @param str
+     *            the String to be drawn.
+     * @param x
+     *            the X coordinate of the first character.
+     * @param y
+     *            the Y coordinate of the first character.
+     * @see java.awt.Graphics#drawString(String, int, int)
+     */
+    @Override
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the interior of the specified Shape.
+     * 
+     * @param s
+     *            the Shape to be filled.
+     */
+    public abstract void fill(Shape s);
+
+    /**
+     * Gets the background color.
+     * 
+     * @return the current background color.
+     */
+    public abstract Color getBackground();
+
+    /**
+     * Gets the current composite of the Graphics2D.
+     * 
+     * @return the current composite which specifies the compositing style.
+     */
+    public abstract Composite getComposite();
+
+    /**
+     * Gets the device configuration.
+     * 
+     * @return the device configuration.
+     */
+    public abstract GraphicsConfiguration getDeviceConfiguration();
+
+    /**
+     * Gets the rendering context of the Font.
+     * 
+     * @return the FontRenderContext.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets the current Paint of Graphics2D.
+     * 
+     * @return the current Paint of Graphics2D.
+     */
+    public abstract Paint getPaint();
+
+    /**
+     * Gets the value of single preference for specified key.
+     * 
+     * @param key
+     *            the specified key of the rendering hint.
+     * @return the value of rendering hint for specified key.
+     */
+    public abstract Object getRenderingHint(RenderingHints.Key key);
+
+    /**
+     * Gets the set of the rendering preferences as a collection of key/value
+     * pairs.
+     * 
+     * @return the RenderingHints which contains the rendering preferences.
+     */
+    public abstract RenderingHints getRenderingHints();
+
+    /**
+     * Gets current stroke of the Graphics2D.
+     * 
+     * @return current stroke of the Graphics2D.
+     */
+    public abstract Stroke getStroke();
+
+    /**
+     * Gets current affine transform of the Graphics2D.
+     * 
+     * @return current AffineTransform of the Graphics2D.
+     */
+    public abstract AffineTransform getTransform();
+
+    /**
+     * Determines whether or not the specified Shape intersects the specified
+     * Rectangle. If the onStroke parameter is true, this method checks whether
+     * or not the specified Shape outline intersects the specified Rectangle,
+     * otherwise this method checks whether or not the specified Shape's
+     * interior intersects the specified Rectangle.
+     * 
+     * @param rect
+     *            the specified Rectangle.
+     * @param s
+     *            the Shape to check for intersection.
+     * @param onStroke
+     *            the parameter determines whether or not this method checks for
+     *            intersection of the Shape outline or of the Shape interior
+     *            with the Rectangle.
+     * @return true, if there is a hit, false otherwise.
+     */
+    public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
+
+    /**
+     * Performs a rotation transform relative to current Graphics2D Transform.
+     * The coordinate system is rotated by the specified angle in radians
+     * relative to current origin.
+     * 
+     * @param theta
+     *            the angle of rotation in radians.
+     */
+    public abstract void rotate(double theta);
+
+    /**
+     * Performs a translated rotation transform relative to current Graphics2D
+     * Transform. The coordinate system is rotated by the specified angle in
+     * radians relative to current origin and then moved to point (x, y). Is
+     * this right?
+     * 
+     * @param theta
+     *            the angle of rotation in radians.
+     * @param x
+     *            the X coordinate.
+     * @param y
+     *            the Y coordinate.
+     */
+    public abstract void rotate(double theta, double x, double y);
+
+    /**
+     * Performs a linear scale transform relative to current Graphics2D
+     * Transform. The coordinate system is rescaled vertically and horizontally
+     * by the specified parameters.
+     * 
+     * @param sx
+     *            the scaling factor by which the X coordinate is multiplied.
+     * @param sy
+     *            the scaling factor by which the Y coordinate is multiplied.
+     */
+    public abstract void scale(double sx, double sy);
+
+    /**
+     * Sets a new background color for clearing rectangular areas. The clearRect
+     * method uses the current background color.
+     * 
+     * @param color
+     *            the new background color.
+     */
+    public abstract void setBackground(Color color);
+
+    /**
+     * Sets the current composite for Graphics2D.
+     * 
+     * @param comp
+     *            the Composite object.
+     */
+    public abstract void setComposite(Composite comp);
+
+    /**
+     * Sets the paint for Graphics2D.
+     * 
+     * @param paint
+     *            the Paint object.
+     */
+    public abstract void setPaint(Paint paint);
+
+    /**
+     * Sets a key-value pair in the current RenderingHints map.
+     * 
+     * @param key
+     *            the key of the rendering hint to set.
+     * @param value
+     *            the value to set for the rendering hint.
+     */
+    public abstract void setRenderingHint(RenderingHints.Key key, Object value);
+
+    /**
+     * Replaces the current rendering hints with the specified rendering
+     * preferences.
+     * 
+     * @param hints
+     *            the new Map of rendering hints.
+     */
+    public abstract void setRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Sets the stroke for the Graphics2D.
+     * 
+     * @param s
+     *            the Stroke object.
+     */
+    public abstract void setStroke(Stroke s);
+
+    /**
+     * Overwrite the current Transform of the Graphics2D. The specified
+     * Transform should be received from the getTransform() method and should be
+     * used only for restoring the original Graphics2D transform after calling
+     * draw or fill methods.
+     * 
+     * @param Tx
+     *            the specified Transform.
+     */
+    public abstract void setTransform(AffineTransform Tx);
+
+    /**
+     * Performs a shear transform relative to current Graphics2D Transform. The
+     * coordinate system is shifted by the specified multipliers relative to
+     * current position.
+     * 
+     * @param shx
+     *            the multiplier by which the X coordinates shift position along
+     *            X axis as a function of Y coordinates.
+     * @param shy
+     *            the multiplier by which the Y coordinates shift position along
+     *            Y axis as a function of X coordinates.
+     */
+    public abstract void shear(double shx, double shy);
+
+    /**
+     * Concatenates the AffineTransform object with current Transform of this
+     * Graphics2D. The transforms are applied in reverse order with the last
+     * specified transform applied first and the next transformation applied to
+     * the result of previous transformation. More precisely, if Cx is the
+     * current Graphics2D transform, the transform method's result with Tx as
+     * the parameter is the transformation Rx, where Rx(p) = Cx(Tx(p)), for p -
+     * a point in current coordinate system. Rx becomes the current Transform
+     * for this Graphics2D.
+     * 
+     * @param Tx
+     *            the AffineTransform object to be concatenated with current
+     *            Transform.
+     */
+    public abstract void transform(AffineTransform Tx);
+
+    /**
+     * Performs a translate transform relative to current Graphics2D Transform.
+     * The coordinate system is moved by the specified distance relative to
+     * current position.
+     * 
+     * @param tx
+     *            the translation distance along the X axis.
+     * @param ty
+     *            the translation distance along the Y axis.
+     */
+    public abstract void translate(double tx, double ty);
+
+    /**
+     * Moves the origin Graphics2D Transform to the point with x, y coordinates
+     * in current coordinate system. The new origin of coordinate system is
+     * moved to the (x, y) point accordingly. All rendering and transform
+     * operations are performed relative to this new origin.
+     * 
+     * @param x
+     *            the X coordinate.
+     * @param y
+     *            the Y coordinate.
+     * @see java.awt.Graphics#translate(int, int)
+     */
+    @Override
+    public abstract void translate(int x, int y);
+
+    /**
+     * Fills a 3D rectangle with the current color. The rectangle is specified
+     * by its width, height, and top left corner coordinates.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     * @param raised
+     *            a boolean value that determines whether the rectangle is drawn
+     *            as raised or indented.
+     * @see java.awt.Graphics#fill3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.fill3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.fill3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+
+    /**
+     * Draws the highlighted outline of a rectangle.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's top left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's top left corner.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     * @param raised
+     *            a boolean value that determines whether the rectangle is drawn
+     *            as raised or indented.
+     * @see java.awt.Graphics#draw3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.draw3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.draw3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/GraphicsConfiguration.java b/awt/java/awt/GraphicsConfiguration.java
new file mode 100644
index 0000000..d59e896
--- /dev/null
+++ b/awt/java/awt/GraphicsConfiguration.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsConfiguration class contains the characteristics of graphics
+ * devices such as a printer or monitor, and represents device's capabilities
+ * and modes. Many GraphicsConfiguration objects can be associated with single
+ * graphics device.
+ * 
+ * @since Android 1.0
+ */
+public abstract class GraphicsConfiguration {
+
+    /**
+     * Constructor could not be used directly and should be obtained in extended
+     * classes.
+     */
+    protected GraphicsConfiguration() {
+    }
+
+    /**
+     * Creates BufferedImage image object with a data layout and color model
+     * compatible with this GraphicsConfiguration with specified width and
+     * height parameters.
+     * 
+     * @param width
+     *            the width of BufferedImage.
+     * @param height
+     *            the height of BufferedImage.
+     * @return the BufferedImage object with specified width and height
+     *         parameters.
+     */
+    public abstract BufferedImage createCompatibleImage(int width, int height);
+
+    /**
+     * Creates a BufferedImage that has the specified width, height,
+     * transparency and has a data layout and color model compatible with this
+     * GraphicsConfiguration.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @param transparency
+     *            the transparency mode.
+     * @return the BufferedImage object.
+     */
+    public abstract BufferedImage createCompatibleImage(int width, int height, int transparency);
+
+    /**
+     * Creates a VolatileImage that has the specified width and height and has a
+     * data layout and color model compatible with this GraphicsConfiguration.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height);
+
+    /**
+     * Creates a VolatileImage that supports the specified width, height,
+     * transparency and has a data layout and color model compatible with this
+     * GraphicsConfiguration.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @param transparency
+     *            the transparency mode.
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height,
+            int transparency);
+
+    /**
+     * Gets the bounds of area covered by the GraphicsConfiguration in the
+     * device coordinates space.
+     * 
+     * @return the Rectangle of GraphicsConfiguration's bounds.
+     */
+    public abstract Rectangle getBounds();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration.
+     * 
+     * @return the ColorModel object of the GraphicsConfiguration.
+     */
+    public abstract ColorModel getColorModel();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration which supports specified
+     * Transparency.
+     * 
+     * @param transparency
+     *            the Transparency mode: OPAQUE, BITMASK, or TRANSLUCENT.
+     * @return the ColorModel of the GraphicsConfiguration which supports
+     *         specified Transparency.
+     */
+    public abstract ColorModel getColorModel(int transparency);
+
+    /**
+     * Gets the default AffineTransform of the GraphicsConfiguration. This
+     * method translates user coordinates to device coordinates.
+     * 
+     * @return the default AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getDefaultTransform();
+
+    /**
+     * Gets the GraphicsDevice of the GraphicsConfiguration.
+     * 
+     * @return the GraphicsDevice of the GraphicsConfiguration.
+     */
+    public abstract GraphicsDevice getDevice();
+
+    /**
+     * Gets the normalizing AffineTransform of the GraphicsConfiguration.
+     * 
+     * @return the normalizing AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getNormalizingTransform();
+
+    /**
+     * Creates VolatileImage with specified width, height, ImageCapabilities; a
+     * data layout and color model compatible with this GraphicsConfiguration.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @param caps
+     *            the ImageCapabilities object.
+     * @return the VolatileImage which data layout and color model compatible
+     *         with this GraphicsConfiguration.
+     * @throws AWTException
+     *             if ImageCapabilities is not supported by the
+     *             GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height, ImageCapabilities caps)
+            throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Creates a VolatileImage with specified width, height, transparency and
+     * ImageCapabilities; a data layout and color model compatible with this
+     * GraphicsConfiguration.
+     * 
+     * @param width
+     *            the width of image.
+     * @param height
+     *            the height of image.
+     * @param caps
+     *            the ImageCapabilities object.
+     * @param transparency
+     *            the Transparency mode: OPAQUE, BITMASK, or TRANSLUCENT.
+     * @return the VolatileImage which data layout and color model compatible
+     *         with this GraphicsConfiguration.
+     * @throws AWTException
+     *             if ImageCapabilities is not supported by the
+     *             GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps, int transparency) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height, transparency);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Gets the buffering capabilities of the GraphicsConfiguration.
+     * 
+     * @return the BufferCapabilities object.
+     */
+    public BufferCapabilities getBufferCapabilities() {
+        return new BufferCapabilities(new ImageCapabilities(false), new ImageCapabilities(false),
+                BufferCapabilities.FlipContents.UNDEFINED);
+    }
+
+    /**
+     * Gets the image capabilities of the GraphicsConfiguration.
+     * 
+     * @return the ImageCapabilities object.
+     */
+    public ImageCapabilities getImageCapabilities() {
+        return new ImageCapabilities(false);
+    }
+}
diff --git a/awt/java/awt/GraphicsDevice.java b/awt/java/awt/GraphicsDevice.java
new file mode 100644
index 0000000..9eda4e0
--- /dev/null
+++ b/awt/java/awt/GraphicsDevice.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsDevice class describes the graphics devices (such as screens or
+ * printers) which are available in a particular graphics environment. Many
+ * GraphicsDevice instances can be associated with a single GraphicsEnvironment.
+ * Each GraphicsDevice has one or more GraphicsConfiguration objects which
+ * specify the different configurations and modes of GraphicsDevice.
+ * 
+ * @since Android 1.0
+ */
+public abstract class GraphicsDevice {
+
+    /**
+     * The display mode.
+     */
+    private DisplayMode displayMode;
+
+    // ???AWT
+    // private Window fullScreenWindow = null;
+
+    /**
+     * The Constant TYPE_IMAGE_BUFFER indicates a image buffer device.
+     */
+
+    public static final int TYPE_IMAGE_BUFFER = 2;
+
+    /**
+     * The Constant TYPE_PRINTER indicates a printer device.
+     */
+    public static final int TYPE_PRINTER = 1;
+
+    /**
+     * The Constant TYPE_RASTER_SCREEN indicates a raster screen device.
+     */
+    public static final int TYPE_RASTER_SCREEN = 0;
+
+    /**
+     * Constructor is not to be used directly as this class is abstract.
+     */
+    protected GraphicsDevice() {
+        displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI,
+                DisplayMode.REFRESH_RATE_UNKNOWN);
+    }
+
+    /**
+     * Returns an array of GraphicsConfiguration objects associated with the
+     * GraphicsDevice.
+     * 
+     * @return an array of GraphicsConfiguration objects associated with the
+     *         GraphicsDevice.
+     */
+    public abstract GraphicsConfiguration[] getConfigurations();
+
+    /**
+     * Gets the default configuration for the GraphicsDevice.
+     * 
+     * @return the default GraphicsConfiguration object for the GraphicsDevice.
+     */
+    public abstract GraphicsConfiguration getDefaultConfiguration();
+
+    /**
+     * Gets the String identifier which associated with the GraphicsDevice in
+     * the GraphicsEnvironment.
+     * 
+     * @return the String identifier of the GraphicsDevice in the
+     *         GraphicsEnvironment.
+     */
+    public abstract String getIDstring();
+
+    /**
+     * Gets the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, TYPE_PRINTER or
+     * TYPE_RASTER_SCREEN.
+     * 
+     * @return the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, TYPE_PRINTER
+     *         or TYPE_RASTER_SCREEN.
+     */
+    public abstract int getType();
+
+    /**
+     * Returns the number of bytes available in accelerated memory on this
+     * device.
+     * 
+     * @return the number of bytes available accelerated memory.
+     */
+    public int getAvailableAcceleratedMemory() {
+        return 0;
+    }
+
+    /*
+     * ???AWT public GraphicsConfiguration
+     * getBestConfiguration(GraphicsConfigTemplate gct) { return
+     * gct.getBestConfiguration(getConfigurations()); }
+     */
+
+    /**
+     * Gets the current display mode of the GraphicsDevice.
+     * 
+     * @return the current display mode of the GraphicsDevice.
+     */
+    public DisplayMode getDisplayMode() {
+        return displayMode;
+    }
+
+    /**
+     * Gets an array of display modes available in this GraphicsDevice.
+     * 
+     * @return an array of display modes available in this GraphicsDevice.
+     */
+    public DisplayMode[] getDisplayModes() {
+        DisplayMode[] dms = {
+            displayMode
+        };
+        return dms;
+    }
+
+    /*
+     * ???AWT public Window getFullScreenWindow() { return fullScreenWindow; }
+     */
+
+    /**
+     * Returns true if this GraphicsDevice supports low-level display changes.
+     * 
+     * @return true, if this GraphicsDevice supports low-level display changes;
+     *         false otherwise.
+     */
+    public boolean isDisplayChangeSupported() {
+        return false;
+    }
+
+    /**
+     * Returns true if this GraphicsDevice supports full screen mode.
+     * 
+     * @return true, if this GraphicsDevice supports full screen mode, false
+     *         otherwise.
+     */
+    public boolean isFullScreenSupported() {
+        return false;
+    }
+
+    // an array of display modes available in this GraphicsDevice.
+
+    /**
+     * Sets the display mode of this GraphicsDevice.
+     * 
+     * @param dm
+     *            the new display mode of this GraphicsDevice.
+     */
+    public void setDisplayMode(DisplayMode dm) {
+        if (!isDisplayChangeSupported()) {
+            // awt.122=Does not support display mode changes
+            throw new UnsupportedOperationException(Messages.getString("awt.122")); //$NON-NLS-1$
+        }
+
+        DisplayMode[] dms = getDisplayModes();
+        for (DisplayMode element : dms) {
+            if (element.equals(dm)) {
+                displayMode = dm;
+                return;
+            }
+        }
+        // awt.123=Unsupported display mode: {0}
+        throw new IllegalArgumentException(Messages.getString("awt.123", dm)); //$NON-NLS-1$
+    }
+
+    /*
+     * ???AWT public void setFullScreenWindow(Window w) { if (w == null) {
+     * fullScreenWindow = null; return; } fullScreenWindow = w; if
+     * (isFullScreenSupported()) { w.enableInputMethods(false); } else {
+     * w.setSize(displayMode.getWidth(), displayMode.getHeight());
+     * w.setLocation(0, 0); } w.setVisible(true); w.setAlwaysOnTop(true); }
+     */
+}
diff --git a/awt/java/awt/GraphicsEnvironment.java b/awt/java/awt/GraphicsEnvironment.java
new file mode 100644
index 0000000..d527417
--- /dev/null
+++ b/awt/java/awt/GraphicsEnvironment.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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+/**
+ * The GraphicsEnvironment class defines a collection of GraphicsDevice objects
+ * and Font objects which are available for Java application on current
+ * platform.
+ * 
+ * @since Android 1.0
+ */
+public abstract class GraphicsEnvironment {
+
+    /**
+     * Constructor could not be used directly and should be obtained in extended
+     * classes.
+     */
+    protected GraphicsEnvironment() {
+    }
+
+    /**
+     * Gets the local GraphicsEnvironment.
+     * 
+     * @return the local GraphicsEnvironment.
+     */
+    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
+        synchronized (ContextStorage.getContextLock()) {
+            if (ContextStorage.getGraphicsEnvironment() == null) {
+                if (isHeadless()) {
+                    ContextStorage.setGraphicsEnvironment(new HeadlessGraphicsEnvironment());
+                } else {
+                    CommonGraphics2DFactory g2df = (CommonGraphics2DFactory)Toolkit
+                            .getDefaultToolkit().getGraphicsFactory();
+
+                    ContextStorage.setGraphicsEnvironment(g2df
+                            .createGraphicsEnvironment(ContextStorage.getWindowFactory()));
+                }
+            }
+
+            return ContextStorage.getGraphicsEnvironment();
+        }
+    }
+
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported in
+     * this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of the
+     *         graphics environment that are dependent on a display, keyboard,
+     *         or mouse, false otherwise.
+     */
+    public boolean isHeadlessInstance() {
+        return false;
+    }
+
+    /**
+     * Checks whether or not a display, keyboard, and mouse are supported in
+     * this environment.
+     * 
+     * @return true, if a HeadlessException is thrown from areas of the Toolkit
+     *         and GraphicsEnvironment that are dependent on a display,
+     *         keyboard, or mouse, false otherwise.
+     */
+    public static boolean isHeadless() {
+        return "true".equals(System.getProperty("java.awt.headless"));
+    }
+
+    /**
+     * Gets the maximum bounds of system centered windows.
+     * 
+     * @return the maximum bounds of system centered windows.
+     * @throws HeadlessException
+     *             if isHeadless() method returns true.
+     */
+    public Rectangle getMaximumWindowBounds() throws HeadlessException {
+        return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+    }
+
+    /**
+     * Gets the Point which should defines the center of system window.
+     * 
+     * @return the Point where the system window should be centered.
+     * @throws HeadlessException
+     *             if isHeadless() method returns true.
+     */
+    public Point getCenterPoint() throws HeadlessException {
+        Rectangle mwb = getMaximumWindowBounds();
+        return new Point(mwb.width >> 1, mwb.height >> 1);
+    }
+
+    /**
+     * Indicates that the primary font should be used. Primary font is specified
+     * by initial system locale or default encoding).
+     */
+    public void preferLocaleFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping,
+        // so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Indicates that a proportional preference of the font should be used.
+     */
+    public void preferProportionalFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping,
+        // so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Creates the Graphics2D object for rendering to the specified
+     * BufferedImage.
+     * 
+     * @param bufferedImage
+     *            the BufferedImage object.
+     * @return the Graphics2D object which allows to render to the specified
+     *         BufferedImage.
+     */
+    public abstract Graphics2D createGraphics(BufferedImage bufferedImage);
+
+    /**
+     * Gets the array of all available fonts instances in this
+     * GraphicsEnviroments.
+     * 
+     * @return the array of all available fonts instances in this
+     *         GraphicsEnviroments.
+     */
+    public abstract Font[] getAllFonts();
+
+    /**
+     * Gets the array of all available font family names.
+     * 
+     * @return the array of all available font family names.
+     */
+    public abstract String[] getAvailableFontFamilyNames();
+
+    /**
+     * Gets the array of all available font family names for the specified
+     * locale.
+     * 
+     * @param locale
+     *            the Locale object which represents geographical region. The
+     *            default locale is used if locale is null.
+     * @return the array of available font family names for the specified
+     *         locale.
+     */
+    public abstract String[] getAvailableFontFamilyNames(Locale locale);
+
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * @throws HeadlessException
+     *             if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice getDefaultScreenDevice() throws HeadlessException;
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice objects which represents all
+     *         available screen devices.
+     * @throws HeadlessException
+     *             if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice[] getScreenDevices() throws HeadlessException;
+}
diff --git a/awt/java/awt/HeadlessException.java b/awt/java/awt/HeadlessException.java
new file mode 100644
index 0000000..ec111f1
--- /dev/null
+++ b/awt/java/awt/HeadlessException.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The HeadlessException class provides notifications and error messages when
+ * code that is dependent on a keyboard, display, or mouse is called in an
+ * environment that does not support a keyboard, display, or mouse.
+ * 
+ * @since Android 1.0
+ */
+public class HeadlessException extends UnsupportedOperationException {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 167183644944358563L;
+
+    /**
+     * Instantiates a new headless exception.
+     */
+    public HeadlessException() {
+        super();
+    }
+
+    /**
+     * Instantiates a new headless exception with the specified message.
+     * 
+     * @param msg
+     *            the String which represents error message.
+     */
+    public HeadlessException(String msg) {
+        super(msg);
+    }
+}
diff --git a/awt/java/awt/HeadlessGraphicsEnvironment.java b/awt/java/awt/HeadlessGraphicsEnvironment.java
new file mode 100644
index 0000000..306393f
--- /dev/null
+++ b/awt/java/awt/HeadlessGraphicsEnvironment.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.
+ */
+
+package java.awt;
+
+import java.awt.GraphicsDevice;
+import java.awt.HeadlessException;
+
+import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
+
+/**
+ * The HeadlessGraphicsEnvironment class is the CommonGraphicsEnvironment
+ * implementation to use in the case where the environment lacks display,
+ * keyboard, and mouse support.
+ * 
+ * @since Android 1.0
+ */
+public class HeadlessGraphicsEnvironment extends CommonGraphicsEnvironment {
+
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported in
+     * this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of the
+     *         graphics environment that are dependent on a display, keyboard,
+     *         or mouse, false otherwise.
+     */
+    @Override
+    public boolean isHeadlessInstance() {
+        return true;
+    }
+
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * @throws HeadlessException
+     *             if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice objects which represents all
+     *         available screen devices.
+     * @throws HeadlessException
+     *             if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+}
diff --git a/awt/java/awt/HeadlessToolkit.java b/awt/java/awt/HeadlessToolkit.java
new file mode 100644
index 0000000..c64a85a
--- /dev/null
+++ b/awt/java/awt/HeadlessToolkit.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 java.awt;
+
+//???AWT
+//import java.awt.datatransfer.Clipboard;
+//import java.awt.dnd.DragGestureEvent;
+//import java.awt.dnd.DragGestureListener;
+//import java.awt.dnd.DragGestureRecognizer;
+//import java.awt.dnd.DragSource;
+//import java.awt.dnd.InvalidDnDOperationException;
+//import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel; //import java.awt.peer.*;
+//import java.beans.PropertyChangeSupport;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.ComponentInternals; //import org.apache.harmony.awt.datatransfer.DTK;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+/**
+ * The HeadlessToolkit class is a subclass of ToolkitImpl to be used for
+ * graphical environments that lack keyboard and mouse capabilities.
+ * 
+ * @since Android 1.0
+ */
+public final class HeadlessToolkit extends ToolkitImpl {
+
+    // ???AWT
+    /*
+     * @Override protected ButtonPeer createButton(Button a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected CheckboxPeer createCheckbox(Checkbox a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected CheckboxMenuItemPeer
+     * createCheckboxMenuItem(CheckboxMenuItem a0) throws HeadlessException {
+     * throw new HeadlessException(); }
+     * @Override protected ChoicePeer createChoice(Choice a0) throws
+     * HeadlessException { throw new HeadlessException(); } public Cursor
+     * createCustomCursor(Image img, Point hotSpot, String name) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected DialogPeer createDialog(Dialog a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override public <T extends DragGestureRecognizer> T
+     * createDragGestureRecognizer( Class<T> recognizerAbstractClass, DragSource
+     * ds, Component c, int srcActions, DragGestureListener dgl) { return null;
+     * }
+     * @Override public DragSourceContextPeer
+     * createDragSourceContextPeer(DragGestureEvent dge) throws
+     * InvalidDnDOperationException { throw new InvalidDnDOperationException();
+     * }
+     * @Override protected FileDialogPeer createFileDialog(FileDialog a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected FramePeer createFrame(Frame a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected LabelPeer createLabel(Label a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected ListPeer createList(List a0) throws HeadlessException
+     * { throw new HeadlessException(); }
+     * @Override protected MenuPeer createMenu(Menu a0) throws HeadlessException
+     * { throw new HeadlessException(); }
+     * @Override protected MenuBarPeer createMenuBar(MenuBar a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected MenuItemPeer createMenuItem(MenuItem a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected PopupMenuPeer createPopupMenu(PopupMenu a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected ScrollbarPeer createScrollbar(Scrollbar a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected ScrollPanePeer createScrollPane(ScrollPane a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected TextAreaPeer createTextArea(TextArea a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected TextFieldPeer createTextField(TextField a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     * @Override protected WindowPeer createWindow(Window a0) throws
+     * HeadlessException { throw new HeadlessException(); }
+     */
+
+    @Override
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public ColorModel getColorModel() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMaximumCursorColors() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    // ???AWT
+    /*
+     * @Override NativeEventQueue getNativeEventQueue() throws HeadlessException
+     * { throw new HeadlessException(); }
+     * @Override public PrintJob getPrintJob(Frame frame, String jobtitle,
+     * JobAttributes jobAttributes, PageAttributes pageAttributes) throws
+     * IllegalArgumentException { throw new IllegalArgumentException(); }
+     * @Override public PrintJob getPrintJob(Frame frame, String jobtitle,
+     * Properties props) throws NullPointerException { throw new
+     * NullPointerException(); }
+     */
+
+    @Override
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public Dimension getScreenSize() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    // ???AWT
+    /*
+     * @Override public Clipboard getSystemClipboard() throws HeadlessException
+     * { throw new HeadlessException(); }
+     * @Override public Clipboard getSystemSelection() throws HeadlessException
+     * { throw new HeadlessException(); }
+     * @Override WindowFactory getWindowFactory() throws HeadlessException {
+     * throw new HeadlessException(); }
+     */
+
+    @Override
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            // ???AWT: new EventQueue(this); // create the system EventQueue
+            // ???AWT: dispatcher = new Dispatcher(this);
+            desktopProperties = new HashMap<String, Object>();
+            // ???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
+            // ???AWT: awtEventsManager = new AWTEventsManager();
+            // ???AWT: dispatchThread = new HeadlessEventDispatchThread(this,
+            // dispatcher);
+            // ???AWT: dtk = DTK.getDTK();
+            dispatchThread.start();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected void loadSystemColors(int[] systemColors) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(InputMethodHighlight highlight)
+            throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+}
diff --git a/awt/java/awt/IllegalComponentStateException.java b/awt/java/awt/IllegalComponentStateException.java
new file mode 100644
index 0000000..bed1729
--- /dev/null
+++ b/awt/java/awt/IllegalComponentStateException.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 Michael Danilov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The IllegalComponentStateException class is used to provide notification that
+ * AWT component is not in an appropriate state for the requested operation.
+ * 
+ * @since Android 1.0
+ */
+public class IllegalComponentStateException extends IllegalStateException {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -1889339587208144238L;
+
+    /**
+     * Instantiates a new IllegalComponentStateException with the specified
+     * message.
+     * 
+     * @param s
+     *            the String message which describes the exception.
+     */
+    public IllegalComponentStateException(String s) {
+        super(s);
+    }
+
+    /**
+     * Instantiates a new IllegalComponentStateException without detailed
+     * message.
+     */
+    public IllegalComponentStateException() {
+    }
+
+}
diff --git a/awt/java/awt/Image.java b/awt/java/awt/Image.java
new file mode 100644
index 0000000..7ae3ed8
--- /dev/null
+++ b/awt/java/awt/Image.java
@@ -0,0 +1,205 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.AreaAveragingScaleFilter;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageFilter;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.ReplicateScaleFilter;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Image abstract class represents the graphic images.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Image {
+
+    /**
+     * The UndefinedProperty object should be returned if property is not
+     * defined for a particular image.
+     */
+    public static final Object UndefinedProperty = new Object(); // $NON-LOCK-1$
+
+    /**
+     * The Constant SCALE_DEFAULT indicates the default image scaling algorithm.
+     */
+    public static final int SCALE_DEFAULT = 1;
+
+    /**
+     * The Constant SCALE_FAST indicates an image scaling algorithm which places
+     * a higher priority on scaling speed than on the image's smoothness.
+     */
+    public static final int SCALE_FAST = 2;
+
+    /**
+     * The Constant SCALE_SMOOTH indicates an image scaling algorithm which
+     * places a higher priority on image smoothness than on scaling speed.
+     */
+    public static final int SCALE_SMOOTH = 4;
+
+    /**
+     * The Constant SCALE_REPLICATE indicates the image scaling algorithm in the
+     * ReplicateScaleFilter class.
+     */
+    public static final int SCALE_REPLICATE = 8;
+
+    /**
+     * The Constant SCALE_AREA_AVERAGING indicates the area averaging image
+     * scaling algorithm.
+     */
+    public static final int SCALE_AREA_AVERAGING = 16;
+
+    /**
+     * The acceleration priority indicates image acceleration.
+     */
+    protected float accelerationPriority = 0.5f;
+
+    /**
+     * The Constant capabilities.
+     */
+    private static final ImageCapabilities capabilities = new ImageCapabilities(false);
+
+    /**
+     * Gets the image property with the specified name. The UndefinedProperty
+     * object should be return if the property is not specified for this image.
+     * The return value should be null if the property is currently unknown yet
+     * and the specified ImageObserver is to be notified later.
+     * 
+     * @param name
+     *            the name of image's property.
+     * @param observer
+     *            the ImageObserver.
+     * @return the Object which represents value of the specified property.
+     */
+    public abstract Object getProperty(String name, ImageObserver observer);
+
+    /**
+     * Gets the ImageProducer object which represents data of this Image.
+     * 
+     * @return the ImageProducer object which represents data of this Image.
+     */
+    public abstract ImageProducer getSource();
+
+    /**
+     * Gets the width of this image. The specified ImageObserver object is
+     * notified when the width of this image is available.
+     * 
+     * @param observer
+     *            the ImageObserver object which is is notified when the width
+     *            of this image is available.
+     * @return the width of image, or -1 if the width of this image is not
+     *         available.
+     */
+    public abstract int getWidth(ImageObserver observer);
+
+    /**
+     * Gets the height of this image. The specified ImageObserver object is
+     * notified when the height of this image is available.
+     * 
+     * @param observer
+     *            the ImageObserver object which is is notified when the height
+     *            of this image is available.
+     * @return the height of image, or -1 if the height of this image is not
+     *         available.
+     */
+    public abstract int getHeight(ImageObserver observer);
+
+    /**
+     * Gets the scaled instance of this Image. This method returns an Image
+     * object constructed from the source of this image with the specified
+     * width, height, and applied scaling algorithm.
+     * 
+     * @param width
+     *            the width of scaled Image.
+     * @param height
+     *            the height of scaled Image.
+     * @param hints
+     *            the constant which indicates scaling algorithm.
+     * @return the scaled Image.
+     */
+    public Image getScaledInstance(int width, int height, int hints) {
+        ImageFilter filter;
+        if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
+            filter = new AreaAveragingScaleFilter(width, height);
+        } else {
+            filter = new ReplicateScaleFilter(width, height);
+        }
+        ImageProducer producer = new FilteredImageSource(getSource(), filter);
+        return Toolkit.getDefaultToolkit().createImage(producer);
+    }
+
+    /**
+     * Gets a Graphics object for rendering this image. This method can be used
+     * for off-screen images.
+     * 
+     * @return a Graphics object for rendering to this image.
+     */
+    public abstract Graphics getGraphics();
+
+    /**
+     * Flushes resources which are used by this Image object. This method resets
+     * the image to the reconstructed state from the image's source.
+     */
+    public abstract void flush();
+
+    /**
+     * Gets the acceleration priority of this image.
+     * 
+     * @return the acceleration priority of this image.
+     */
+    public float getAccelerationPriority() {
+        return accelerationPriority;
+    }
+
+    /**
+     * Sets the acceleration priority for this image.
+     * 
+     * @param priority
+     *            the new acceleration priority (value in the range 0-1).
+     */
+    public void setAccelerationPriority(float priority) {
+        if (priority < 0 || priority > 1) {
+            // awt.10A=Priority must be a value between 0 and 1, inclusive
+            throw new IllegalArgumentException(Messages.getString("awt.10A")); //$NON-NLS-1$
+        }
+        accelerationPriority = priority;
+    }
+
+    /**
+     * Gets an ImageCapabilities object of this Image object for the specified
+     * GraphicsConfiguration.
+     * 
+     * @param gc
+     *            the specified GraphicsConfiguration object (null value means
+     *            default GraphicsConfiguration).
+     * @return an ImageCapabilities object of this Image object for the
+     *         specified GraphicsConfiguration.
+     */
+    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+        // Note: common image is not accelerated.
+        return capabilities;
+    }
+}
diff --git a/awt/java/awt/ImageCapabilities.java b/awt/java/awt/ImageCapabilities.java
new file mode 100644
index 0000000..c6d5946
--- /dev/null
+++ b/awt/java/awt/ImageCapabilities.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
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The ImageCapabilities class gives information about an image's capabilities.
+ * 
+ * @since Android 1.0
+ */
+public class ImageCapabilities implements Cloneable {
+
+    /**
+     * The accelerated.
+     */
+    private final boolean accelerated;
+
+    /**
+     * Instantiates a new ImageCapabilities with the specified acceleration flag
+     * which indicates whether acceleration is desired or not.
+     * 
+     * @param accelerated
+     *            the accelerated flag.
+     */
+    public ImageCapabilities(boolean accelerated) {
+        this.accelerated = accelerated;
+    }
+
+    /**
+     * Returns a copy of this ImageCapabilities object.
+     * 
+     * @return the copy of this ImageCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new ImageCapabilities(accelerated);
+    }
+
+    /**
+     * Returns true if the Image of this ImageCapabilities is or can be
+     * accelerated.
+     * 
+     * @return true, if the Image of this ImageCapabilities is or can be
+     *         accelerated, false otherwise.
+     */
+    public boolean isAccelerated() {
+        return accelerated;
+    }
+
+    /**
+     * Returns true if this ImageCapabilities applies to the VolatileImage which
+     * can lose its surfaces.
+     * 
+     * @return true if this ImageCapabilities applies to the VolatileImage which
+     *         can lose its surfaces, false otherwise.
+     */
+    public boolean isTrueVolatile() {
+        return true;
+    }
+}
diff --git a/awt/java/awt/Insets.java b/awt/java/awt/Insets.java
new file mode 100644
index 0000000..04f198c
--- /dev/null
+++ b/awt/java/awt/Insets.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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Insets class represents the borders of a container. This class describes
+ * the space that a container should leave at each edge: the top, the bottom,
+ * the right side, and the left side. The space can be filled with a border, a
+ * blank space, or a title.
+ * 
+ * @since Android 1.0
+ */
+public class Insets implements Cloneable, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -2272572637695466749L;
+
+    /**
+     * The top inset indicates the size of the space added to the top of the
+     * rectangle.
+     */
+    public int top;
+
+    /**
+     * The left inset indicates the size of the space added to the left side of
+     * the rectangle.
+     */
+    public int left;
+
+    /**
+     * The bottom inset indicates the size of the space subtracted from the
+     * bottom of the rectangle.
+     */
+    public int bottom;
+
+    /**
+     * The right inset indicates the size of the space subtracted from the right
+     * side of the rectangle.
+     */
+    public int right;
+
+    /**
+     * Instantiates a new Inset object with the specified top, left, bottom,
+     * right parameters.
+     * 
+     * @param top
+     *            the top inset.
+     * @param left
+     *            the left inset.
+     * @param bottom
+     *            the bottom inset.
+     * @param right
+     *            the right inset.
+     */
+    public Insets(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Returns a hash code of the Insets object.
+     * 
+     * @return a hash code of the Insets object.
+     */
+    @Override
+    public int hashCode() {
+        int hashCode = HashCode.EMPTY_HASH_CODE;
+        hashCode = HashCode.combine(hashCode, top);
+        hashCode = HashCode.combine(hashCode, left);
+        hashCode = HashCode.combine(hashCode, bottom);
+        hashCode = HashCode.combine(hashCode, right);
+        return hashCode;
+    }
+
+    /**
+     * Returns a copy of this Insets object.
+     * 
+     * @return a copy of this Insets object.
+     */
+    @Override
+    public Object clone() {
+        return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * Checks if this Insets object is equal to the specified object.
+     * 
+     * @param o
+     *            the Object to be compared.
+     * @return true, if the object is an Insets object whose data values are
+     *         equal to those of this object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof Insets) {
+            Insets i = (Insets)o;
+            return ((i.left == left) && (i.bottom == bottom) && (i.right == right) && (i.top == top));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a String representation of this Insets object.
+     * 
+     * @return a String representation of this Insets object.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code: System.out.println(new Insets(1, 2, 3, 4));
+         */
+
+        return (getClass().getName() + "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
+                ",right=" + right + ",bottom=" + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets top, left, bottom, and right insets to the specified values.
+     * 
+     * @param top
+     *            the top inset.
+     * @param left
+     *            the left inset.
+     * @param bottom
+     *            the bottom inset.
+     * @param right
+     *            the right inset.
+     */
+    public void set(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Sets the values.
+     * 
+     * @param top
+     *            the top.
+     * @param left
+     *            the left.
+     * @param bottom
+     *            the bottom.
+     * @param right
+     *            the right.
+     */
+    private void setValues(int top, int left, int bottom, int right) {
+        this.top = top;
+        this.left = left;
+        this.bottom = bottom;
+        this.right = right;
+    }
+}
diff --git a/awt/java/awt/ItemSelectable.java b/awt/java/awt/ItemSelectable.java
new file mode 100644
index 0000000..212cf70
--- /dev/null
+++ b/awt/java/awt/ItemSelectable.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 Michael Danilov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.event.ItemListener;
+
+/**
+ * The ItemSelectable interface represents a set of items which can be selected.
+ * 
+ * @since Android 1.0
+ */
+public interface ItemSelectable {
+
+    /**
+     * Adds an ItemListener for receiving item events when the state of an item
+     * is changed by the user.
+     * 
+     * @param l
+     *            the ItemListener.
+     */
+    public void addItemListener(ItemListener l);
+
+    /**
+     * Gets an array of the selected objects or null if there is no selected
+     * object.
+     * 
+     * @return an array of the selected objects or null if there is no selected
+     *         object.
+     */
+    public Object[] getSelectedObjects();
+
+    /**
+     * Removes the specified ItemListener.
+     * 
+     * @param l
+     *            the ItemListener which will be removed.
+     */
+    public void removeItemListener(ItemListener l);
+
+}
diff --git a/awt/java/awt/MenuComponent.java b/awt/java/awt/MenuComponent.java
new file mode 100644
index 0000000..9c1b120
--- /dev/null
+++ b/awt/java/awt/MenuComponent.java
@@ -0,0 +1,783 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.awt.peer.MenuComponentPeer;
+import java.io.Serializable;
+import java.util.Locale; //import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleSelection;
+//import javax.accessibility.AccessibleStateSet;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.state.MenuItemState;
+import org.apache.harmony.awt.state.MenuState;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ * The MenuComponent abstract class is the superclass for menu components. Menu
+ * components receive and process AWT events.
+ * 
+ * @since Android 1.0
+ */
+public abstract class MenuComponent implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -4536902356223894379L;
+
+    /**
+     * The name.
+     */
+    private String name;
+
+    /**
+     * The font.
+     */
+    private Font font;
+
+    /**
+     * The parent.
+     */
+    MenuContainer parent;
+
+    /**
+     * The deprecated event handler.
+     */
+    boolean deprecatedEventHandler = true;
+
+    /**
+     * The selected item index.
+     */
+    private int selectedItemIndex;
+
+    // ???AWT: private AccessibleContext accessibleContext;
+
+    /**
+     * The toolkit.
+     */
+    final Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    // ???AWT
+    /*
+     * protected abstract class AccessibleAWTMenuComponent extends
+     * AccessibleContext implements Serializable, AccessibleComponent,
+     * AccessibleSelection { private static final long serialVersionUID =
+     * -4269533416223798698L; public void addFocusListener(FocusListener
+     * listener) { } public boolean contains(Point pt) { return false; } public
+     * Accessible getAccessibleAt(Point pt) { return null; } public Color
+     * getBackground() { return null; } public Rectangle getBounds() { return
+     * null; } public Cursor getCursor() { return null; } public Font getFont()
+     * { return MenuComponent.this.getFont(); } public FontMetrics
+     * getFontMetrics(Font font) { return null; } public Color getForeground() {
+     * return null; } public Point getLocation() { return null; } public Point
+     * getLocationOnScreen() { return null; } public Dimension getSize() {
+     * return null; } public boolean isEnabled() { return true; // always
+     * enabled } public boolean isFocusTraversable() { return true; // always
+     * focus traversable } public boolean isShowing() { return true;// always
+     * showing } public boolean isVisible() { return true; // always visible }
+     * public void removeFocusListener(FocusListener listener) { } public void
+     * requestFocus() { } public void setBackground(Color color) { } public void
+     * setBounds(Rectangle rect) { } public void setCursor(Cursor cursor) { }
+     * public void setEnabled(boolean enabled) { } public void setFont(Font
+     * font) { MenuComponent.this.setFont(font); } public void
+     * setForeground(Color color) { } public void setLocation(Point pt) { }
+     * public void setSize(Dimension pt) { } public void setVisible(boolean
+     * visible) { } public void addAccessibleSelection(int index) { } public
+     * void clearAccessibleSelection() { } public Accessible
+     * getAccessibleSelection(int index) { return null; } public int
+     * getAccessibleSelectionCount() { return 0; } public boolean
+     * isAccessibleChildSelected(int index) { return false; } public void
+     * removeAccessibleSelection(int index) { } public void
+     * selectAllAccessibleSelection() { }
+     * @Override public Accessible getAccessibleChild(int index) { return null;
+     * }
+     * @Override public int getAccessibleChildrenCount() { return 0; }
+     * @Override public AccessibleComponent getAccessibleComponent() { return
+     * this; }
+     * @Override public String getAccessibleDescription() { return
+     * super.getAccessibleDescription(); }
+     * @Override public int getAccessibleIndexInParent() { toolkit.lockAWT();
+     * try { Accessible aParent = getAccessibleParent(); int aIndex = -1; if
+     * (aParent instanceof MenuComponent) { MenuComponent parent =
+     * (MenuComponent) aParent; int count = parent.getItemCount(); for (int i =
+     * 0; i < count; i++) { MenuComponent comp = parent.getItem(i); if (comp
+     * instanceof Accessible) { aIndex++; if (comp == MenuComponent.this) {
+     * return aIndex; } } } } return -1; } finally { toolkit.unlockAWT(); } }
+     * @Override public String getAccessibleName() { return
+     * super.getAccessibleName(); }
+     * @Override public Accessible getAccessibleParent() { toolkit.lockAWT();
+     * try { Accessible aParent = super.getAccessibleParent(); if (aParent !=
+     * null) { return aParent; } MenuContainer parent = getParent(); if (parent
+     * instanceof Accessible) { aParent = (Accessible) parent; } return aParent;
+     * } finally { toolkit.unlockAWT(); } }
+     * @Override public AccessibleRole getAccessibleRole() { return
+     * AccessibleRole.AWT_COMPONENT; }
+     * @Override public AccessibleSelection getAccessibleSelection() { return
+     * this; }
+     * @Override public AccessibleStateSet getAccessibleStateSet() { return new
+     * AccessibleStateSet(); }
+     * @Override public Locale getLocale() { return Locale.getDefault(); } }
+     */
+
+    /**
+     * The accessor to MenuComponent internal state, utilized by the visual
+     * theme.
+     * 
+     * @throws HeadlessException
+     *             the headless exception.
+     */
+    // ???AWT
+    /*
+     * class State implements MenuState { Dimension size; Dimension getSize() {
+     * if (size == null) { calculate(); } return size; } public int getWidth() {
+     * return getSize().width; } public int getHeight() { return
+     * getSize().height; } public Font getFont() { return
+     * MenuComponent.this.getFont(); } public int getItemCount() { return
+     * MenuComponent.this.getItemCount(); } public int getSelectedItemIndex() {
+     * return MenuComponent.this.getSelectedItemIndex(); } public boolean
+     * isFontSet() { return MenuComponent.this.isFontSet(); }
+     * @SuppressWarnings("deprecation") public FontMetrics getFontMetrics(Font
+     * f) { return MenuComponent.this.toolkit.getFontMetrics(f); } public Point
+     * getLocation() { return MenuComponent.this.getLocation(); } public
+     * MenuItemState getItem(int index) { MenuItem item =
+     * MenuComponent.this.getItem(index); return item.itemState; } public void
+     * setSize(int w, int h) { this.size = new Dimension(w, h); } void
+     * calculate() { size = new Dimension();
+     * size.setSize(toolkit.theme.calculateMenuSize(this)); } void reset() { for
+     * (int i = 0; i < getItemCount(); i++) { ((MenuItem.State)
+     * getItem(i)).reset(); } } }
+     */
+
+    /**
+     * Pop-up box for menu. It transfers the paint events, keyboard and mouse
+     * events to the menu component itself.
+     */
+    // ???AWT
+    /*
+     * class MenuPopupBox extends PopupBox { private final Point lastMousePos =
+     * new Point();
+     * @Override boolean isMenu() { return true; }
+     * @Override void paint(Graphics gr) { MenuComponent.this.paint(gr); }
+     * @Override void onKeyEvent(int eventId, int vKey, long when, int
+     * modifiers) { MenuComponent.this.onKeyEvent(eventId, vKey, when,
+     * modifiers); }
+     * @Override void onMouseEvent(int eventId, Point where, int mouseButton,
+     * long when, int modifiers, int wheelRotation) { // prevent conflict of
+     * mouse and keyboard // when sub-menu drops down due to keyboard navigation
+     * if (lastMousePos.equals(where) && (eventId == MouseEvent.MOUSE_MOVED ||
+     * eventId == MouseEvent.MOUSE_ENTERED)) { return; }
+     * lastMousePos.setLocation(where); MenuComponent.this.onMouseEvent(eventId,
+     * where, mouseButton, when, modifiers); } }
+     */
+
+    /**
+     * Instantiates a new MenuComponent object.
+     * 
+     * @throws HeadlessException
+     *             if the graphical interface environment can't support
+     *             MenuComponents.
+     */
+    public MenuComponent() throws HeadlessException {
+        toolkit.lockAWT();
+        try {
+            Toolkit.checkHeadless();
+            name = autoName();
+            selectedItemIndex = -1;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the name of the MenuComponent object.
+     * 
+     * @return the name of the MenuComponent object.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns a String representation of the MenuComponent object.
+     * 
+     * @return a String representation of the MenuComponent object.
+     */
+    @Override
+    public String toString() {
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the parent menu container.
+     * 
+     * @return the parent.
+     */
+    public MenuContainer getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the name of the MenuComponent to the specified string.
+     * 
+     * @param name
+     *            the new name of the MenuComponent object.
+     */
+    public void setName(String name) {
+        toolkit.lockAWT();
+        try {
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatches AWT event.
+     * 
+     * @param event
+     *            the AWTEvent.
+     */
+    public final void dispatchEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            processEvent(event);
+            if (deprecatedEventHandler) {
+                postDeprecatedEvent(event);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param event
+     *            the event.
+     */
+    void postDeprecatedEvent(AWTEvent event) {
+        Event evt = event.getEvent();
+        if (evt != null) {
+            postEvent(evt);
+        }
+    }
+
+    /**
+     * Gets the peer of the MenuComponent; an application must not use this
+     * method directly.
+     * 
+     * @return the MenuComponentPeer object.
+     * @throws NotImplementedException
+     *             if this method is not implemented by a subclass.
+     * @deprecated an application must not use this method directly.
+     */
+    @Deprecated
+    public MenuComponentPeer getPeer() throws org.apache.harmony.luni.util.NotImplementedException {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Gets the locking object of this MenuComponent.
+     * 
+     * @return the locking object of this MenuComponent.
+     */
+    protected final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * Posts the Event to the MenuComponent.
+     * 
+     * @param e
+     *            the Event.
+     * @return true, if the event is posted successfully, false otherwise.
+     * @deprecated Replaced dispatchEvent method.
+     */
+    @SuppressWarnings("deprecation")
+    @Deprecated
+    public boolean postEvent(Event e) {
+        toolkit.lockAWT();
+        try {
+            if (parent != null) {
+                return parent.postEvent(e);
+            }
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the string representation of the MenuComponent state.
+     * 
+     * @return returns the string representation of the MenuComponent state.
+     */
+    protected String paramString() {
+        toolkit.lockAWT();
+        try {
+            return getName();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    // ???AWT
+    /*
+     * public AccessibleContext getAccessibleContext() { toolkit.lockAWT(); try
+     * { if (accessibleContext == null) { accessibleContext =
+     * createAccessibleContext(); } return accessibleContext; } finally {
+     * toolkit.unlockAWT(); } }
+     */
+
+    /**
+     * Gets the font of the MenuComponent object.
+     * 
+     * @return the Font of the MenuComponent object.
+     */
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            if (font == null && hasDefaultFont()) {
+                return toolkit.getDefaultFont();
+            }
+            if (font == null && parent != null) {
+                return parent.getFont();
+            }
+            return font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if is font set.
+     * 
+     * @return true, if is font set
+     */
+    boolean isFontSet() {
+        return font != null
+                || ((parent instanceof MenuComponent) && ((MenuComponent)parent).isFontSet());
+    }
+
+    /**
+     * Checks for default font.
+     * 
+     * @return true, if successful.
+     */
+    boolean hasDefaultFont() {
+        return false;
+    }
+
+    /**
+     * Processes an AWTEevent on this menu component.
+     * 
+     * @param event
+     *            the AWTEvent.
+     */
+    protected void processEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            // do nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the peer of the MenuComponent.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the Font for this MenuComponent object.
+     * 
+     * @param font
+     *            the new Font to be used for this MenuComponent.
+     */
+    public void setFont(Font font) {
+        toolkit.lockAWT();
+        try {
+            this.font = font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the parent.
+     * 
+     * @param parent
+     *            the new parent.
+     */
+    void setParent(MenuContainer parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Gets the location.
+     * 
+     * @return the location.
+     */
+    Point getLocation() {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width.
+     */
+    int getWidth() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height.
+     */
+    int getHeight() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Recursively find the menu item for a menu shortcut.
+     * 
+     * @param gr
+     *            the gr.
+     * @return the menu item; or null if the item is not available for this
+     *         shortcut.
+     */
+    // ???AWT
+    /*
+     * MenuItem getShortcutMenuItemImpl(MenuShortcut ms) { if (ms == null) {
+     * return null; } for (int i = 0; i < getItemCount(); i++) { MenuItem mi =
+     * getItem(i); if (mi instanceof Menu) { mi = ((Menu)
+     * mi).getShortcutMenuItemImpl(ms); if (mi != null) { return mi; } } else if
+     * (ms.equals(mi.getShortcut())) { return mi; } } return null; }
+     */
+
+    void paint(Graphics gr) {
+        gr.setColor(Color.LIGHT_GRAY);
+        gr.fillRect(0, 0, getWidth(), getHeight());
+        gr.setColor(Color.BLACK);
+    }
+
+    /**
+     * Mouse events handler.
+     * 
+     * @param eventId
+     *            one of the MouseEvent.MOUSE_* constants.
+     * @param where
+     *            mouse location.
+     * @param mouseButton
+     *            mouse button that was pressed or released.
+     * @param when
+     *            event time.
+     * @param modifiers
+     *            input event modifiers.
+     */
+    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Keyboard event handler.
+     * 
+     * @param eventId
+     *            one of the KeyEvent.KEY_* constants.
+     * @param vKey
+     *            the key code.
+     * @param when
+     *            event time.
+     * @param modifiers
+     *            input event modifiers.
+     */
+    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Post the ActionEvent or ItemEvent, depending on type of the menu item.
+     * 
+     * @param index
+     *            the index.
+     * @return the item rect.
+     */
+    // ???AWT
+    /*
+     * void fireItemAction(int item, long when, int modifiers) { MenuItem mi =
+     * getItem(item); mi.itemSelected(when, modifiers); } MenuItem getItem(int
+     * index) { // to be overridden return null; } int getItemCount() { return
+     * 0; }
+     */
+
+    /**
+     * @return The sub-menu of currently selecetd item, or null if such a
+     *         sub-menu is not available.
+     */
+    // ???AWT
+    /*
+     * Menu getSelectedSubmenu() { if (selectedItemIndex < 0) { return null; }
+     * MenuItem item = getItem(selectedItemIndex); return (item instanceof Menu)
+     * ? (Menu) item : null; }
+     */
+
+    /**
+     * Convenience method for selectItem(index, true).
+     */
+    // ???AWT
+    /*
+     * void selectItem(int index) { selectItem(index, true); }
+     */
+
+    /**
+     * Change the selection in the menu.
+     * 
+     * @param index
+     *            new selecetd item's index.
+     * @param showSubMenu
+     *            if new selected item has a sub-menu, should that sub-menu be
+     *            displayed.
+     */
+    // ???AWT
+    /*
+     * void selectItem(int index, boolean showSubMenu) { if (selectedItemIndex
+     * == index) { return; } if (selectedItemIndex >= 0 &&
+     * getItem(selectedItemIndex) instanceof Menu) { ((Menu)
+     * getItem(selectedItemIndex)).hide(); } MultiRectArea clip =
+     * getUpdateClip(index, selectedItemIndex); selectedItemIndex = index;
+     * Graphics gr = getGraphics(clip); if (gr != null) { paint(gr); } if
+     * (showSubMenu) { showSubMenu(selectedItemIndex); } }
+     */
+
+    /**
+     * Change the selected item to the next one in the requested direction
+     * moving cyclically, skipping separators
+     * 
+     * @param forward
+     *            the direction to move the selection.
+     * @param showSubMenu
+     *            if new selected item has a sub-menu, should that sub-menu be
+     *            displayed.
+     */
+    // ???AWT
+    /*
+     * void selectNextItem(boolean forward, boolean showSubMenu) { int selected
+     * = getSelectedItemIndex(); int count = getItemCount(); if (count == 0) {
+     * return; } if (selected < 0) { selected = (forward ? count - 1 : 0); } int
+     * i = selected; do { i = (forward ? (i + 1) : (i + count - 1)) % count; i
+     * %= count; MenuItem item = getItem(i); if (!"-".equals(item.getLabel())) {
+     * //$NON-NLS-1$ selectItem(i, showSubMenu); return; } } while (i !=
+     * selected); } void showSubMenu(int index) { if ((index < 0) ||
+     * !isActive()) { return; } MenuItem item = getItem(index); if (item
+     * instanceof Menu) { Menu menu = ((Menu) getItem(index)); if
+     * (menu.getItemCount() == 0) { return; } Point location =
+     * getSubmenuLocation(index); menu.show(location.x, location.y, false); } }
+     */
+
+    /**
+     * @return the menu bar which is the root of current menu's hierarchy; or
+     *         null if the hierarchy root is not a menu bar.
+     */
+    // ???AWT
+    /*
+     * MenuBar getMenuBar() { if (parent instanceof MenuBar) { return (MenuBar)
+     * parent; } if (parent instanceof MenuComponent) { return ((MenuComponent)
+     * parent).getMenuBar(); } return null; } PopupBox getPopupBox() { return
+     * null; }
+     */
+
+    Rectangle getItemRect(int index) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * Determine the clip region when menu selection is changed from index1 to
+     * index2.
+     * 
+     * @param index1
+     *            old selected item.
+     * @param index2
+     *            new selected item.
+     * @return the region to repaint.
+     */
+    final MultiRectArea getUpdateClip(int index1, int index2) {
+        MultiRectArea clip = new MultiRectArea();
+        if (index1 >= 0) {
+            clip.add(getItemRect(index1));
+        }
+        if (index2 >= 0) {
+            clip.add(getItemRect(index2));
+        }
+        return clip;
+    }
+
+    /**
+     * Gets the submenu location.
+     * 
+     * @param index
+     *            the index.
+     * @return the submenu location.
+     */
+    Point getSubmenuLocation(int index) {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the selected item index.
+     * 
+     * @return the selected item index.
+     */
+    int getSelectedItemIndex() {
+        return selectedItemIndex;
+    }
+
+    /**
+     * Hide.
+     */
+    void hide() {
+        selectedItemIndex = -1;
+        if (parent instanceof MenuComponent) {
+            ((MenuComponent)parent).itemHidden(this);
+        }
+    }
+
+    /**
+     * Item hidden.
+     * 
+     * @param mc
+     *            the mc.
+     */
+    void itemHidden(MenuComponent mc) {
+        // to be overridden
+    }
+
+    /**
+     * Checks if is visible.
+     * 
+     * @return true, if is visible.
+     */
+    boolean isVisible() {
+        return true;
+    }
+
+    /**
+     * Checks if is active.
+     * 
+     * @return true, if is active.
+     */
+    boolean isActive() {
+        return true;
+    }
+
+    /**
+     * Hide all menu hierarchy.
+     */
+    void endMenu() {
+        // ???AWT: toolkit.dispatcher.popupDispatcher.deactivateAll();
+    }
+
+    /**
+     * Handle the mouse click or Enter key event on a menu's item.
+     * 
+     * @param when
+     *            the event time.
+     * @param modifiers
+     *            input event modifiers.
+     */
+    void itemSelected(long when, int modifiers) {
+        endMenu();
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string.
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        // ???AWT: int number = toolkit.autoNumber.nextMenuComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Creates the Graphics object for the pop-up box of this menu component.
+     * 
+     * @param clip
+     *            the clip to set on this Graphics.
+     * @return the created Graphics object, or null if such object is not
+     *         available.
+     */
+    Graphics getGraphics(MultiRectArea clip) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * @return accessible context specific for particular menu component.
+     */
+    // ???AWT
+    /*
+     * AccessibleContext createAccessibleContext() { return null; }
+     */
+}
diff --git a/awt/java/awt/MenuContainer.java b/awt/java/awt/MenuContainer.java
new file mode 100644
index 0000000..e509a1b
--- /dev/null
+++ b/awt/java/awt/MenuContainer.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 Pavel Dolgov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The MenuContainer interface represents all menu containers.
+ * 
+ * @since Android 1.0
+ */
+public interface MenuContainer {
+
+    /**
+     * Removes the specified MenuComponent from the MenuContainer.
+     * 
+     * @param c
+     *            the MenuComponent.
+     */
+    public void remove(MenuComponent c);
+
+    /**
+     * Gets the Font of the MenuContainer.
+     * 
+     * @return the font of the MenuContainer.
+     */
+    public Font getFont();
+
+    /**
+     * Posts an Event.
+     * 
+     * @param e
+     *            the Event.
+     * @return true if the event is posted successfully, false otherwise.
+     * @deprecated Replaced by dispatchEvent method.
+     */
+    @Deprecated
+    public boolean postEvent(Event e);
+
+}
diff --git a/awt/java/awt/ModalContext.java b/awt/java/awt/ModalContext.java
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..dfea3a7
--- /dev/null
+++ b/awt/java/awt/Paint.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+/**
+ * The Paint interface provides possibility of generating color patterns in
+ * device space for fill, draw, or stroke operations in a Graphics2D.
+ * 
+ * @since Android 1.0
+ */
+public interface Paint extends Transparency {
+
+    /**
+     * Creates the PaintContext which is used to generate color patterns for
+     * rendering operations of Graphics2D.
+     * 
+     * @param cm
+     *            the ColorModel object, or null.
+     * @param deviceBounds
+     *            the Rectangle represents the bounding box of device space for
+     *            the graphics rendering operations.
+     * @param userBounds
+     *            the Rectangle represents bounding box of user space for the
+     *            graphics rendering operations.
+     * @param xform
+     *            the AffineTransform for translation from user space to device
+     *            space.
+     * @param hints
+     *            the RenderingHints preferences.
+     * @return the PaintContext for generating color patterns.
+     */
+    PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
+            AffineTransform xform, RenderingHints hints);
+}
diff --git a/awt/java/awt/PaintContext.java b/awt/java/awt/PaintContext.java
new file mode 100644
index 0000000..966b6ca
--- /dev/null
+++ b/awt/java/awt/PaintContext.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.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * The PaintContext interface determines the specific environment for generating
+ * color patterns in device space for fill, draw, or stroke rendering operations
+ * using Graphics2D. This interface provides colors through the Raster object
+ * associated with the specific ColorModel for Graphics2D rendering operations.
+ * 
+ * @since Android 1.0
+ */
+public interface PaintContext {
+
+    /**
+     * Releases the resources allocated for the operation.
+     */
+    void dispose();
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel object.
+     */
+    ColorModel getColorModel();
+
+    /**
+     * Gets the Raster which defines the colors of the specified rectangular
+     * area for Graphics2D rendering operations.
+     * 
+     * @param x
+     *            the X coordinate of the device space area for which colors are
+     *            generated.
+     * @param y
+     *            the Y coordinate of the device space area for which colors are
+     *            generated.
+     * @param w
+     *            the width of the device space area for which colors are
+     *            generated.
+     * @param h
+     *            the height of the device space area for which colors are
+     *            generated.
+     * @return the Raster object which contains the colors of the specified
+     *         rectangular area for Graphics2D rendering operations.
+     */
+    Raster getRaster(int x, int y, int w, int h);
+}
diff --git a/awt/java/awt/Point.java b/awt/java/awt/Point.java
new file mode 100644
index 0000000..8ec4241
--- /dev/null
+++ b/awt/java/awt/Point.java
@@ -0,0 +1,211 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+/**
+ * The Point class represents a point location with coordinates X, Y in current
+ * coordinate system.
+ * 
+ * @since Android 1.0
+ */
+public class Point extends Point2D implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -5276940640259749850L;
+
+    /**
+     * The X coordinate of Point.
+     */
+    public int x;
+
+    /**
+     * The Y coordinate of Point.
+     */
+    public int y;
+
+    /**
+     * Instantiates a new point with (0, O) coordinates, the origin of
+     * coordinate system.
+     */
+    public Point() {
+        setLocation(0, 0);
+    }
+
+    /**
+     * Instantiates a new point with (x, y) coordinates.
+     * 
+     * @param x
+     *            the X coordinate of Point.
+     * @param y
+     *            the Y coordinate of Point.
+     */
+    public Point(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Instantiates a new point, giving it the same location as the parameter p.
+     * 
+     * @param p
+     *            the Point object giving the coordinates of the new point.
+     */
+    public Point(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Compares current Point with the specified object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the Object being compared is a Point whose coordinates
+     *         are equal to the coordinates of this Point, false otherwise.
+     * @see java.awt.geom.Point2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point) {
+            Point p = (Point)obj;
+            return x == p.x && y == p.y;
+        }
+        return false;
+    }
+
+    /**
+     * Returns string representation of the current Point object.
+     * 
+     * @return a string representation of the current Point object.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Gets X coordinate of Point as a double.
+     * 
+     * @return X coordinate of the point as a double.
+     * @see java.awt.geom.Point2D#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets Y coordinate of Point as a double.
+     * 
+     * @return Y coordinate of the point as a double.
+     * @see java.awt.geom.Point2D#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the location of the Point as a new Point object.
+     * 
+     * @return a copy of the Point.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the Point to the same coordinates as p.
+     * 
+     * @param p
+     *            the Point that gives the new location.
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Sets the location of the Point to the coordinates X, Y.
+     * 
+     * @param x
+     *            the X coordinate of the Point's new location.
+     * @param y
+     *            the Y coordinate of the Point's new location.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of Point to the specified double coordinates.
+     * 
+     * @param x
+     *            the X the Point's new location.
+     * @param y
+     *            the Y the Point's new location.
+     * @see java.awt.geom.Point2D#setLocation(double, double)
+     */
+    @Override
+    public void setLocation(double x, double y) {
+        x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                : x;
+        y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE
+                : y;
+        setLocation((int)Math.round(x), (int)Math.round(y));
+    }
+
+    /**
+     * Moves the Point to the specified (x, y) location.
+     * 
+     * @param x
+     *            the X coordinate of the new location.
+     * @param y
+     *            the Y coordinate of the new location.
+     */
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Translates current Point moving it from the position (x, y) to the new
+     * position given by (x+dx, x+dy) coordinates.
+     * 
+     * @param dx
+     *            the horizontal delta - the Point is moved to this distance
+     *            along X axis.
+     * @param dy
+     *            the vertical delta - the Point is moved to this distance along
+     *            Y axis.
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+}
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
new file mode 100644
index 0000000..de31eb9
--- /dev/null
+++ b/awt/java/awt/Polygon.java
@@ -0,0 +1,515 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Polygon class defines an closed area specified by n vertices and n edges.
+ * The coordinates of the vertices are specified by x, y arrays. The edges are
+ * the line segments from the point (x[i], y[i]) to the point (x[i+1], y[i+1]),
+ * for -1 < i < (n-1) plus the line segment from the point (x[n-1], y[n-1]) to
+ * the point (x[0], y[0]) point. The Polygon is empty if the number of vertices
+ * is zero.
+ * 
+ * @since Android 1.0
+ */
+public class Polygon implements Shape, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -6460061437900069969L;
+
+    /**
+     * The points buffer capacity.
+     */
+    private static final int BUFFER_CAPACITY = 4;
+
+    /**
+     * The number of Polygon vertices.
+     */
+    public int npoints;
+
+    /**
+     * The array of X coordinates of the vertices.
+     */
+    public int[] xpoints;
+
+    /**
+     * The array of Y coordinates of the vertices.
+     */
+    public int[] ypoints;
+
+    /**
+     * The smallest Rectangle that completely contains this Polygon.
+     */
+    protected Rectangle bounds;
+
+    /*
+     * Polygon path iterator
+     */
+    /**
+     * The internal Class Iterator.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The source Polygon object.
+         */
+        public Polygon p;
+
+        /**
+         * The path iterator transformation.
+         */
+        public AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        public int index;
+
+        /**
+         * Constructs a new Polygon.Iterator for the given polygon and
+         * transformation
+         * 
+         * @param at
+         *            the AffineTransform object to apply rectangle path.
+         * @param p
+         *            the p.
+         */
+        public Iterator(AffineTransform at, Polygon p) {
+            this.p = p;
+            this.t = at;
+            if (p.npoints == 0) {
+                index = 1;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_EVEN_ODD;
+        }
+
+        public boolean isDone() {
+            return index > p.npoints;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+    }
+
+    /**
+     * Instantiates a new empty polygon.
+     */
+    public Polygon() {
+        xpoints = new int[BUFFER_CAPACITY];
+        ypoints = new int[BUFFER_CAPACITY];
+    }
+
+    /**
+     * Instantiates a new polygon with the specified number of vertices, and the
+     * given arrays of x, y vertex coordinates. The length of each coordinate
+     * array may not be less than the specified number of vertices but may be
+     * greater. Only the first n elements are used from each coordinate array.
+     * 
+     * @param xpoints
+     *            the array of X vertex coordinates.
+     * @param ypoints
+     *            the array of Y vertex coordinates.
+     * @param npoints
+     *            the number vertices of the polygon.
+     * @throws IndexOutOfBoundsException
+     *             if the length of xpoints or ypoints is less than n.
+     * @throws NegativeArraySizeException
+     *             if n is negative.
+     */
+    public Polygon(int[] xpoints, int[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            // awt.111=Parameter npoints is greater than array length
+            throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
+        }
+        if (npoints < 0) {
+            // awt.112=Negative number of points
+            throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
+        }
+        this.npoints = npoints;
+        this.xpoints = new int[npoints];
+        this.ypoints = new int[npoints];
+        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+    }
+
+    /**
+     * Resets the current Polygon to an empty Polygon. More precisely, the
+     * number of Polygon vertices is set to zero, but x, y coordinates arrays
+     * are not affected.
+     */
+    public void reset() {
+        npoints = 0;
+        bounds = null;
+    }
+
+    /**
+     * Invalidates the data that depends on the vertex coordinates. This method
+     * should be called after direct manipulations of the x, y vertex
+     * coordinates arrays to avoid unpredictable results of methods which rely
+     * on the bounding box.
+     */
+    public void invalidate() {
+        bounds = null;
+    }
+
+    /**
+     * Adds the point to the Polygon and updates the bounding box accordingly.
+     * 
+     * @param px
+     *            the X coordinate of the added vertex.
+     * @param py
+     *            the Y coordinate of the added vertex.
+     */
+    public void addPoint(int px, int py) {
+        if (npoints == xpoints.length) {
+            int[] tmp;
+
+            tmp = new int[xpoints.length + BUFFER_CAPACITY];
+            System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
+            xpoints = tmp;
+
+            tmp = new int[ypoints.length + BUFFER_CAPACITY];
+            System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
+            ypoints = tmp;
+        }
+
+        xpoints[npoints] = px;
+        ypoints[npoints] = py;
+        npoints++;
+
+        if (bounds != null) {
+            bounds.setFrameFromDiagonal(Math.min(bounds.getMinX(), px), Math.min(bounds.getMinY(),
+                    py), Math.max(bounds.getMaxX(), px), Math.max(bounds.getMaxY(), py));
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle is the
+     * smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * @see java.awt.Shape#getBounds()
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+        if (npoints == 0) {
+            return new Rectangle();
+        }
+
+        int bx1 = xpoints[0];
+        int by1 = ypoints[0];
+        int bx2 = bx1;
+        int by2 = by1;
+
+        for (int i = 1; i < npoints; i++) {
+            int x = xpoints[i];
+            int y = ypoints[i];
+            if (x < bx1) {
+                bx1 = x;
+            } else if (x > bx2) {
+                bx2 = x;
+            }
+            if (y < by1) {
+                by1 = y;
+            } else if (y > by2) {
+                by2 = y;
+            }
+        }
+
+        return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle is the
+     * smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * @deprecated Use getBounds() method.
+     */
+    @Deprecated
+    public Rectangle getBoundingBox() {
+        return getBounds();
+    }
+
+    /**
+     * Gets the Rectangle2D which represents Polygon bounds. The bounding
+     * rectangle is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * @see java.awt.Shape#getBounds2D()
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds().getBounds2D();
+    }
+
+    /**
+     * Translates all vertices of Polygon the specified distances along X, Y
+     * axis.
+     * 
+     * @param mx
+     *            the distance to translate horizontally.
+     * @param my
+     *            the distance to translate vertically.
+     */
+    public void translate(int mx, int my) {
+        for (int i = 0; i < npoints; i++) {
+            xpoints[i] += mx;
+            ypoints[i] += my;
+        }
+        if (bounds != null) {
+            bounds.translate(mx, my);
+        }
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside
+     * the Polygon.
+     * 
+     * @param x
+     *            the X coordinate of the point to check.
+     * @param y
+     *            the Y coordinate of the point to check.
+     * @return true, if the specified point lies inside the Polygon, false
+     *         otherwise.
+     * @deprecated Use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        return contains((double)x, (double)y);
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside
+     * the Polygon.
+     * 
+     * @param x
+     *            the X coordinate of the point to check.
+     * @param y
+     *            the Y coordinate of the point to check.
+     * @return true, if the specified point lies inside the Polygon, false
+     *         otherwise.
+     */
+    public boolean contains(int x, int y) {
+        return contains((double)x, (double)y);
+    }
+
+    /**
+     * Checks whether or not the point with specified double coordinates lies
+     * inside the Polygon.
+     * 
+     * @param x
+     *            the X coordinate of the point to check.
+     * @param y
+     *            the Y coordinate of the point to check.
+     * @return true, if the point given by the double coordinates lies inside
+     *         the Polygon, false otherwise.
+     * @see java.awt.Shape#contains(double, double)
+     */
+    public boolean contains(double x, double y) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters [x, y,
+     * width, height] lies inside the Polygon.
+     * 
+     * @param x
+     *            the X coordinate of the rectangles's left upper corner as a
+     *            double.
+     * @param y
+     *            the Y coordinate of the rectangles's left upper corner as a
+     *            double.
+     * @param width
+     *            the width of rectangle as a double.
+     * @param height
+     *            the height of rectangle as a double.
+     * @return true, if the specified rectangle lies inside the Polygon, false
+     *         otherwise.
+     * @see java.awt.Shape#contains(double, double, double, double)
+     */
+    public boolean contains(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters [x, y,
+     * width, height] intersects the interior of the Polygon.
+     * 
+     * @param x
+     *            the X coordinate of the rectangles's left upper corner as a
+     *            double.
+     * @param y
+     *            the Y coordinate of the rectangles's left upper corner as a
+     *            double.
+     * @param width
+     *            the width of rectangle as a double.
+     * @param height
+     *            the height of rectangle as a double.
+     * @return true, if the specified rectangle intersects the interior of the
+     *         Polygon, false otherwise.
+     * @see java.awt.Shape#intersects(double, double, double, double)
+     */
+    public boolean intersects(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Polygon.
+     * 
+     * @param rect
+     *            the Rectangle2D object.
+     * @return true, if the specified rectangle lies inside the Polygon, false
+     *         otherwise.
+     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
+     */
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Checks whether or not the specified Point lies inside the Polygon.
+     * 
+     * @param point
+     *            the Point object.
+     * @return true, if the specified Point lies inside the Polygon, false
+     *         otherwise.
+     */
+    public boolean contains(Point point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Polygon.
+     * 
+     * @param point
+     *            the Point2D object.
+     * @return true, if the specified Point2D lies inside the Polygon, false
+     *         otherwise.
+     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
+     */
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the interior of rectangle specified by the
+     * Rectangle2D object intersects the interior of the Polygon.
+     * 
+     * @param rect
+     *            the Rectangle2D object.
+     * @return true, if the Rectangle2D intersects the interior of the Polygon,
+     *         false otherwise.
+     * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
+     */
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of the polygon,
+     * transformed according to the specified AffineTransform.
+     * 
+     * @param t
+     *            the specified AffineTransform object or null.
+     * @return PathIterator object for the Polygon.
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(t, this);
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of the polygon,
+     * transformed according to the specified AffineTransform. The flatness
+     * parameter is ignored.
+     * 
+     * @param t
+     *            the specified AffineTransform object or null.
+     * @param flatness
+     *            the maximum number of the control points for a given curve
+     *            which varies from colinear before a subdivided curve is
+     *            replaced by a straight line connecting the endpoints. This
+     *            parameter is ignored for the Polygon class.
+     * @return PathIterator object for the Polygon.
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform,
+     *      double)
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(t, this);
+    }
+
+}
diff --git a/awt/java/awt/Rectangle.java b/awt/java/awt/Rectangle.java
new file mode 100644
index 0000000..d8ebb3a
--- /dev/null
+++ b/awt/java/awt/Rectangle.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 Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * The Rectangle class defines the rectangular area in terms of its upper left
+ * corner coordinates [x,y], its width, and its height. A Rectangle specified by
+ * [x, y, width, height] parameters has an outline path with corners at [x, y],
+ * [x + width,y], [x + width,y + height], and [x, y + height]. <br>
+ * <br>
+ * The rectangle is empty if the width or height is negative or zero. In this
+ * case the isEmpty method returns true.
+ * 
+ * @since Android 1.0
+ */
+public class Rectangle extends Rectangle2D implements Shape, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -4345857070255674764L;
+
+    /**
+     * The X coordinate of the rectangle's left upper corner.
+     */
+    public int x;
+
+    /**
+     * The Y coordinate of the rectangle's left upper corner.
+     */
+    public int y;
+
+    /**
+     * The width of rectangle.
+     */
+    public int width;
+
+    /**
+     * The height of rectangle.
+     */
+    public int height;
+
+    /**
+     * Instantiates a new rectangle with [0, 0] upper left corner coordinates,
+     * the width and the height are zero.
+     */
+    public Rectangle() {
+        setBounds(0, 0, 0, 0);
+    }
+
+    /**
+     * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and the height are
+     * zero.
+     * 
+     * @param p
+     *            the Point specifies the upper left corner coordinates of the
+     *            rectangle.
+     */
+    public Rectangle(Point p) {
+        setBounds(p.x, p.y, 0, 0);
+    }
+
+    /**
+     * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and the height are
+     * given by Dimension object (d.width and d.height).
+     * 
+     * @param p
+     *            the point specifies the upper left corner coordinates of the
+     *            rectangle.
+     * @param d
+     *            the dimension specifies the width and the height of the
+     *            rectangle.
+     */
+    public Rectangle(Point p, Dimension d) {
+        setBounds(p.x, p.y, d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new rectangle determined by the upper left corner
+     * coordinates (x, y), width and height.
+     * 
+     * @param x
+     *            the X upper left corner coordinate of the rectangle.
+     * @param y
+     *            the Y upper left corner coordinate of the rectangle.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     */
+    public Rectangle(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with [0, 0] as its upper left corner
+     * coordinates and the specified width and height.
+     * 
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     */
+    public Rectangle(int width, int height) {
+        setBounds(0, 0, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with the same coordinates as the given
+     * source rectangle.
+     * 
+     * @param r
+     *            the Rectangle object which parameters will be used for
+     *            instantiating a new Rectangle.
+     */
+    public Rectangle(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+
+    /*
+     * public Rectangle(Dimension d) { setBounds(0, 0, d.width, d.height); }
+     */
+    /**
+     * Gets the X coordinate of bound as a double.
+     * 
+     * @return the X coordinate of bound as a double.
+     * @see java.awt.geom.RectangularShape#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets the Y coordinate of bound as a double.
+     * 
+     * @return the Y coordinate of bound as a double.
+     * @see java.awt.geom.RectangularShape#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the height of the rectangle as a double.
+     * 
+     * @return the height of the rectangle as a double.
+     * @see java.awt.geom.RectangularShape#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the rectangle as a double.
+     * 
+     * @return the width of the rectangle as a double.
+     * @see java.awt.geom.RectangularShape#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+    /**
+     * Determines whether or not the rectangle is empty. The rectangle is empty
+     * if its width or height is negative or zero.
+     * 
+     * @return true, if the rectangle is empty, otherwise false.
+     * @see java.awt.geom.RectangularShape#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return width <= 0 || height <= 0;
+    }
+
+    /**
+     * Gets the size of a Rectangle as Dimension object.
+     * 
+     * @return a Dimension object which represents size of the rectangle.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Sets the size of the Rectangle.
+     * 
+     * @param width
+     *            the new width of the rectangle.
+     * @param height
+     *            the new height of the rectangle.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of a Rectangle specified as Dimension object.
+     * 
+     * @param d
+     *            a Dimension object which represents new size of a rectangle.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Gets the location of a rectangle's upper left corner as a Point object.
+     * 
+     * @return the Point object with coordinates equal to the upper left corner
+     *         of the rectangle.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the rectangle in terms of its upper left corner
+     * coordinates X and Y.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the Y coordinate of the rectangle's upper left corner.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of a rectangle using a Point object to give the
+     * coordinates of the upper left corner.
+     * 
+     * @param p
+     *            the Point object which represents the new upper left corner
+     *            coordinates of rectangle.
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Moves a rectangle to the new location by moving its upper left corner to
+     * the point with coordinates X and Y.
+     * 
+     * @param x
+     *            the new X coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the new Y coordinate of the rectangle's upper left corner.
+     * @deprecated Use setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Sets the rectangle to be the nearest rectangle with integer coordinates
+     * bounding the rectangle defined by the double-valued parameters.
+     * 
+     * @param x
+     *            the X coordinate of the upper left corner of the double-valued
+     *            rectangle to be bounded.
+     * @param y
+     *            the Y coordinate of the upper left corner of the double-valued
+     *            rectangle to be bounded.
+     * @param width
+     *            the width of the rectangle to be bounded.
+     * @param height
+     *            the height of the rectangle to be bounded.
+     * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
+     */
+    @Override
+    public void setRect(double x, double y, double width, double height) {
+        int x1 = (int)Math.floor(x);
+        int y1 = (int)Math.floor(y);
+        int x2 = (int)Math.ceil(x + width);
+        int y2 = (int)Math.ceil(y + height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Sets a new size for the rectangle.
+     * 
+     * @param width
+     *            the rectangle's new width.
+     * @param height
+     *            the rectangle's new height.
+     * @deprecated use the setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Resets the bounds of a rectangle to the specified x, y, width and height
+     * parameters.
+     * 
+     * @param x
+     *            the new X coordinate of the upper left corner.
+     * @param y
+     *            the new Y coordinate of the upper left corner.
+     * @param width
+     *            the new width of rectangle.
+     * @param height
+     *            the new height of rectangle.
+     * @deprecated use setBounds(int, int, int, int) method
+     */
+    @Deprecated
+    public void reshape(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Gets bounds of the rectangle as a new Rectangle object.
+     * 
+     * @return the Rectangle object with the same bounds as the original
+     *         rectangle.
+     * @see java.awt.geom.RectangularShape#getBounds()
+     */
+    @Override
+    public Rectangle getBounds() {
+        return new Rectangle(x, y, width, height);
+    }
+
+    /**
+     * Gets the bounds of the original rectangle as a Rectangle2D object.
+     * 
+     * @return the Rectangle2D object which represents the bounds of the
+     *         original rectangle.
+     * @see java.awt.geom.Rectangle2D#getBounds2D()
+     */
+    @Override
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Sets the bounds of a rectangle to the specified x, y, width, and height
+     * parameters.
+     * 
+     * @param x
+     *            the X coordinate of the upper left corner.
+     * @param y
+     *            the Y coordinate of the upper left corner.
+     * @param width
+     *            the width of rectangle.
+     * @param height
+     *            the height of rectangle.
+     */
+    public void setBounds(int x, int y, int width, int height) {
+        this.x = x;
+        this.y = y;
+        this.height = height;
+        this.width = width;
+    }
+
+    /**
+     * Sets the bounds of the rectangle to match the bounds of the Rectangle
+     * object sent as a parameter.
+     * 
+     * @param r
+     *            the Rectangle object which specifies the new bounds.
+     */
+    public void setBounds(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Enlarges the rectangle by moving each corner outward from the center by a
+     * distance of dx horizonally and a distance of dy vertically. Specifically,
+     * changes a rectangle with [x, y, width, height] parameters to a rectangle
+     * with [x-dx, y-dy, width+2*dx, height+2*dy] parameters.
+     * 
+     * @param dx
+     *            the horizontal distance to move each corner coordinate.
+     * @param dy
+     *            the vertical distance to move each corner coordinate.
+     */
+    public void grow(int dx, int dy) {
+        x -= dx;
+        y -= dy;
+        width += dx + dx;
+        height += dy + dy;
+    }
+
+    /**
+     * Moves a rectangle a distance of mx along the x coordinate axis and a
+     * distance of my along y coordinate axis.
+     * 
+     * @param mx
+     *            the horizontal translation increment.
+     * @param my
+     *            the vertical translation increment.
+     */
+    public void translate(int mx, int my) {
+        x += mx;
+        y += my;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point.
+     * 
+     * @param px
+     *            the X coordinate of the new point to be covered by the
+     *            rectangle.
+     * @param py
+     *            the Y coordinate of the new point to be covered by the
+     *            rectangle.
+     */
+    public void add(int px, int py) {
+        int x1 = Math.min(x, px);
+        int x2 = Math.max(x + width, px);
+        int y1 = Math.min(y, py);
+        int y2 = Math.max(y + height, py);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point with the new point
+     * given as a Point object.
+     * 
+     * @param p
+     *            the Point object that specifies the new point to be covered by
+     *            the rectangle.
+     */
+    public void add(Point p) {
+        add(p.x, p.y);
+    }
+
+    /**
+     * Adds a new rectangle to the original rectangle, the result is an union of
+     * the specified specified rectangle and original rectangle.
+     * 
+     * @param r
+     *            the Rectangle which is added to the original rectangle.
+     */
+    public void add(Rectangle r) {
+        int x1 = Math.min(x, r.x);
+        int x2 = Math.max(x + width, r.x + r.width);
+        int y1 = Math.min(y, r.y);
+        int y2 = Math.max(y + height, r.y + r.height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the point with specified coordinates [px, py]
+     * is within the bounds of the rectangle.
+     * 
+     * @param px
+     *            the X coordinate of point.
+     * @param py
+     *            the Y coordinate of point.
+     * @return true, if the point with specified coordinates [px, py] is within
+     *         the bounds of the rectangle, false otherwise.
+     */
+    public boolean contains(int px, int py) {
+        if (isEmpty()) {
+            return false;
+        }
+        if (px < x || py < y) {
+            return false;
+        }
+        px -= x;
+        py -= y;
+        return px < width && py < height;
+    }
+
+    /**
+     * Determines whether or not the point given as a Point object is within the
+     * bounds of the rectangle.
+     * 
+     * @param p
+     *            the Point object
+     * @return true, if the point p is within the bounds of the rectangle,
+     *         otherwise false.
+     */
+    public boolean contains(Point p) {
+        return contains(p.x, p.y);
+    }
+
+    /**
+     * Determines whether or not the rectangle specified by [rx, ry, rw, rh]
+     * parameters is located inside the original rectangle.
+     * 
+     * @param rx
+     *            the X coordinate of the rectangle to compare.
+     * @param ry
+     *            the Y coordinate of the rectangle to compare.
+     * @param rw
+     *            the width of the rectangle to compare.
+     * @param rh
+     *            the height of the rectangle to compare.
+     * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
+     *         contained in the original rectangle, false otherwise.
+     */
+    public boolean contains(int rx, int ry, int rw, int rh) {
+        return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
+    }
+
+    /**
+     * Compares whether or not the rectangle specified by the Rectangle object
+     * is located inside the original rectangle.
+     * 
+     * @param r
+     *            the Rectangle object.
+     * @return true, if the rectangle specified by Rectangle object is entirely
+     *         contained in the original rectangle, false otherwise.
+     */
+    public boolean contains(Rectangle r) {
+        return contains(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Compares whether or not a point with specified coordinates [px, py]
+     * belongs to a rectangle.
+     * 
+     * @param px
+     *            the X coordinate of a point.
+     * @param py
+     *            the Y coordinate of a point.
+     * @return true, if a point with specified coordinates [px, py] belongs to a
+     *         rectangle, otherwise false.
+     * @deprecated use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int px, int py) {
+        return contains(px, py);
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the specified
+     * Rectangle2D.
+     * 
+     * @param r
+     *            the Rectangle2D object.
+     * @return the Rectangle2D object that is the result of intersecting the
+     *         original rectangle with the specified Rectangle2D.
+     * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createIntersection(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return intersection((Rectangle)r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.intersect(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the specified
+     * rectangle. An empty rectangle is returned if there is no intersection.
+     * 
+     * @param r
+     *            the Rectangle object.
+     * @return the Rectangle object is result of the original rectangle with the
+     *         specified rectangle.
+     */
+    public Rectangle intersection(Rectangle r) {
+        int x1 = Math.max(x, r.x);
+        int y1 = Math.max(y, r.y);
+        int x2 = Math.min(x + width, r.x + r.width);
+        int y2 = Math.min(y + height, r.y + r.height);
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the original rectangle intersects the specified
+     * rectangle.
+     * 
+     * @param r
+     *            the Rectangle object.
+     * @return true, if the two rectangles overlap, false otherwise.
+     */
+    public boolean intersects(Rectangle r) {
+        return !intersection(r).isEmpty();
+    }
+
+    /**
+     * Determines where the specified Point is located with respect to the
+     * rectangle. This method computes whether the point is to the right or to
+     * the left of the rectangle and whether it is above or below the rectangle,
+     * and packs the result into an integer by using a binary OR operation with
+     * the following masks:
+     * <ul>
+     *<li>Rectangle2D.OUT_LEFT</li>
+     *<li>Rectangle2D.OUT_TOP</li>
+     *<li>Rectangle2D.OUT_RIGHT</li>
+     *<li>Rectangle2D.OUT_BOTTOM</li>
+     *</ul>
+     * If the rectangle is empty, all masks are set, and if the point is inside
+     * the rectangle, none are set.
+     * 
+     * @param px
+     *            the X coordinate of the specified point.
+     * @param py
+     *            the Y coordinate of the specified point.
+     * @return the location of the Point relative to the rectangle as the result
+     *         of logical OR operation with all out masks.
+     * @see java.awt.geom.Rectangle2D#outcode(double, double)
+     */
+    @Override
+    public int outcode(double px, double py) {
+        int code = 0;
+
+        if (width <= 0) {
+            code |= OUT_LEFT | OUT_RIGHT;
+        } else if (px < x) {
+            code |= OUT_LEFT;
+        } else if (px > x + width) {
+            code |= OUT_RIGHT;
+        }
+
+        if (height <= 0) {
+            code |= OUT_TOP | OUT_BOTTOM;
+        } else if (py < y) {
+            code |= OUT_TOP;
+        } else if (py > y + height) {
+            code |= OUT_BOTTOM;
+        }
+
+        return code;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified Rectangle2D.
+     * 
+     * @param r
+     *            the Rectangle2D object.
+     * @return the union of the original and the specified Rectangle2D.
+     * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createUnion(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return union((Rectangle)r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.union(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified rectangle.
+     * 
+     * @param r
+     *            the Rectangle.
+     * @return the union of the original and the specified rectangle.
+     */
+    public Rectangle union(Rectangle r) {
+        Rectangle dst = new Rectangle(this);
+        dst.add(r);
+        return dst;
+    }
+
+    /**
+     * Compares the original Rectangle with the specified object.
+     * 
+     * @param obj
+     *            the specified Object for comparison.
+     * @return true, if the specified Object is a rectangle with the same
+     *         dimensions as the original rectangle, false otherwise.
+     * @see java.awt.geom.Rectangle2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle) {
+            Rectangle r = (Rectangle)obj;
+            return r.x == x && r.y == y && r.width == width && r.height == height;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of the rectangle; the string contains [x,
+     * y, width, height] parameters of the rectangle.
+     * 
+     * @return the string representation of the rectangle.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be
+        // obtained in the following way
+        // System.out.println(new Rectangle().toString())
+        return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
+                ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/awt/java/awt/RenderingHints.java b/awt/java/awt/RenderingHints.java
new file mode 100644
index 0000000..acf6fa1
--- /dev/null
+++ b/awt/java/awt/RenderingHints.java
@@ -0,0 +1,606 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The RenderingHints class represents preferences for the rendering algorithms.
+ * The preferences are arbitrary and can be specified by Map objects or by
+ * key-value pairs.
+ * 
+ * @since Android 1.0
+ */
+public class RenderingHints implements Map<Object, Object>, Cloneable {
+
+    /**
+     * The Constant KEY_ALPHA_INTERPOLATION - alpha interpolation rendering hint
+     * key.
+     */
+    public static final Key KEY_ALPHA_INTERPOLATION = new KeyImpl(1);
+
+    /**
+     * The Constant VALUE_ALPHA_INTERPOLATION_DEFAULT - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT = new KeyValue(
+            KEY_ALPHA_INTERPOLATION);
+
+    /**
+     * The Constant VALUE_ALPHA_INTERPOLATION_SPEED - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED = new KeyValue(
+            KEY_ALPHA_INTERPOLATION);
+
+    /**
+     * The Constant VALUE_ALPHA_INTERPOLATION_QUALITY - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY = new KeyValue(
+            KEY_ALPHA_INTERPOLATION);
+
+    /**
+     * The Constant KEY_ANTIALIASING - antialiasing rendering hint key.
+     */
+    public static final Key KEY_ANTIALIASING = new KeyImpl(2);
+
+    /**
+     * The Constant VALUE_ANTIALIAS_DEFAULT - antialiasing rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_DEFAULT = new KeyValue(KEY_ANTIALIASING);
+
+    /**
+     * The Constant VALUE_ANTIALIAS_ON - antialiasing rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_ON = new KeyValue(KEY_ANTIALIASING);
+
+    /**
+     * The Constant VALUE_ANTIALIAS_OFF - antialiasing rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_OFF = new KeyValue(KEY_ANTIALIASING);
+
+    /**
+     * The Constant KEY_COLOR_RENDERING - color rendering hint key.
+     */
+    public static final Key KEY_COLOR_RENDERING = new KeyImpl(3);
+
+    /**
+     * The Constant VALUE_COLOR_RENDER_DEFAULT - color rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_DEFAULT = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     * The Constant VALUE_COLOR_RENDER_SPEED - color rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_SPEED = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     * The Constant VALUE_COLOR_RENDER_QUALITY - color rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_QUALITY = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     * The Constant KEY_DITHERING - dithering rendering hint key.
+     */
+    public static final Key KEY_DITHERING = new KeyImpl(4);
+
+    /**
+     * The Constant VALUE_DITHER_DEFAULT - dithering rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DEFAULT = new KeyValue(KEY_DITHERING);
+
+    /**
+     * The Constant VALUE_DITHER_DISABLE - dithering rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DISABLE = new KeyValue(KEY_DITHERING);
+
+    /**
+     * The Constant VALUE_DITHER_DISABLE - dithering rendering hint value.
+     */
+    public static final Object VALUE_DITHER_ENABLE = new KeyValue(KEY_DITHERING);
+
+    /**
+     * The Constant KEY_FRACTIONALMETRICS - fractional metrics rendering hint
+     * key.
+     */
+    public static final Key KEY_FRACTIONALMETRICS = new KeyImpl(5);
+
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_DEFAULT - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_ON - fractional metrics rendering
+     * hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_ON = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_OFF - fractional metrics rendering
+     * hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_OFF = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /**
+     * The Constant KEY_INTERPOLATION - interpolation rendering hint key.
+     */
+    public static final Key KEY_INTERPOLATION = new KeyImpl(6);
+
+    /**
+     * The Constant VALUE_INTERPOLATION_BICUBIC - interpolation rendering hint
+     * value.
+     */
+    public static final Object VALUE_INTERPOLATION_BICUBIC = new KeyValue(KEY_INTERPOLATION);
+
+    /**
+     * The Constant VALUE_INTERPOLATION_BILINEAR - interpolation rendering hint
+     * value.
+     */
+    public static final Object VALUE_INTERPOLATION_BILINEAR = new KeyValue(KEY_INTERPOLATION);
+
+    /**
+     * The Constant VALUE_INTERPOLATION_NEAREST_NEIGHBOR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR = new KeyValue(
+            KEY_INTERPOLATION);
+
+    /**
+     * The Constant KEY_RENDERING - rendering hint key.
+     */
+    public static final Key KEY_RENDERING = new KeyImpl(7);
+
+    /**
+     * The Constant VALUE_RENDER_DEFAULT - rendering hint value.
+     */
+    public static final Object VALUE_RENDER_DEFAULT = new KeyValue(KEY_RENDERING);
+
+    /**
+     * The Constant VALUE_RENDER_SPEED - rendering hint value.
+     */
+    public static final Object VALUE_RENDER_SPEED = new KeyValue(KEY_RENDERING);
+
+    /**
+     * The Constant VALUE_RENDER_QUALITY - rendering hint value.
+     */
+    public static final Object VALUE_RENDER_QUALITY = new KeyValue(KEY_RENDERING);
+
+    /**
+     * The Constant KEY_STROKE_CONTROL - stroke control hint key.
+     */
+    public static final Key KEY_STROKE_CONTROL = new KeyImpl(8);
+
+    /**
+     * The Constant VALUE_STROKE_DEFAULT - stroke hint value.
+     */
+    public static final Object VALUE_STROKE_DEFAULT = new KeyValue(KEY_STROKE_CONTROL);
+
+    /**
+     * The Constant VALUE_STROKE_NORMALIZE - stroke hint value.
+     */
+    public static final Object VALUE_STROKE_NORMALIZE = new KeyValue(KEY_STROKE_CONTROL);
+
+    /**
+     * The Constant VALUE_STROKE_PURE - stroke hint value.
+     */
+    public static final Object VALUE_STROKE_PURE = new KeyValue(KEY_STROKE_CONTROL);
+
+    /**
+     * The Constant KEY_TEXT_ANTIALIASING - text antialiasing hint key.
+     */
+    public static final Key KEY_TEXT_ANTIALIASING = new KeyImpl(9);
+
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_DEFAULT - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_ON - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_ON = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_OFF - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_OFF = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /** The map. */
+    private HashMap<Object, Object> map = new HashMap<Object, Object>();
+
+    /**
+     * Instantiates a new rendering hints object from specified Map object with
+     * defined key/value pairs or null for empty RenderingHints.
+     * 
+     * @param map
+     *            the Map object with defined key/value pairs or null for empty
+     *            RenderingHints.
+     */
+    public RenderingHints(Map<Key, ?> map) {
+        super();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Instantiates a new rendering hints object with the specified key/value
+     * pair.
+     * 
+     * @param key
+     *            the key of hint property.
+     * @param value
+     *            the value of hint property.
+     */
+    public RenderingHints(Key key, Object value) {
+        super();
+        put(key, value);
+    }
+
+    /**
+     * Adds the properties represented by key/value pairs from the specified
+     * RenderingHints object to current object.
+     * 
+     * @param hints
+     *            the RenderingHints to be added.
+     */
+    public void add(RenderingHints hints) {
+        map.putAll(hints.map);
+    }
+
+    /**
+     * Puts the specified value to the specified key. Neither the key nor the
+     * value can be null.
+     * 
+     * @param key
+     *            the rendering hint key.
+     * @param value
+     *            the rendering hint value.
+     * @return the previous rendering hint value assigned to the key or null.
+     */
+    public Object put(Object key, Object value) {
+        if (!((Key)key).isCompatibleValue(value)) {
+            throw new IllegalArgumentException();
+        }
+
+        return map.put(key, value);
+    }
+
+    /**
+     * Removes the specified key and corresponding value from the RenderingHints
+     * object.
+     * 
+     * @param key
+     *            the specified hint key to be removed.
+     * @return the object of previous rendering hint value which is assigned to
+     *         the specified key, or null.
+     */
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Gets the value assigned to the specified key.
+     * 
+     * @param key
+     *            the rendering hint key.
+     * @return the object assigned to the specified key.
+     */
+    public Object get(Object key) {
+        return map.get(key);
+    }
+
+    /**
+     * Returns a set of rendering hints keys for current RenderingHints object.
+     * 
+     * @return the set of rendering hints keys.
+     */
+    public Set<Object> keySet() {
+        return map.keySet();
+    }
+
+    /**
+     * Returns a set of Map.Entry objects which contain current RenderingHint
+     * key/value pairs.
+     * 
+     * @return the a set of mapped RenderingHint key/value pairs.
+     */
+    public Set<Map.Entry<Object, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+    /**
+     * Puts all of the preferences from the specified Map into the current
+     * RenderingHints object. These mappings replace all existing preferences.
+     * 
+     * @param m
+     *            the specified Map of preferences.
+     */
+    public void putAll(Map<?, ?> m) {
+        if (m instanceof RenderingHints) {
+            map.putAll(((RenderingHints)m).map);
+        } else {
+            Set<?> entries = m.entrySet();
+
+            if (entries != null) {
+                Iterator<?> it = entries.iterator();
+                while (it.hasNext()) {
+                    Map.Entry<?, ?> entry = (Map.Entry<?, ?>)it.next();
+                    Key key = (Key)entry.getKey();
+                    Object val = entry.getValue();
+                    put(key, val);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Collection of values contained in current RenderingHints
+     * object.
+     * 
+     * @return the Collection of RenderingHints's values.
+     */
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains at least one
+     * the value which is equal to the specified Object.
+     * 
+     * @param value
+     *            the specified Object.
+     * @return true, if the specified object is assigned to at least one
+     *         RenderingHint's key, false otherwise.
+     */
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains the key
+     * which is equal to the specified Object.
+     * 
+     * @param key
+     *            the specified Object.
+     * @return true, if the RenderingHints object contains the specified Object
+     *         as a key, false otherwise.
+     */
+    public boolean containsKey(Object key) {
+        if (key == null) {
+            throw new NullPointerException();
+        }
+
+        return map.containsKey(key);
+    }
+
+    /**
+     * Checks whether or not the RenderingHints object contains any key/value
+     * pairs.
+     * 
+     * @return true, if the RenderingHints object is empty, false otherwise.
+     */
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    /**
+     * Clears the RenderingHints of all key/value pairs.
+     */
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Returns the number of key/value pairs in the RenderingHints.
+     * 
+     * @return the number of key/value pairs.
+     */
+    public int size() {
+        return map.size();
+    }
+
+    /**
+     * Compares the RenderingHints object with the specified object.
+     * 
+     * @param o
+     *            the specified Object to be compared.
+     * @return true, if the Object is a Map whose key/value pairs match this
+     *         RenderingHints' key/value pairs, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map)) {
+            return false;
+        }
+
+        Map<?, ?> m = (Map<?, ?>)o;
+        Set<?> keys = keySet();
+        if (!keys.equals(m.keySet())) {
+            return false;
+        }
+
+        Iterator<?> it = keys.iterator();
+        while (it.hasNext()) {
+            Key key = (Key)it.next();
+            Object v1 = get(key);
+            Object v2 = m.get(key);
+            if (!(v1 == null ? v2 == null : v1.equals(v2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the hash code for this RenderingHints object.
+     * 
+     * @return the hash code for this RenderingHints object.
+     */
+    @Override
+    public int hashCode() {
+        return map.hashCode();
+    }
+
+    /**
+     * Returns the clone of the RenderingHints object with the same contents.
+     * 
+     * @return the clone of the RenderingHints instance.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        RenderingHints clone = new RenderingHints(null);
+        clone.map = (HashMap<Object, Object>)this.map.clone();
+        return clone;
+    }
+
+    /**
+     * Returns the string representation of the RenderingHints object.
+     * 
+     * @return the String object which represents RenderingHints object.
+     */
+    @Override
+    public String toString() {
+        return "RenderingHints[" + map.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * The RenderingHints.Key class is abstract and defines a base type for all
+     * RenderingHints keys.
+     * 
+     * @since Android 1.0
+     */
+    public abstract static class Key {
+
+        /** The key. */
+        private final int key;
+
+        /**
+         * Instantiates a new key with unique integer identifier. No two objects
+         * of the same subclass with the same integer key can be instantiated.
+         * 
+         * @param key
+         *            the unique key.
+         */
+        protected Key(int key) {
+            this.key = key;
+        }
+
+        /**
+         * Compares the Key object with the specified object.
+         * 
+         * @param o
+         *            the specified Object to be compared.
+         * @return true, if the Key is equal to the specified object, false
+         *         otherwise.
+         */
+        @Override
+        public final boolean equals(Object o) {
+            return this == o;
+        }
+
+        /**
+         * Returns the hash code for this Key object.
+         * 
+         * @return the hash code for this Key object.
+         */
+        @Override
+        public final int hashCode() {
+            return System.identityHashCode(this);
+        }
+
+        /**
+         * Returns integer unique key with which this Key object has been
+         * instantiated.
+         * 
+         * @return the integer unique key with which this Key object has been
+         *         instantiated.
+         */
+        protected final int intKey() {
+            return key;
+        }
+
+        /**
+         * Checks whether or not specified value is compatible with the Key.
+         * 
+         * @param val
+         *            the Object.
+         * @return true, if the specified value is compatible with the Key,
+         *         false otherwise.
+         */
+        public abstract boolean isCompatibleValue(Object val);
+    }
+
+    /**
+     * Private implementation of Key class.
+     */
+    private static class KeyImpl extends Key {
+
+        /**
+         * Instantiates a new key implementation.
+         * 
+         * @param key
+         *            the key.
+         */
+        protected KeyImpl(int key) {
+            super(key);
+        }
+
+        @Override
+        public boolean isCompatibleValue(Object val) {
+            if (!(val instanceof KeyValue)) {
+                return false;
+            }
+
+            return ((KeyValue)val).key == this;
+        }
+    }
+
+    /**
+     * Private class KeyValue is used as value for Key class instance.
+     */
+    private static class KeyValue {
+
+        /**
+         * The key.
+         */
+        private final Key key;
+
+        /**
+         * Instantiates a new key value.
+         * 
+         * @param key
+         *            the key.
+         */
+        protected KeyValue(Key key) {
+            this.key = key;
+        }
+    }
+}
diff --git a/awt/java/awt/Shape.java b/awt/java/awt/Shape.java
new file mode 100644
index 0000000..59bc623
--- /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.
+ * 
+ * @since Android 1.0
+ */
+public interface Shape {
+
+    /**
+     * Checks whether or not the point with specified coordinates lies inside
+     * the Shape.
+     * 
+     * @param x
+     *            the X coordinate.
+     * @param y
+     *            the Y coordinate.
+     * @return true, if the specified coordinates lie inside the Shape, false
+     *         otherwise.
+     */
+    public boolean contains(double x, double y);
+
+    /**
+     * Checks whether or not the rectangle with specified [x, y, width, height]
+     * parameters lies inside the Shape.
+     * 
+     * @param x
+     *            the X double coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the Y double coordinate of the rectangle's upper left corner.
+     * @param w
+     *            the width of rectangle.
+     * @param h
+     *            the height of rectangle.
+     * @return true, if the specified rectangle lies inside the Shape, false
+     *         otherwise.
+     */
+    public boolean contains(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Shape.
+     * 
+     * @param point
+     *            the Point2D object.
+     * @return true, if the specified Point2D lies inside the Shape, false
+     *         otherwise.
+     */
+    public boolean contains(Point2D point);
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Shape.
+     * 
+     * @param r
+     *            the Rectangle2D object.
+     * @return true, if the specified rectangle lies inside the Shape, false
+     *         otherwise.
+     */
+    public boolean contains(Rectangle2D r);
+
+    /**
+     * Gets the bounding rectangle of the Shape. The bounding rectangle is the
+     * smallest rectangle which contains the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle getBounds();
+
+    /**
+     * Gets the Rectangle2D which represents Shape bounds. The bounding
+     * rectangle is the smallest rectangle which contains the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle2D getBounds2D();
+
+    /**
+     * Gets the PathIterator object of the Shape which provides access to the
+     * shape's boundary modified by the specified AffineTransform.
+     * 
+     * @param at
+     *            the specified AffineTransform object or null.
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at);
+
+    /**
+     * Gets the PathIterator object of the Shape which provides access to the
+     * coordinates of the shapes boundary modified by the specified
+     * AffineTransform. The flatness parameter defines the amount of subdivision
+     * of the curved segments and specifies the maximum distance which every
+     * point on the unflattened transformed curve can deviate from the returned
+     * flattened path segments.
+     * 
+     * @param at
+     *            the specified AffineTransform object or null.
+     * @param flatness
+     *            the maximum number of the control points for a given curve
+     *            which varies from colinear before a subdivided curve is
+     *            replaced by a straight line connecting the endpoints.
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness);
+
+    /**
+     * Checks whether or not the interior of rectangular specified by [x, y,
+     * width, height] parameters intersects the interior of the Shape.
+     * 
+     * @param x
+     *            the X double coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the Y double coordinate of the rectangle's upper left corner.
+     * @param w
+     *            the width of rectangle.
+     * @param h
+     *            the height of rectangle.
+     * @return true, if the rectangle specified by [x, y, width, height]
+     *         parameters intersects the interior of the Shape, false otherwise.
+     */
+    public boolean intersects(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the interior of rectangle specified by Rectangle2D
+     * object intersects the interior of the Shape.
+     * 
+     * @param r
+     *            the Rectangle2D object.
+     * @return true, if the Rectangle2D intersects the interior of the Shape,
+     *         otherwise false.
+     */
+    public boolean intersects(Rectangle2D r);
+}
diff --git a/awt/java/awt/Stroke.java b/awt/java/awt/Stroke.java
new file mode 100644
index 0000000..6d17a23
--- /dev/null
+++ b/awt/java/awt/Stroke.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The Stroke interface gives a pen style to be used by the Graphics2D
+ * interface. It provides a means for getting a stroked version of a shape,
+ * which is the version that is suitable for drawing via the Graphics2D
+ * interface. Stroking a shape gives the shape's outline a width or drawing
+ * style.
+ * <p>
+ * The Draw methods from Graphics2D interface should use the Stroke object for
+ * rendering the shape's outline. The stroke should be set by
+ * setStroke(java.awt.Stroke) method of the Graphics2D interface.
+ * 
+ * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
+ * @since Android 1.0
+ */
+public interface Stroke {
+
+    /**
+     * Creates the stroked shape, which is the version that is suitable for
+     * drawing via the Graphics2D interface. Stroking a shape gives the shape's
+     * outline a width or drawing style.
+     * 
+     * @param p
+     *            the original shape.
+     * @return the stroked shape.
+     */
+    public Shape createStrokedShape(Shape p);
+}
diff --git a/awt/java/awt/Toolkit.java b/awt/java/awt/Toolkit.java
new file mode 100644
index 0000000..e38d524
--- /dev/null
+++ b/awt/java/awt/Toolkit.java
@@ -0,0 +1,1444 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.AWTEventListener;
+import java.awt.event.AWTEventListenerProxy;
+import java.awt.event.InputEvent;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.FontPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.awt.ChoiceStyle;
+import org.apache.harmony.awt.ComponentInternals;
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.ReadOnlyIterator;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.CreationParams;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeEventThread;
+import org.apache.harmony.awt.wtk.ShutdownWatchdog;
+import org.apache.harmony.awt.wtk.Synchronizer;
+import org.apache.harmony.awt.wtk.WTK;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ * The Toolkit class is the representation of the platform-specific Abstract
+ * Window Toolkit implementation. Toolkit's subclasses are used to bind the
+ * various components to particular native toolkit implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Toolkit {
+
+    /**
+     * The Constant RECOURCE_PATH.
+     */
+    private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
+
+    /**
+     * The Constant properties.
+     */
+    private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
+
+    /**
+     * The dispatcher.
+     */
+    Dispatcher dispatcher;
+
+    /**
+     * The system event queue core.
+     */
+    private EventQueueCore systemEventQueueCore;
+
+    /**
+     * The dispatch thread.
+     */
+    EventDispatchThread dispatchThread;
+
+    /**
+     * The native thread.
+     */
+    NativeEventThread nativeThread;
+
+    /**
+     * The AWT events manager.
+     */
+    protected AWTEventsManager awtEventsManager;
+
+    /**
+     * The Class AWTTreeLock.
+     */
+    private class AWTTreeLock {
+    }
+
+    /**
+     * The AWT tree lock.
+     */
+    final Object awtTreeLock = new AWTTreeLock();
+
+    /**
+     * The synchronizer.
+     */
+    private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
+
+    /**
+     * The shutdown watchdog.
+     */
+    final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
+
+    /**
+     * The auto number.
+     */
+    final AutoNumber autoNumber = new AutoNumber();
+
+    /**
+     * The event type lookup.
+     */
+    final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
+
+    /**
+     * The b dynamic layout set.
+     */
+    private boolean bDynamicLayoutSet = true;
+
+    /**
+     * The set of desktop properties that user set directly.
+     */
+    private final HashSet<String> userPropSet = new HashSet<String>();
+
+    /**
+     * The desktop properties.
+     */
+    protected Map<String, Object> desktopProperties;
+
+    /**
+     * The desktop props support.
+     */
+    protected PropertyChangeSupport desktopPropsSupport;
+
+    /**
+     * For this component the native window is being created It is used in the
+     * callback-driven window creation (e.g. on Windows in the handler of
+     * WM_CREATE event) to establish the connection between this component and
+     * its native window.
+     */
+    private Object recentNativeWindowComponent;
+
+    /**
+     * The wtk.
+     */
+    private WTK wtk;
+
+    /**
+     * The Class ComponentInternalsImpl.
+     * 
+     * @since Android 1.0
+     */
+    protected final class ComponentInternalsImpl extends ComponentInternals {
+
+        /**
+         * Shutdown.
+         */
+        @Override
+        public void shutdown() {
+            dispatchThread.shutdown();
+        }
+
+        /**
+         * Sets the desktop property to the specified value and fires a property
+         * change event.
+         * 
+         * @param name
+         *            the name of property.
+         * @param value
+         *            the new value of property.
+         */
+        @Override
+        public void setDesktopProperty(String name, Object value) {
+            Toolkit.this.setDesktopProperty(name, value);
+        }
+    }
+
+    /**
+     * A lot of methods must throw HeadlessException if
+     * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
+     * 
+     * @throws HeadlessException
+     *             the headless exception.
+     */
+    static void checkHeadless() throws HeadlessException {
+        if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
+            throw new HeadlessException();
+    }
+
+    /**
+     * Lock AWT.
+     */
+    final void lockAWT() {
+        synchronizer.lock();
+    }
+
+    /**
+     * Static lock AWT.
+     */
+    static final void staticLockAWT() {
+        ContextStorage.getSynchronizer().lock();
+    }
+
+    /**
+     * Unlock AWT.
+     */
+    final void unlockAWT() {
+        synchronizer.unlock();
+    }
+
+    /**
+     * Static unlock AWT.
+     */
+    static final void staticUnlockAWT() {
+        ContextStorage.getSynchronizer().unlock();
+    }
+
+    /**
+     * InvokeAndWait under AWT lock. W/o this method system can hang up. Added
+     * to support modality (Dialog.show() & PopupMenu.show()) from not event
+     * dispatch thread. Use in other cases is not recommended. Still can be
+     * called only for whole API methods that cannot be called from other
+     * classes API methods. Examples: show() for modal dialogs - correct, only
+     * user can call it, directly or through setVisible(true) setBounds() for
+     * components - incorrect, setBounds() can be called from layoutContainer()
+     * for layout managers
+     * 
+     * @param runnable
+     *            the runnable.
+     * @throws InterruptedException
+     *             the interrupted exception.
+     * @throws InvocationTargetException
+     *             the invocation target exception.
+     */
+    final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
+            InvocationTargetException {
+        synchronizer.storeStateAndFree();
+        try {
+            EventQueue.invokeAndWait(runnable);
+        } finally {
+            synchronizer.lockAndRestoreState();
+        }
+    }
+
+    /**
+     * Gets the synchronizer.
+     * 
+     * @return the synchronizer.
+     */
+    final Synchronizer getSynchronizer() {
+        return synchronizer;
+    }
+
+    /**
+     * Gets the wTK.
+     * 
+     * @return the wTK.
+     */
+    final WTK getWTK() {
+        return wtk;
+    }
+
+    /**
+     * Gets the property with the specified key and default value. This method
+     * returns the defValue if the property is not found.
+     * 
+     * @param propName
+     *            the name of property.
+     * @param defVal
+     *            the default value.
+     * @return the property value.
+     */
+    public static String getProperty(String propName, String defVal) {
+        if (propName == null) {
+            // awt.7D=Property name is null
+            throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
+        }
+        staticLockAWT();
+        try {
+            String retVal = null;
+            if (properties != null) {
+                try {
+                    retVal = properties.getString(propName);
+                } catch (MissingResourceException e) {
+                } catch (ClassCastException e) {
+                }
+            }
+            return (retVal == null) ? defVal : retVal;
+        } finally {
+            staticUnlockAWT();
+        }
+    }
+
+    /**
+     * Gets the default Toolkit.
+     * 
+     * @return the default Toolkit.
+     */
+    public static Toolkit getDefaultToolkit() {
+        synchronized (ContextStorage.getContextLock()) {
+            if (ContextStorage.shutdownPending()) {
+                return null;
+            }
+            Toolkit defToolkit = ContextStorage.getDefaultToolkit();
+            if (defToolkit != null) {
+                return defToolkit;
+            }
+            staticLockAWT();
+            try {
+                defToolkit = GraphicsEnvironment.isHeadless() ? new HeadlessToolkit()
+                        : new ToolkitImpl();
+                ContextStorage.setDefaultToolkit(defToolkit);
+                return defToolkit;
+            } finally {
+                staticUnlockAWT();
+            }
+            // TODO: read system property named awt.toolkit
+            // and create an instance of the specified class,
+            // by default use ToolkitImpl
+        }
+    }
+
+    /**
+     * Gets the default Font.
+     * 
+     * @return the default Font for Toolkit.
+     */
+    Font getDefaultFont() {
+        return wtk.getSystemProperties().getDefaultFont();
+    }
+
+    /**
+     * Load resources.
+     * 
+     * @param path
+     *            the path.
+     * @return the resource bundle.
+     */
+    private static ResourceBundle loadResources(String path) {
+        try {
+            return ResourceBundle.getBundle(path);
+        } catch (MissingResourceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the wTK class name.
+     * 
+     * @return the wTK class name.
+     */
+    private static String getWTKClassName() {
+        return "com.android.internal.awt.AndroidWTK";
+    }
+
+    /**
+     * Gets the component by id.
+     * 
+     * @param id
+     *            the id.
+     * @return the component by id.
+     */
+    Component getComponentById(long id) {
+        if (id == 0) {
+            return null;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the GraphicsFactory.
+     * 
+     * @return the GraphicsFactory object.
+     */
+    public GraphicsFactory getGraphicsFactory() {
+        return wtk.getGraphicsFactory();
+    }
+
+    /**
+     * Instantiates a new toolkit.
+     */
+    public Toolkit() {
+        init();
+    }
+
+    /**
+     * Initiates AWT.
+     */
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            new EventQueue(this); // create the system EventQueue
+            dispatcher = new Dispatcher(this);
+            final String className = getWTKClassName();
+            desktopProperties = new HashMap<String, Object>();
+            desktopPropsSupport = new PropertyChangeSupport(this);
+            awtEventsManager = new AWTEventsManager();
+            dispatchThread = new EventDispatchThread(this, dispatcher);
+            nativeThread = new NativeEventThread();
+            NativeEventThread.Init init = new NativeEventThread.Init() {
+                public WTK init() {
+                    wtk = createWTK(className);
+                    wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
+                    synchronizer.setEnvironment(wtk, dispatchThread);
+                    ContextStorage.setWTK(wtk);
+                    return wtk;
+                }
+            };
+            nativeThread.start(init);
+            dispatchThread.start();
+            wtk.getNativeEventQueue().awake();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Synchronizes this toolkit's graphics.
+     */
+    public abstract void sync();
+
+    /**
+     * Returns the construction status of a specified image that is being
+     * created.
+     * 
+     * @param a0
+     *            the image to be checked.
+     * @param a1
+     *            the width of scaled image for which the status is being
+     *            checked or -1.
+     * @param a2
+     *            the height of scaled image for which the status is being
+     *            checked or -1.
+     * @param a3
+     *            the ImageObserver object to be notified while the image is
+     *            being prepared.
+     * @return the ImageObserver flags which give the current state of the image
+     *         data.
+     */
+    public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
+
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param a0
+     *            the ImageProducer to be used for image creation.
+     * @return the image with the specified ImageProducer.
+     */
+    public abstract Image createImage(ImageProducer a0);
+
+    /**
+     * Creates the image from the specified byte array, offset and length. The
+     * byte array should contain data with image format supported by Toolkit
+     * such as JPEG, GIF, or PNG.
+     * 
+     * @param a0
+     *            the byte array with the image data.
+     * @param a1
+     *            the offset of the beginning the image data in the byte array.
+     * @param a2
+     *            the length of the image data in the byte array.
+     * @return the created Image.
+     */
+    public abstract Image createImage(byte[] a0, int a1, int a2);
+
+    /**
+     * Creates the image using image data from the specified URL.
+     * 
+     * @param a0
+     *            the URL for extracting image data.
+     * @return the Image.
+     */
+    public abstract Image createImage(URL a0);
+
+    /**
+     * Creates the image using image data from the specified file.
+     * 
+     * @param a0
+     *            the file name which contains image data of supported format.
+     * @return the Image.
+     */
+    public abstract Image createImage(String a0);
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel of Toolkit's screen.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract ColorModel getColorModel() throws HeadlessException;
+
+    /**
+     * Gets the screen device metrics for the specified font.
+     * 
+     * @param font
+     *            the Font.
+     * @return the FontMetrics for the specified Font.
+     * @deprecated Use getLineMetrics method from Font class.
+     */
+
+    @Deprecated
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Prepares the specified image for rendering on the screen with the
+     * specified size.
+     * 
+     * @param a0
+     *            the Image to be prepared.
+     * @param a1
+     *            the width of the screen representation or -1 for the current
+     *            screen.
+     * @param a2
+     *            the height of the screen representation or -1 for the current
+     *            screen.
+     * @param a3
+     *            the ImageObserver object to be notified as soon as the image
+     *            is prepared.
+     * @return true, if image is fully prepared, false otherwise.
+     */
+    public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
+
+    /**
+     * Creates an audio beep.
+     */
+    public abstract void beep();
+
+    /**
+     * Returns the array of font names which are available in this Toolkit.
+     * 
+     * @return the array of font names which are available in this Toolkit.
+     * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
+     */
+    @Deprecated
+    public abstract String[] getFontList();
+
+    /**
+     * Gets the the Font implementation using the specified peer interface.
+     * 
+     * @param a0
+     *            the Font name to be implemented.
+     * @param a1
+     *            the the font style: PLAIN, BOLD, ITALIC.
+     * @return the FontPeer implementation of the specified Font.
+     * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
+     */
+
+    @Deprecated
+    protected abstract FontPeer getFontPeer(String a0, int a1);
+
+    /**
+     * Gets the image from the specified file which contains image data in a
+     * supported image format (such as JPEG, GIF, or PNG); this method should
+     * return the same Image for multiple calls of this method with the same
+     * image file name.
+     * 
+     * @param a0
+     *            the file name which contains image data in a supported image
+     *            format (such as JPEG, GIF, or PNG).
+     * @return the Image.
+     */
+    public abstract Image getImage(String a0);
+
+    /**
+     * Gets the image from the specified URL which contains image data in a
+     * supported image format (such as JPEG, GIF, or PNG); this method should
+     * return the same Image for multiple calls of this method with the same
+     * image URL.
+     * 
+     * @param a0
+     *            the URL which contains image data in a supported image format
+     *            (such as JPEG, GIF, or PNG).
+     * @return the Image.
+     */
+    public abstract Image getImage(URL a0);
+
+    /**
+     * Gets the screen resolution.
+     * 
+     * @return the screen resolution.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract int getScreenResolution() throws HeadlessException;
+
+    /**
+     * Gets the screen size.
+     * 
+     * @return a Dimension object containing the width and height of the screen.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract Dimension getScreenSize() throws HeadlessException;
+
+    /**
+     * Gets the EventQueue instance without checking access.
+     * 
+     * @return the system EventQueue.
+     */
+    protected abstract EventQueue getSystemEventQueueImpl();
+
+    /**
+     * Returns a map of text attributes for the abstract level description of
+     * the specified input method highlight, or null if no mapping is found.
+     * 
+     * @param highlight
+     *            the InputMethodHighlight.
+     * @return the Map<java.awt.font. text attribute,?>.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException;
+
+    /**
+     * Map input method highlight impl.
+     * 
+     * @param highlight
+     *            the highlight.
+     * @return the map<java.awt.font. text attribute,?>.
+     * @throws HeadlessException
+     *             the headless exception.
+     */
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(InputMethodHighlight highlight)
+            throws HeadlessException {
+        HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
+        wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
+        return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
+    }
+
+    /**
+     * Adds the specified PropertyChangeListener listener for the specified
+     * property.
+     * 
+     * @param propName
+     *            the property name for which the specified
+     *            PropertyChangeListener will be added.
+     * @param l
+     *            the PropertyChangeListener object.
+     */
+    public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+        } finally {
+            unlockAWT();
+        }
+        if (l != null) { // there is no guarantee that null listener will not be
+            // added
+            desktopPropsSupport.addPropertyChangeListener(propName, l);
+        }
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with this
+     * Toolkit.
+     * 
+     * @return an array of the property change listeners registered with this
+     *         Toolkit.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return desktopPropsSupport.getPropertyChangeListeners();
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with this
+     * Toolkit for notification regarding the specified property.
+     * 
+     * @param propName
+     *            the property name for which the PropertyChangeListener was
+     *            registered.
+     * @return the array of PropertyChangeListeners registered for the specified
+     *         property name.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
+        return desktopPropsSupport.getPropertyChangeListeners(propName);
+    }
+
+    /**
+     * Removes the specified property change listener registered for the
+     * specified property name.
+     * 
+     * @param propName
+     *            the property name.
+     * @param l
+     *            the PropertyChangeListener registered for the specified
+     *            property name.
+     */
+    public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
+        desktopPropsSupport.removePropertyChangeListener(propName, l);
+    }
+
+    /**
+     * Creates a custom cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @param img
+     *            the image of activated cursor.
+     * @param hotSpot
+     *            the Point giving the coordinates of the cursor's hot spot.
+     * @param name
+     *            the cursor description.
+     * @return the cursor with the specified Image, hot spot, and cursor
+     *         description.
+     * @throws IndexOutOfBoundsException
+     *             if the hot spot values are outside the bounds of the cursor.
+     * @throws HeadlessException
+     *             if isHeadless() method of GraphicsEnvironment class returns
+     *             true.
+     */
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+            throws IndexOutOfBoundsException, HeadlessException {
+        lockAWT();
+        try {
+            int w = img.getWidth(null), x = hotSpot.x;
+            int h = img.getHeight(null), y = hotSpot.y;
+            if (x < 0 || x >= w || y < 0 || y >= h) {
+                // awt.7E=invalid hotSpot
+                throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
+            }
+            return new Cursor(name, img, hotSpot);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the supported cursor dimension which is closest to the specified
+     * width and height. If the Toolkit only supports a single cursor size, this
+     * method should return the supported cursor size. If custom cursor is not
+     * supported, a dimension of 0, 0 should be returned.
+     * 
+     * @param prefWidth
+     *            the preferred cursor width.
+     * @param prefHeight
+     *            the preferred cursor height.
+     * @return the supported cursor dimension which is closest to the specified
+     *         width and height.
+     * @throws HeadlessException
+     *             if GraphicsEnvironment.isHeadless() returns true.
+     */
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the value for the specified desktop property.
+     * 
+     * @param propName
+     *            the property name.
+     * @return the Object that is the property's value.
+     */
+    public final Object getDesktopProperty(String propName) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+            if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
+                // dynamicLayoutSupported is special case
+                return Boolean.valueOf(isDynamicLayoutActive());
+            }
+            Object val = desktopProperties.get(propName);
+            if (val == null) {
+                // try to lazily load prop value
+                // just for compatibility, our lazilyLoad is empty
+                val = lazilyLoadDesktopProperty(propName);
+            }
+            return val;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the locking key state for the specified key.
+     * 
+     * @param a0
+     *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
+     *            VK_KANA_LOCK.
+     * @return true if the specified key code is in the locked state, false
+     *         otherwise.
+     * @throws UnsupportedOperationException
+     *             if the state of this key can't be retrieved, or if the
+     *             keyboard doesn't have this key.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean getLockingKeyState(int a0) throws UnsupportedOperationException,
+            org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return true;
+    }
+
+    /**
+     * Returns the maximum number of colors which the Toolkit supports for
+     * custom cursor.
+     * 
+     * @return the maximum cursor colors.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public int getMaximumCursorColors() throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getMaximumCursorColors();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the menu shortcut key mask.
+     * 
+     * @return the menu shortcut key mask.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        lockAWT();
+        try {
+            return InputEvent.CTRL_MASK;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the screen insets.
+     * 
+     * @param gc
+     *            the GraphicsConfiguration.
+     * @return the insets of this toolkit.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        if (gc == null) {
+            throw new NullPointerException();
+        }
+        lockAWT();
+        try {
+            return new Insets(0, 0, 0, 0); // TODO: get real screen insets
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the system EventQueue instance. If the default implementation of
+     * checkAwtEventQueueAccess is used, then this results of a call to the
+     * security manager's checkPermission method with an
+     * AWTPermission("accessEventQueue") permission.
+     * 
+     * @return the system EventQueue instance.
+     */
+    public final EventQueue getSystemEventQueue() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkAwtEventQueueAccess();
+        }
+        return getSystemEventQueueImpl();
+    }
+
+    /**
+     * Gets the system event queue core.
+     * 
+     * @return the system event queue core.
+     */
+    EventQueueCore getSystemEventQueueCore() {
+        return systemEventQueueCore;
+    }
+
+    /**
+     * Sets the system event queue core.
+     * 
+     * @param core
+     *            the new system event queue core.
+     */
+    void setSystemEventQueueCore(EventQueueCore core) {
+        systemEventQueueCore = core;
+    }
+
+    /**
+     * Initialize the desktop properties.
+     */
+    protected void initializeDesktopProperties() {
+        lockAWT();
+        try {
+            wtk.getSystemProperties().init(desktopProperties);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if dynamic layout of Containers is active or not.
+     * 
+     * @return true, if is dynamic layout of Containers is active, false
+     *         otherwise.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        lockAWT();
+        try {
+            // always return true
+            return true;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns if the layout of Containers is checked dynamically during
+     * resizing, or statically after resizing is completed.
+     * 
+     * @return true, if if the layout of Containers is checked dynamically
+     *         during resizing; false, if the layout of Containers is checked
+     *         statically after resizing is completed.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        lockAWT();
+        try {
+            return bDynamicLayoutSet;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the specified frame state is supported by Toolkit or not.
+     * 
+     * @param state
+     *            the frame state.
+     * @return true, if frame state is supported, false otherwise.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getWindowFactory().isWindowStateSupported(state);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Loads the value of the desktop property with the specified property name.
+     * 
+     * @param propName
+     *            the property name.
+     * @return the desktop property values.
+     */
+    protected Object lazilyLoadDesktopProperty(String propName) {
+        return null;
+    }
+
+    /**
+     * Loads the current system color values to the specified array.
+     * 
+     * @param colors
+     *            the array where the current system color values are written by
+     *            this method.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    protected void loadSystemColors(int[] colors) throws HeadlessException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the value of the desktop property with the specified name.
+     * 
+     * @param propName
+     *            the property's name.
+     * @param value
+     *            the property's value.
+     */
+    protected final void setDesktopProperty(String propName, Object value) {
+        Object oldVal;
+        lockAWT();
+        try {
+            oldVal = getDesktopProperty(propName);
+            userPropSet.add(propName);
+            desktopProperties.put(propName, value);
+        } finally {
+            unlockAWT();
+        }
+        desktopPropsSupport.firePropertyChange(propName, oldVal, value);
+    }
+
+    /**
+     * Sets the layout state, whether the Container layout is checked
+     * dynamically during resizing, or statically after resizing is completed.
+     * 
+     * @param dynamic
+     *            the new dynamic layout state - if true the layout of
+     *            Containers is checked dynamically during resizing, if false -
+     *            statically after resizing is completed.
+     * @throws HeadlessException
+     *             if the GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        lockAWT();
+        try {
+            bDynamicLayoutSet = dynamic;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locking key state for the specified key code.
+     * 
+     * @param a0
+     *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
+     *            VK_KANA_LOCK.
+     * @param a1
+     *            the state - true to set the specified key code to the locked
+     *            state, false - to unlock it.
+     * @throws UnsupportedOperationException
+     *             if the state of this key can't be set, or if the keyboard
+     *             doesn't have this key.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException,
+            org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return;
+    }
+
+    /**
+     * On queue empty.
+     */
+    void onQueueEmpty() {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Creates the wtk.
+     * 
+     * @param clsName
+     *            the cls name.
+     * @return the wTK.
+     */
+    private WTK createWTK(String clsName) {
+        WTK newWTK = null;
+        try {
+            newWTK = (WTK)Class.forName(clsName).newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return newWTK;
+    }
+
+    /**
+     * Connect the component to its native window
+     * 
+     * @param winId
+     *            the id of native window just created.
+     */
+    boolean onWindowCreated(long winId) {
+        return false;
+    }
+
+    /**
+     * Gets the native event queue.
+     * 
+     * @return the native event queue.
+     */
+    NativeEventQueue getNativeEventQueue() {
+        return wtk.getNativeEventQueue();
+    }
+
+    /**
+     * Returns a shared instance of implementation of
+     * org.apache.harmony.awt.wtk.NativeCursor for current platform for.
+     * 
+     * @param type
+     *            the Java Cursor type.
+     * @return new instance of implementation of NativeCursor.
+     */
+    NativeCursor createNativeCursor(int type) {
+        return wtk.getCursorFactory().getCursor(type);
+    }
+
+    /**
+     * Returns a shared instance of implementation of
+     * org.apache.harmony.awt.wtk.NativeCursor for current platform for custom
+     * cursor
+     * 
+     * @param img
+     *            the img.
+     * @param hotSpot
+     *            the hot spot.
+     * @param name
+     *            the name.
+     * @return new instance of implementation of NativeCursor.
+     */
+    NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
+        return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
+    }
+
+    /**
+     * Adds an AWTEventListener to the Toolkit to listen for events of types
+     * corresponding to bits in the specified event mask. Event masks are
+     * defined in AWTEvent class.
+     * 
+     * @param listener
+     *            the AWTEventListener.
+     * @param eventMask
+     *            the bitmask of event types.
+     */
+    public void addAWTEventListener(AWTEventListener listener, long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.addAWTEventListener(listener, eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the specified AWT event listener.
+     * 
+     * @param listener
+     *            the AWTEventListener to be removed.
+     */
+    public void removeAWTEventListener(AWTEventListener listener) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.removeAWTEventListener(listener);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the array of all AWT event listeners registered with this Toolkit.
+     * 
+     * @return the array of all AWT event listeners registered with this
+     *         Toolkit.
+     */
+    public AWTEventListener[] getAWTEventListeners() {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the array of the AWT event listeners registered with this Toolkit
+     * for the event types corresponding to the specified event mask.
+     * 
+     * @param eventMask
+     *            the bit mask of event type.
+     * @return the array of the AWT event listeners registered in this Toolkit
+     *         for the event types corresponding to the specified event mask.
+     */
+    public AWTEventListener[] getAWTEventListeners(long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners(eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatch AWT event.
+     * 
+     * @param event
+     *            the event.
+     */
+    void dispatchAWTEvent(AWTEvent event) {
+        awtEventsManager.dispatchAWTEvent(event);
+    }
+
+    /**
+     * The Class AWTEventsManager.
+     */
+    final class AWTEventsManager {
+
+        /**
+         * The permission.
+         */
+        AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
+
+        /**
+         * The listeners.
+         */
+        private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
+
+        /**
+         * Adds the AWT event listener.
+         * 
+         * @param listener
+         *            the listener.
+         * @param eventMask
+         *            the event mask.
+         */
+        void addAWTEventListener(AWTEventListener listener, long eventMask) {
+            if (listener != null) {
+                listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
+            }
+        }
+
+        /**
+         * Removes the AWT event listener.
+         * 
+         * @param listener
+         *            the listener.
+         */
+        void removeAWTEventListener(AWTEventListener listener) {
+            if (listener != null) {
+                for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                    if (listener == proxy.getListener()) {
+                        listeners.removeUserListener(proxy);
+                        return;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Gets the AWT event listeners.
+         * 
+         * @return the AWT event listeners.
+         */
+        AWTEventListener[] getAWTEventListeners() {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                listenersSet.add(proxy.getListener());
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Gets the AWT event listeners.
+         * 
+         * @param eventMask
+         *            the event mask.
+         * @return the AWT event listeners.
+         */
+        AWTEventListener[] getAWTEventListeners(long eventMask) {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & eventMask) == eventMask) {
+                    listenersSet.add(proxy.getListener());
+                }
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Dispatch AWT event.
+         * 
+         * @param event
+         *            the event.
+         */
+        void dispatchAWTEvent(AWTEvent event) {
+            AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
+            if (descriptor == null) {
+                return;
+            }
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
+                    proxy.eventDispatched(event);
+                }
+            }
+        }
+    }
+
+    /**
+     * The Class AutoNumber.
+     */
+    static final class AutoNumber {
+
+        /**
+         * The next component.
+         */
+        int nextComponent = 0;
+
+        /**
+         * The next canvas.
+         */
+        int nextCanvas = 0;
+
+        /**
+         * The next panel.
+         */
+        int nextPanel = 0;
+
+        /**
+         * The next window.
+         */
+        int nextWindow = 0;
+
+        /**
+         * The next frame.
+         */
+        int nextFrame = 0;
+
+        /**
+         * The next dialog.
+         */
+        int nextDialog = 0;
+
+        /**
+         * The next button.
+         */
+        int nextButton = 0;
+
+        /**
+         * The next menu component.
+         */
+        int nextMenuComponent = 0;
+
+        /**
+         * The next label.
+         */
+        int nextLabel = 0;
+
+        /**
+         * The next check box.
+         */
+        int nextCheckBox = 0;
+
+        /**
+         * The next scrollbar.
+         */
+        int nextScrollbar = 0;
+
+        /**
+         * The next scroll pane.
+         */
+        int nextScrollPane = 0;
+
+        /**
+         * The next list.
+         */
+        int nextList = 0;
+
+        /**
+         * The next choice.
+         */
+        int nextChoice = 0;
+
+        /**
+         * The next file dialog.
+         */
+        int nextFileDialog = 0;
+
+        /**
+         * The next text area.
+         */
+        int nextTextArea = 0;
+
+        /**
+         * The next text field.
+         */
+        int nextTextField = 0;
+    }
+
+    private class Lock {
+    }
+
+    /**
+     * The lock.
+     */
+    private final Object lock = new Lock();
+
+}
diff --git a/awt/java/awt/ToolkitImpl.java b/awt/java/awt/ToolkitImpl.java
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..44a1e7f
--- /dev/null
+++ b/awt/java/awt/Transparency.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 Pavel Dolgov
+ * @version $Revision$
+ */
+
+package java.awt;
+
+/**
+ * The Transparency interface defines transparency's general modes.
+ * 
+ * @since Android 1.0
+ */
+public interface Transparency {
+
+    /**
+     * The Constant OPAQUE represents completely opaque data, all pixels have an
+     * alpha value of 1.0.
+     */
+    public static final int OPAQUE = 1;
+
+    /**
+     * The Constant BITMASK represents data which can be either completely
+     * opaque, with an alpha value of 1.0, or completely transparent, with an
+     * alpha value of 0.0.
+     */
+    public static final int BITMASK = 2;
+
+    /**
+     * The Constant TRANSLUCENT represents data which alpha value can vary
+     * between and including 0.0 and 1.0.
+     */
+    public static final int TRANSLUCENT = 3;
+
+    /**
+     * Gets the transparency mode.
+     * 
+     * @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.
+     */
+    public int getTransparency();
+
+}
diff --git a/awt/java/awt/color/CMMException.java b/awt/java/awt/color/CMMException.java
new file mode 100644
index 0000000..18b9a7e
--- /dev/null
+++ b/awt/java/awt/color/CMMException.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$
+ */
+package java.awt.color;
+
+/**
+ * The CMMException is thrown as soon as a native CMM error occurs.
+ * 
+ * @since Android 1.0
+ */
+public class CMMException extends java.lang.RuntimeException {
+    
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 5775558044142994965L;
+
+    /**
+     * Instantiates a new CMM exception with detail message.
+     * 
+     * @param s
+     *            the detail message of the exception.
+     */
+    public CMMException (String s) {
+        super (s);
+    }
+}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
new file mode 100644
index 0000000..44c491b
--- /dev/null
+++ b/awt/java/awt/color/ColorSpace.java
@@ -0,0 +1,414 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.Serializable;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorSpace class defines a color space type for a Color and provides
+ * methods for arrays of color component operations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class ColorSpace implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -409452704308689724L;
+
+    /**
+     * The Constant TYPE_XYZ indicates XYZ color space type.
+     */
+    public static final int TYPE_XYZ = 0;
+
+    /**
+     * The Constant TYPE_Lab indicates Lab color space type.
+     */
+    public static final int TYPE_Lab = 1;
+
+    /**
+     * The Constant TYPE_Luv indicates Luv color space type.
+     */
+    public static final int TYPE_Luv = 2;
+
+    /**
+     * The Constant TYPE_YCbCr indicates YCbCr color space type.
+     */
+    public static final int TYPE_YCbCr = 3;
+
+    /**
+     * The Constant TYPE_Yxy indicates Yxy color space type.
+     */
+    public static final int TYPE_Yxy = 4;
+
+    /**
+     * The Constant TYPE_RGB indicates RGB color space type.
+     */
+    public static final int TYPE_RGB = 5;
+
+    /**
+     * The Constant TYPE_GRAY indicates Gray color space type.
+     */
+    public static final int TYPE_GRAY = 6;
+
+    /**
+     * The Constant TYPE_HSV indicates HSV color space type.
+     */
+    public static final int TYPE_HSV = 7;
+
+    /**
+     * The Constant TYPE_HLS indicates HLS color space type.
+     */
+    public static final int TYPE_HLS = 8;
+
+    /**
+     * The Constant TYPE_CMYK indicates CMYK color space type.
+     */
+    public static final int TYPE_CMYK = 9;
+
+    /**
+     * The Constant TYPE_CMY indicates CMY color space type.
+     */
+    public static final int TYPE_CMY = 11;
+
+    /**
+     * The Constant TYPE_2CLR indicates color spaces with 2 components.
+     */
+    public static final int TYPE_2CLR = 12;
+
+    /**
+     * The Constant TYPE_3CLR indicates color spaces with 3 components.
+     */
+    public static final int TYPE_3CLR = 13;
+
+    /**
+     * The Constant TYPE_4CLR indicates color spaces with 4 components.
+     */
+    public static final int TYPE_4CLR = 14;
+
+    /**
+     * The Constant TYPE_5CLR indicates color spaces with 5 components.
+     */
+    public static final int TYPE_5CLR = 15;
+
+    /**
+     * The Constant TYPE_6CLR indicates color spaces with 6 components.
+     */
+    public static final int TYPE_6CLR = 16;
+
+    /**
+     * The Constant TYPE_7CLR indicates color spaces with 7 components.
+     */
+    public static final int TYPE_7CLR = 17;
+
+    /**
+     * The Constant TYPE_8CLR indicates color spaces with 8 components.
+     */
+    public static final int TYPE_8CLR = 18;
+
+    /**
+     * The Constant TYPE_9CLR indicates color spaces with 9 components.
+     */
+    public static final int TYPE_9CLR = 19;
+
+    /**
+     * The Constant TYPE_ACLR indicates color spaces with 10 components.
+     */
+    public static final int TYPE_ACLR = 20;
+
+    /**
+     * The Constant TYPE_BCLR indicates color spaces with 11 components.
+     */
+    public static final int TYPE_BCLR = 21;
+
+    /**
+     * The Constant TYPE_CCLR indicates color spaces with 12 components.
+     */
+    public static final int TYPE_CCLR = 22;
+
+    /**
+     * The Constant TYPE_DCLR indicates color spaces with 13 components.
+     */
+    public static final int TYPE_DCLR = 23;
+
+    /**
+     * The Constant TYPE_ECLR indicates color spaces with 14 components.
+     */
+    public static final int TYPE_ECLR = 24;
+
+    /**
+     * The Constant TYPE_FCLR indicates color spaces with 15 components.
+     */
+    public static final int TYPE_FCLR = 25;
+
+    /**
+     * The Constant CS_sRGB indicates standard RGB color space.
+     */
+    public static final int CS_sRGB = 1000;
+
+    /**
+     * The Constant CS_LINEAR_RGB indicates linear RGB color space.
+     */
+    public static final int CS_LINEAR_RGB = 1004;
+
+    /**
+     * The Constant CS_CIEXYZ indicates CIEXYZ conversion color space.
+     */
+    public static final int CS_CIEXYZ = 1001;
+
+    /**
+     * The Constant CS_PYCC indicates Photo YCC conversion color space.
+     */
+    public static final int CS_PYCC = 1002;
+
+    /**
+     * The Constant CS_GRAY indicates linear gray scale color space.
+     */
+    public static final int CS_GRAY = 1003;
+
+    /**
+     * The cs_ gray.
+     */
+    private static ColorSpace cs_Gray = null;
+    
+    /**
+     * The cs_ pycc.
+     */
+    private static ColorSpace cs_PYCC = null;
+    
+    /**
+     * The cs_ ciexyz.
+     */
+    private static ColorSpace cs_CIEXYZ = null;
+    
+    /**
+     * The cs_ lrgb.
+     */
+    private static ColorSpace cs_LRGB = null;
+    
+    /**
+     * The cs_s rgb.
+     */
+    private static ColorSpace cs_sRGB = null;
+
+    /**
+     * The type.
+     */
+    private int type;
+    
+    /**
+     * The num components.
+     */
+    private int numComponents;
+
+    /**
+     * Instantiates a ColorSpace with the specified ColorSpace type and number
+     * of components.
+     * 
+     * @param type
+     *            the type of color space.
+     * @param numcomponents
+     *            the number of components.
+     */
+    protected ColorSpace(int type, int numcomponents) {
+        this.numComponents = numcomponents;
+        this.type = type;
+    }
+
+    /**
+     * Gets the name of the component for the specified component index.
+     * 
+     * @param idx
+     *            the index of the component.
+     * @return the name of the component.
+     */
+    public String getName(int idx) {
+        if (idx < 0 || idx > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", idx)); //$NON-NLS-1$
+        }
+
+      return "Unnamed color component #" + idx; //$NON-NLS-1$
+    }
+
+    /**
+     * Performs the transformation of a color from this ColorSpace into the RGB
+     * color space.
+     * 
+     * @param colorvalue
+     *            the color value in this ColorSpace.
+     * @return the float array with color components in the RGB color space.
+     */
+    public abstract float[] toRGB(float[] colorvalue);
+
+    /**
+     * Performs the transformation of a color from this ColorSpace into the
+     * CS_CIEXYZ color space.
+     * 
+     * @param colorvalue
+     *            the color value in this ColorSpace.
+     * @return the float array with color components in the CS_CIEXYZ color
+     *         space.
+     */
+    public abstract float[] toCIEXYZ(float[] colorvalue);
+
+    /**
+     * Performs the transformation of a color from the RGB color space into this
+     * ColorSpace.
+     * 
+     * @param rgbvalue
+     *            the float array representing a color in the RGB color space.
+     * @return the float array with the transformed color components.
+     */
+    public abstract float[] fromRGB(float[] rgbvalue);
+
+    /**
+     * Performs the transformation of a color from the CS_CIEXYZ color space
+     * into this ColorSpace.
+     * 
+     * @param colorvalue
+     *            the float array representing a color in the CS_CIEXYZ color
+     *            space.
+     * @return the float array with the transformed color components.
+     */
+    public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+    /**
+     * Gets the minimum normalized color component value for the specified
+     * component.
+     * 
+     * @param component
+     *            the component to determine the minimum value.
+     * @return the minimum normalized value of the component.
+     */
+    public float getMinValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the maximum normalized color component value for the specified
+     * component.
+     * 
+     * @param component
+     *            the component to determine the maximum value.
+     * @return the maximum normalized value of the component.
+     */
+    public float getMaxValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 1;
+    }
+
+    /**
+     * Checks if this ColorSpace has CS_sRGB type or not.
+     * 
+     * @return true, if this ColorSpace has CS_sRGB type, false otherwise.
+     */
+    public boolean isCS_sRGB() {
+        // If our color space is sRGB, then cs_sRGB
+        // is already initialized
+        return (this == cs_sRGB);
+    }
+
+    /**
+     * Gets the type of the ColorSpace.
+     * 
+     * @return the type of the ColorSpace.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the number of components for this ColorSpace.
+     * 
+     * @return the number of components.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+
+    /**
+     * Gets the single instance of ColorSpace with the specified ColorSpace:
+     * CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_GRAY, or CS_PYCC.
+     * 
+     * @param colorspace
+     *            the identifier of the specified Colorspace.
+     * @return the single instance of the desired ColorSpace.
+     */
+    public static ColorSpace getInstance(int colorspace) {
+        switch (colorspace) {
+            case CS_sRGB:
+                if (cs_sRGB == null) {
+                    cs_sRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_sRGB));
+                    LUTColorConverter.sRGB_CS = cs_sRGB;
+                            //ICC_Profile.getInstance (CS_sRGB));
+                }
+                return cs_sRGB;
+            case CS_CIEXYZ:
+                if (cs_CIEXYZ == null) {
+                    cs_CIEXYZ = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_CIEXYZ));
+                            //ICC_Profile.getInstance (CS_CIEXYZ));
+                }
+                return cs_CIEXYZ;
+            case CS_GRAY:
+                if (cs_Gray == null) {
+                    cs_Gray = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_GRAY));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_GRAY));
+                }
+                return cs_Gray;
+            case CS_PYCC:
+                if (cs_PYCC == null) {
+                    cs_PYCC = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_PYCC));
+                            //ICC_Profile.getInstance (CS_PYCC));
+                }
+                return cs_PYCC;
+            case CS_LINEAR_RGB:
+                if (cs_LRGB == null) {
+                    cs_LRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_LINEAR_RGB));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_LINEAR_RGB));
+                }
+                return cs_LRGB;
+            default:
+        }
+
+        // Unknown argument passed
+        // awt.16B=Not a predefined colorspace
+        throw new IllegalArgumentException(Messages.getString("Not a predefined colorspace")); //$NON-NLS-1$
+    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ICC_ColorSpace.java b/awt/java/awt/color/ICC_ColorSpace.java
new file mode 100644
index 0000000..5b4d7e9
--- /dev/null
+++ b/awt/java/awt/color/ICC_ColorSpace.java
@@ -0,0 +1,468 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import java.io.*;
+
+/**
+ * This class implements the abstract class ColorSpace and represents device
+ * independent and device dependent color spaces. This color space is based on
+ * the International Color Consortium Specification (ICC) File Format for Color
+ * Profiles: <a href="http://www.color.org">http://www.color.org</a>
+ * 
+ * @since Android 1.0
+ */
+public class ICC_ColorSpace extends ColorSpace {
+    
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 3455889114070431483L;
+
+    // Need to keep compatibility with serialized form
+    /**
+     * The Constant serialPersistentFields.
+     */
+    private static final ObjectStreamField[]
+      serialPersistentFields = {
+        new ObjectStreamField("thisProfile", ICC_Profile.class), //$NON-NLS-1$
+        new ObjectStreamField("minVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("maxVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("diffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("invDiffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("needScaleInit", Boolean.TYPE) //$NON-NLS-1$
+    };
+
+
+   /**
+     * According to ICC specification (from http://www.color.org) "For the
+     * CIEXYZ encoding, each component (X, Y, and Z) is encoded as a
+     * u1Fixed15Number". This means that max value for this encoding is 1 +
+     * (32767/32768)
+     */
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+    
+    /**
+     * The Constant MAX_SHORT.
+     */
+    private static final float MAX_SHORT = 65535f;
+    
+    /**
+     * The Constant INV_MAX_SHORT.
+     */
+    private static final float INV_MAX_SHORT = 1f/MAX_SHORT;
+    
+    /**
+     * The Constant SHORT2XYZ_FACTOR.
+     */
+    private static final float SHORT2XYZ_FACTOR = MAX_XYZ/MAX_SHORT;
+    
+    /**
+     * The Constant XYZ2SHORT_FACTOR.
+     */
+    private static final float XYZ2SHORT_FACTOR = MAX_SHORT/MAX_XYZ;
+
+    /**
+     * The profile.
+     */
+    private ICC_Profile profile = null;
+    
+    /**
+     * The min values.
+     */
+    private float minValues[] = null;
+    
+    /**
+     * The max values.
+     */
+    private float maxValues[] = null;
+
+    // cache transforms here - performance gain
+    /**
+     * The to rgb transform.
+     */
+    private ICC_Transform toRGBTransform = null;
+    
+    /**
+     * The from rgb transform.
+     */
+    private ICC_Transform fromRGBTransform = null;
+    
+    /**
+     * The to xyz transform.
+     */
+    private ICC_Transform toXYZTransform = null;
+    
+    /**
+     * The from xyz transform.
+     */
+    private ICC_Transform fromXYZTransform = null;
+
+    /**
+     * The converter.
+     */
+    private final ColorConverter converter = new ColorConverter();
+    
+    /**
+     * The scaler.
+     */
+    private final ColorScaler scaler = new ColorScaler();
+    
+    /**
+     * The scaling data loaded.
+     */
+    private boolean scalingDataLoaded = false;
+
+    /**
+     * The resolved deserialized inst.
+     */
+    private ICC_ColorSpace resolvedDeserializedInst;
+
+    /**
+     * Instantiates a new ICC color space from an ICC_Profile object.
+     * 
+     * @param pf
+     *            the ICC_Profile object.
+     */
+    public ICC_ColorSpace(ICC_Profile pf) {
+        super(pf.getColorSpaceType(), pf.getNumComponents());
+
+        int pfClass = pf.getProfileClass();
+
+        switch (pfClass) {
+            case ICC_Profile.CLASS_COLORSPACECONVERSION:
+            case ICC_Profile.CLASS_DISPLAY:
+            case ICC_Profile.CLASS_OUTPUT:
+            case ICC_Profile.CLASS_INPUT:
+                break; // OK, it is color conversion profile
+            default:
+                // awt.168=Invalid profile class.
+                throw new IllegalArgumentException(Messages.getString("awt.168")); //$NON-NLS-1$
+        }
+
+        profile = pf;
+        fillMinMaxValues();
+    }
+
+    /**
+     * Gets the ICC_Profile for this ICC_ColorSpace.
+     * 
+     * @return the ICC_Profile for this ICC_ColorSpace.
+     */
+    public ICC_Profile getProfile() {
+        if (profile instanceof ICC_ProfileStub) {
+            profile = ((ICC_ProfileStub) profile).loadProfile();
+        }
+
+        return profile;
+    }
+
+    /**
+     * Performs the transformation of a color from this ColorSpace into the RGB
+     * color space.
+     * 
+     * @param colorvalue
+     *            the color value in this ColorSpace.
+     * @return the float array with color components in the RGB color space.
+     */
+    @Override
+    public float[] toRGB(float[] colorvalue) {
+        if (toRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), sRGBProfile};
+            toRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toRGBTransform, data, null);
+
+        // unscale to sRGB
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * INV_MAX_SHORT;
+        res[1] = ((converted[1] & 0xFFFF)) * INV_MAX_SHORT;
+        res[2] = ((converted[2] & 0xFFFF)) * INV_MAX_SHORT;
+
+        return res;
+    }
+
+    /**
+     * Performs the transformation of a color from this ColorSpace into the
+     * CS_CIEXYZ color space.
+     * 
+     * @param colorvalue
+     *            the color value in this ColorSpace.
+     * @return the float array with color components in the CS_CIEXYZ color
+     *         space.
+     */
+    @Override
+    public float[] toCIEXYZ(float[] colorvalue) {
+        if (toXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), xyzProfile};
+            try {
+                int[] intents = {
+                        ICC_Profile.icRelativeColorimetric,
+                        ICC_Profile.icPerceptual};
+                toXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                toXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toXYZTransform, data, null);
+
+        // unscale to XYZ
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[1] = ((converted[1] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[2] = ((converted[2] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+
+        return res;
+    }
+
+    /**
+     * Performs the transformation of a color from the RGB color space into this
+     * ColorSpace.
+     * 
+     * @param rgbvalue
+     *            the float array representing a color in the RGB color space.
+     * @return the float array with the transformed color components.
+     */
+    @Override
+    public float[] fromRGB(float[] rgbvalue) {
+        if (fromRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {sRGBProfile, getProfile()};
+            fromRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        // scale rgb value to short
+        short[] scaledRGBValue = new short[3];
+        scaledRGBValue[0] = (short)(rgbvalue[0] * MAX_SHORT + 0.5f);
+        scaledRGBValue[1] = (short)(rgbvalue[1] * MAX_SHORT + 0.5f);
+        scaledRGBValue[2] = (short)(rgbvalue[2] * MAX_SHORT + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromRGBTransform, scaledRGBValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    /**
+     * Performs the transformation of a color from the CS_CIEXYZ color space
+     * into this ColorSpace.
+     * 
+     * @param xyzvalue
+     *            the float array representing a color in the CS_CIEXYZ color
+     *            space.
+     * @return the float array with the transformed color components.
+     */
+    @Override
+    public float[] fromCIEXYZ(float[] xyzvalue) {
+        if (fromXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {xyzProfile, getProfile()};
+            try {
+                int[] intents = {
+                        ICC_Profile.icPerceptual,
+                        ICC_Profile.icRelativeColorimetric};
+                fromXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                fromXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+
+        }
+
+        // scale xyz value to short
+        short[] scaledXYZValue = new short[3];
+        scaledXYZValue[0] = (short)(xyzvalue[0] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[1] = (short)(xyzvalue[1] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[2] = (short)(xyzvalue[2] * XYZ2SHORT_FACTOR + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromXYZTransform, scaledXYZValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    /**
+     * Gets the minimum normalized color component value for the specified
+     * component.
+     * 
+     * @param component
+     *            the component to determine the minimum value.
+     * @return the minimum normalized value of the component.
+     */
+    @Override
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return minValues[component];
+    }
+
+    /**
+     * Gets the maximum normalized color component value for the specified
+     * component.
+     * 
+     * @param component
+     *            the component to determine the maximum value.
+     * @return the maximum normalized value of the component.
+     */
+    @Override
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return maxValues[component];
+    }
+
+    /**
+     * Fill min max values.
+     */
+    private void fillMinMaxValues() {
+        int n = getNumComponents();
+        maxValues = new float[n];
+        minValues = new float[n];
+        switch (getType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for(int i=0; i<n; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+    }
+
+    /**
+     * Write object.
+     * 
+     * @param out
+     *            the out
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        ObjectOutputStream.PutField fields = out.putFields();
+
+        fields.put("thisProfile", profile); //$NON-NLS-1$
+        fields.put("minVal", null); //$NON-NLS-1$
+        fields.put("maxVal", null); //$NON-NLS-1$
+        fields.put("diffMinMax", null); //$NON-NLS-1$
+        fields.put("invDiffMinMax", null); //$NON-NLS-1$
+        fields.put("needScaleInit", true); //$NON-NLS-1$
+
+        out.writeFields();
+    }
+
+    /**
+     * Read object.
+     * 
+     * @param in
+     *            the in
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException
+     *             the class not found exception
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = in.readFields();
+        resolvedDeserializedInst =
+                new ICC_ColorSpace((ICC_Profile) fields.get("thisProfile", null)); //$NON-NLS-1$
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * @throws ObjectStreamException
+     *             the object stream exception
+     */
+    Object readResolve() throws ObjectStreamException {
+        return resolvedDeserializedInst;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_Profile.java b/awt/java/awt/color/ICC_Profile.java
new file mode 100644
index 0000000..8ffee6c
--- /dev/null
+++ b/awt/java/awt/color/ICC_Profile.java
@@ -0,0 +1,1477 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.color;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
+import org.apache.harmony.awt.gl.color.NativeCMM;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_Profile class represents a color profile data for color spaces based
+ * on the International Color Consortium Specification ICC.1:2001-12, File
+ * Format for Color Profiles.
+ * 
+ * @since Android 1.0
+ */
+public class ICC_Profile implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -3938515861990936766L;
+
+    // NOTE: Constant field values are noted in 1.5 specification.
+
+    /**
+     * The Constant CLASS_INPUT indicates that profile class is input.
+     */
+    public static final int CLASS_INPUT = 0;
+
+    /**
+     * The Constant CLASS_DISPLAY indicates that profile class is display.
+     */
+    public static final int CLASS_DISPLAY = 1;
+
+    /**
+     * The Constant CLASS_OUTPUT indicates that profile class is output.
+     */
+    public static final int CLASS_OUTPUT = 2;
+
+    /**
+     * The Constant CLASS_DEVICELINK indicates that profile class is device
+     * link.
+     */
+    public static final int CLASS_DEVICELINK = 3;
+
+    /**
+     * The Constant CLASS_COLORSPACECONVERSION indicates that profile class is
+     * color space conversion.
+     */
+    public static final int CLASS_COLORSPACECONVERSION = 4;
+
+    /**
+     * The Constant CLASS_ABSTRACT indicates that profile class is abstract.
+     */
+    public static final int CLASS_ABSTRACT = 5;
+
+    /**
+     * The Constant CLASS_NAMEDCOLOR indicates that profile class is named
+     * color.
+     */
+    public static final int CLASS_NAMEDCOLOR = 6;
+
+    /**
+     * The Constant icSigXYZData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigXYZData = 1482250784;
+
+    /**
+     * The Constant icSigLabData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigLabData = 1281450528;
+
+    /**
+     * The Constant icSigLuvData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigLuvData = 1282766368;
+
+    /**
+     * The Constant icSigYCbCrData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigYCbCrData = 1497588338;
+
+    /**
+     * The Constant icSigYxyData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigYxyData = 1501067552;
+
+    /**
+     * The Constant icSigRgbData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigRgbData = 1380401696;
+
+    /**
+     * The Constant icSigGrayData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigGrayData = 1196573017;
+
+    /**
+     * The Constant icSigHsvData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigHsvData = 1213421088;
+
+    /**
+     * The Constant icSigHlsData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigHlsData = 1212961568;
+
+    /**
+     * The Constant icSigCmykData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigCmykData = 1129142603;
+
+    /**
+     * The Constant icSigCmyData - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigCmyData = 1129142560;
+
+    /**
+     * The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace2CLR = 843271250;
+
+    /**
+     * The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace3CLR = 860048466;
+
+    /**
+     * The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace4CLR = 876825682;
+
+    /**
+     * The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace5CLR = 893602898;
+
+    /**
+     * The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace6CLR = 910380114;
+
+    /**
+     * The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace7CLR = 927157330;
+
+    /**
+     * The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace8CLR = 943934546;
+
+    /**
+     * The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpace9CLR = 960711762;
+
+    /**
+     * The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceACLR = 1094929490;
+
+    /**
+     * The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceBCLR = 1111706706;
+
+    /**
+     * The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceCCLR = 1128483922;
+
+    /**
+     * The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceDCLR = 1145261138;
+
+    /**
+     * The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceECLR = 1162038354;
+
+    /**
+     * The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature.
+     */
+    public static final int icSigSpaceFCLR = 1178815570;
+
+    /**
+     * The Constant icSigInputClass - ICC Profile Class Signature.
+     */
+    public static final int icSigInputClass = 1935896178;
+
+    /**
+     * The Constant icSigDisplayClass - ICC Profile Class Signature.
+     */
+    public static final int icSigDisplayClass = 1835955314;
+
+    /**
+     * The Constant icSigOutputClass - ICC Profile Class Signature.
+     */
+    public static final int icSigOutputClass = 1886549106;
+
+    /**
+     * The Constant icSigLinkClass - ICC Profile Class Signature.
+     */
+    public static final int icSigLinkClass = 1818848875;
+
+    /**
+     * The Constant icSigAbstractClass - ICC Profile Class Signature.
+     */
+    public static final int icSigAbstractClass = 1633842036;
+
+    /**
+     * The Constant icSigColorantOrderTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigColorantOrderTag = 1668051567;
+
+    /**
+     * The Constant icSigColorantTableTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigColorantTableTag = 1668051572;
+
+    /**
+     * The Constant icSigColorSpaceClass - ICC Profile Tag Signature.
+     */
+    public static final int icSigColorSpaceClass = 1936744803;
+
+    /**
+     * The Constant icSigNamedColorClass - ICC Profile Tag Signature.
+     */
+    public static final int icSigNamedColorClass = 1852662636;
+
+    /**
+     * The Constant icPerceptual - ICC Profile Rendering Intent.
+     */
+    public static final int icPerceptual = 0;
+
+    /**
+     * The Constant icRelativeColorimetric - ICC Profile Rendering Intent.
+     */
+    public static final int icRelativeColorimetric = 1;
+
+    /**
+     * The Constant icSaturation - ICC Profile Rendering Intent.
+     */
+    public static final int icSaturation = 2;
+
+    /**
+     * The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent.
+     */
+    public static final int icAbsoluteColorimetric = 3;
+
+    /**
+     * The Constant icSigHead - ICC Profile Tag Signature.
+     */
+    public static final int icSigHead = 1751474532;
+
+    /**
+     * The Constant icSigAToB0Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigAToB0Tag = 1093812784;
+
+    /**
+     * The Constant icSigAToB1Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigAToB1Tag = 1093812785;
+
+    /**
+     * The Constant icSigAToB2Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigAToB2Tag = 1093812786;
+
+    /**
+     * The Constant icSigBlueColorantTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBlueColorantTag = 1649957210;
+
+    /**
+     * The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBlueMatrixColumnTag = 1649957210;
+
+    /**
+     * The Constant icSigBlueTRCTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBlueTRCTag = 1649693251;
+
+    /**
+     * The Constant icSigBToA0Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBToA0Tag = 1110589744;
+
+    /**
+     * The Constant icSigBToA1Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBToA1Tag = 1110589745;
+
+    /**
+     * The Constant icSigBToA2Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigBToA2Tag = 1110589746;
+
+    /**
+     * The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigCalibrationDateTimeTag = 1667329140;
+
+    /**
+     * The Constant icSigCharTargetTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigCharTargetTag = 1952543335;
+
+    /**
+     * The Constant icSigCopyrightTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigCopyrightTag = 1668313716;
+
+    /**
+     * The Constant icSigCrdInfoTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigCrdInfoTag = 1668441193;
+
+    /**
+     * The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigDeviceMfgDescTag = 1684893284;
+
+    /**
+     * The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigDeviceModelDescTag = 1684890724;
+
+    /**
+     * The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigDeviceSettingsTag = 1684371059;
+
+    /**
+     * The Constant icSigGamutTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigGamutTag = 1734438260;
+
+    /**
+     * The Constant icSigGrayTRCTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigGrayTRCTag = 1800688195;
+
+    /**
+     * The Constant icSigGreenColorantTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigGreenColorantTag = 1733843290;
+
+    /**
+     * The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigGreenMatrixColumnTag = 1733843290;
+
+    /**
+     * The Constant icSigGreenTRCTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigGreenTRCTag = 1733579331;
+
+    /**
+     * The Constant icSigLuminanceTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigLuminanceTag = 1819635049;
+
+    /**
+     * The Constant icSigMeasurementTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigMeasurementTag = 1835360627;
+
+    /**
+     * The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigMediaBlackPointTag = 1651208308;
+
+    /**
+     * The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigMediaWhitePointTag = 2004119668;
+
+    /**
+     * The Constant icSigNamedColor2Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigNamedColor2Tag = 1852009522;
+
+    /**
+     * The Constant icSigOutputResponseTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigOutputResponseTag = 1919251312;
+
+    /**
+     * The Constant icSigPreview0Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPreview0Tag = 1886545200;
+
+    /**
+     * The Constant icSigPreview1Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPreview1Tag = 1886545201;
+
+    /**
+     * The Constant icSigPreview2Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPreview2Tag = 1886545202;
+
+    /**
+     * The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigProfileDescriptionTag = 1684370275;
+
+    /**
+     * The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigProfileSequenceDescTag = 1886610801;
+
+    /**
+     * The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2CRD0Tag = 1886610480;
+
+    /**
+     * The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2CRD1Tag = 1886610481;
+
+    /**
+     * The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2CRD2Tag = 1886610482;
+
+    /**
+     * The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2CRD3Tag = 1886610483;
+
+    /**
+     * The Constant icSigPs2CSATag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2CSATag = 1886597747;
+
+    /**
+     * The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigPs2RenderingIntentTag = 1886597737;
+
+    /**
+     * The Constant icSigRedColorantTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigRedColorantTag = 1918392666;
+
+    /**
+     * The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigRedMatrixColumnTag = 1918392666;
+
+    /**
+     * The Constant icSigRedTRCTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigRedTRCTag = 1918128707;
+
+    /**
+     * The Constant icSigScreeningDescTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigScreeningDescTag = 1935897188;
+
+    /**
+     * The Constant icSigScreeningTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigScreeningTag = 1935897198;
+
+    /**
+     * The Constant icSigTechnologyTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigTechnologyTag = 1952801640;
+
+    /**
+     * The Constant icSigUcrBgTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigUcrBgTag = 1650877472;
+
+    /**
+     * The Constant icSigViewingCondDescTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigViewingCondDescTag = 1987405156;
+
+    /**
+     * The Constant icSigViewingConditionsTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigViewingConditionsTag = 1986618743;
+
+    /**
+     * The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigChromaticAdaptationTag = 1667785060;
+
+    /**
+     * The Constant icSigChromaticityTag - ICC Profile Tag Signature.
+     */
+    public static final int icSigChromaticityTag = 1667789421;
+
+    /**
+     * The Constant icHdrSize - ICC Profile Header Location.
+     */
+    public static final int icHdrSize = 0;
+
+    /**
+     * The Constant icHdrCmmId - ICC Profile Header Location.
+     */
+    public static final int icHdrCmmId = 4;
+
+    /**
+     * The Constant icHdrVersion - ICC Profile Header Location.
+     */
+    public static final int icHdrVersion = 8;
+
+    /**
+     * The Constant icHdrDeviceClass - ICC Profile Header Location.
+     */
+    public static final int icHdrDeviceClass = 12;
+
+    /**
+     * The Constant icHdrColorSpace - ICC Profile Header Location.
+     */
+    public static final int icHdrColorSpace = 16;
+
+    /**
+     * The Constant icHdrPcs - ICC Profile Header Location.
+     */
+    public static final int icHdrPcs = 20;
+
+    /**
+     * The Constant icHdrDate - ICC Profile Header Location.
+     */
+    public static final int icHdrDate = 24;
+
+    /**
+     * The Constant icHdrMagic - ICC Profile Header Location.
+     */
+    public static final int icHdrMagic = 36;
+
+    /**
+     * The Constant icHdrPlatform - ICC Profile Header Location.
+     */
+    public static final int icHdrPlatform = 40;
+
+    /**
+     * The Constant icHdrProfileID - ICC Profile Header Location.
+     */
+    public static final int icHdrProfileID = 84;
+
+    /**
+     * The Constant icHdrFlags - ICC Profile Header Location.
+     */
+    public static final int icHdrFlags = 44;
+
+    /**
+     * The Constant icHdrManufacturer - ICC Profile Header Location.
+     */
+    public static final int icHdrManufacturer = 48;
+
+    /**
+     * The Constant icHdrModel - ICC Profile Header Location.
+     */
+    public static final int icHdrModel = 52;
+
+    /**
+     * The Constant icHdrAttributes - ICC Profile Header Location.
+     */
+    public static final int icHdrAttributes = 56;
+
+    /**
+     * The Constant icHdrRenderingIntent - ICC Profile Header Location.
+     */
+    public static final int icHdrRenderingIntent = 64;
+
+    /**
+     * The Constant icHdrIlluminant - ICC Profile Header Location.
+     */
+    public static final int icHdrIlluminant = 68;
+
+    /**
+     * The Constant icHdrCreator - ICC Profile Header Location.
+     */
+    public static final int icHdrCreator = 80;
+
+    /**
+     * The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent.
+     */
+    public static final int icICCAbsoluteColorimetric = 3;
+
+    /**
+     * The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent.
+     */
+    public static final int icMediaRelativeColorimetric = 1;
+
+    /**
+     * The Constant icTagType - ICC Profile Constant.
+     */
+    public static final int icTagType = 0;
+
+    /**
+     * The Constant icTagReserved - ICC Profile Constant.
+     */
+    public static final int icTagReserved = 4;
+
+    /**
+     * The Constant icCurveCount - ICC Profile Constant.
+     */
+    public static final int icCurveCount = 8;
+
+    /**
+     * The Constant icCurveData - ICC Profile Constant.
+     */
+    public static final int icCurveData = 12;
+
+    /**
+     * The Constant icXYZNumberX - ICC Profile Constant.
+     */
+    public static final int icXYZNumberX = 8;
+
+    /**
+     * Size of a profile header.
+     */
+    private static final int headerSize = 128;
+
+    /**
+     * header magic number.
+     */
+    private static final int headerMagicNumber = 0x61637370;
+
+    // Cache of predefined profiles
+    /**
+     * The s rgb profile.
+     */
+    private static ICC_Profile sRGBProfile;
+
+    /**
+     * The xyz profile.
+     */
+    private static ICC_Profile xyzProfile;
+
+    /**
+     * The gray profile.
+     */
+    private static ICC_Profile grayProfile;
+
+    /**
+     * The pycc profile.
+     */
+    private static ICC_Profile pyccProfile;
+
+    /**
+     * The linear rgb profile.
+     */
+    private static ICC_Profile linearRGBProfile;
+
+    /**
+     * Handle to the current profile.
+     */
+    private transient long profileHandle = 0;
+
+    /**
+     * If handle is used by another class this object is not responsible for
+     * closing profile.
+     */
+    private transient boolean handleStolen = false;
+
+    /**
+     * Cached header data.
+     */
+    private transient byte[] headerData = null;
+
+    /**
+     * Serialization support.
+     */
+    private transient ICC_Profile openedProfileObject;
+
+    /**
+     * Instantiates a new ICC profile with the given data.
+     * 
+     * @param data
+     *            the data.
+     */
+    private ICC_Profile(byte[] data) {
+        profileHandle = NativeCMM.cmmOpenProfile(data);
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Used to instantiate dummy ICC_ProfileStub objects.
+     */
+    ICC_Profile() {
+    }
+
+    /**
+     * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
+     * 
+     * @param profileHandle
+     *            - should be valid handle to opened color profile
+     */
+    ICC_Profile(long profileHandle) {
+        this.profileHandle = profileHandle;
+        // A new object reference, need to add it.
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Writes the ICC_Profile to a file with the specified name.
+     * 
+     * @param fileName
+     *            the file name.
+     * @throws IOException
+     *             if an I/O exception has occurred during writing or opening
+     *             the file.
+     */
+    public void write(String fileName) throws IOException {
+        FileOutputStream oStream = new FileOutputStream(fileName);
+        oStream.write(getData());
+        oStream.close();
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s
+     *            the s
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        s.defaultWriteObject();
+        s.writeObject(null);
+        s.writeObject(getData());
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s
+     *            the s
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException
+     *             the class not found exception
+     */
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        String colorSpaceStr = (String)s.readObject();
+        byte[] data = (byte[])s.readObject();
+
+        if (colorSpaceStr != null) {
+            if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_sRGB);
+            } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_GRAY);
+            } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
+            } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
+            } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_PYCC);
+            } else {
+                openedProfileObject = ICC_Profile.getInstance(data);
+            }
+        } else {
+            openedProfileObject = ICC_Profile.getInstance(data);
+        }
+    }
+
+    /**
+     * Resolves instances being deserialized into instances registered with CMM.
+     * 
+     * @return ICC_Profile object for profile registered with CMM.
+     * @throws ObjectStreamException
+     *             if there is an error in the serialized files or during the
+     *             process of reading them.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return openedProfileObject;
+    }
+
+    /**
+     * Writes the ICC_Profile to an OutputStream.
+     * 
+     * @param s
+     *            the OutputStream.
+     * @throws IOException
+     *             signals that an I/O exception has occurred during writing or
+     *             opening OutputStream.
+     */
+    public void write(OutputStream s) throws IOException {
+        s.write(getData());
+    }
+
+    /**
+     * Sets a tagged data element in the profile from a byte array.
+     * 
+     * @param tagSignature
+     *            the ICC tag signature for the data element to be set.
+     * @param tagData
+     *            the data to be set for the specified tag signature.
+     */
+    public void setData(int tagSignature, byte[] tagData) {
+        NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
+        // Remove cached header data if header is modified
+        if (tagSignature == icSigHead) {
+            headerData = null;
+        }
+    }
+
+    /**
+     * Gets a tagged data element from the profile as a byte array. Elements are
+     * identified by tag signatures as defined in the ICC specification.
+     * 
+     * @param tagSignature
+     *            the ICC tag signature for the data element to get.
+     * @return a byte array that contains the tagged data element.
+     */
+    public byte[] getData(int tagSignature) {
+        int tagSize = 0;
+        try {
+            tagSize = NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
+        } catch (CMMException e) {
+            // We'll get this exception if there's no element with
+            // the specified tag signature
+            return null;
+        }
+
+        byte[] data = new byte[tagSize];
+        NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
+        return data;
+    }
+
+    /**
+     * Gets a data byte array of this ICC_Profile.
+     * 
+     * @return a byte array that contains the ICC Profile data.
+     */
+    public byte[] getData() {
+        int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
+        byte[] data = new byte[profileSize];
+        NativeCMM.cmmGetProfile(profileHandle, data);
+        return data;
+    }
+
+    /**
+     * Frees the resources associated with an ICC_Profile object.
+     */
+    @Override
+    protected void finalize() {
+        if (profileHandle != 0 && !handleStolen) {
+            NativeCMM.cmmCloseProfile(profileHandle);
+        }
+
+        // Always remove because key no more exist
+        // when object is destroyed
+        NativeCMM.removeHandle(this);
+    }
+
+    /**
+     * Gets the profile class.
+     * 
+     * @return the profile class constant.
+     */
+    public int getProfileClass() {
+        int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
+
+        switch (deviceClassSignature) {
+            case icSigColorSpaceClass:
+                return CLASS_COLORSPACECONVERSION;
+            case icSigDisplayClass:
+                return CLASS_DISPLAY;
+            case icSigOutputClass:
+                return CLASS_OUTPUT;
+            case icSigInputClass:
+                return CLASS_INPUT;
+            case icSigLinkClass:
+                return CLASS_DEVICELINK;
+            case icSigAbstractClass:
+                return CLASS_ABSTRACT;
+            case icSigNamedColorClass:
+                return CLASS_NAMEDCOLOR;
+            default:
+        }
+
+        // Not an ICC profile class
+        // awt.15F=Profile class does not comply with ICC specification
+        throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
+
+    }
+
+    /**
+     * Gets the color space type of the Profile Connection Space (PCS).
+     * 
+     * @return the PCS type.
+     */
+    public int getPCSType() {
+        return csFromSignature(getIntFromHeader(icHdrPcs));
+    }
+
+    /**
+     * Gets the number of components of this ICC Profile.
+     * 
+     * @return the number of components of this ICC Profile.
+     */
+    public int getNumComponents() {
+        switch (getIntFromHeader(icHdrColorSpace)) {
+            // The most common cases go first to increase speed
+            case icSigRgbData:
+            case icSigXYZData:
+            case icSigLabData:
+                return 3;
+            case icSigCmykData:
+                return 4;
+                // Then all other
+            case icSigGrayData:
+                return 1;
+            case icSigSpace2CLR:
+                return 2;
+            case icSigYCbCrData:
+            case icSigLuvData:
+            case icSigYxyData:
+            case icSigHlsData:
+            case icSigHsvData:
+            case icSigCmyData:
+            case icSigSpace3CLR:
+                return 3;
+            case icSigSpace4CLR:
+                return 4;
+            case icSigSpace5CLR:
+                return 5;
+            case icSigSpace6CLR:
+                return 6;
+            case icSigSpace7CLR:
+                return 7;
+            case icSigSpace8CLR:
+                return 8;
+            case icSigSpace9CLR:
+                return 9;
+            case icSigSpaceACLR:
+                return 10;
+            case icSigSpaceBCLR:
+                return 11;
+            case icSigSpaceCCLR:
+                return 12;
+            case icSigSpaceDCLR:
+                return 13;
+            case icSigSpaceECLR:
+                return 14;
+            case icSigSpaceFCLR:
+                return 15;
+            default:
+        }
+
+        // awt.160=Color space doesn't comply with ICC specification
+        throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
+        );
+    }
+
+    /**
+     * Gets the minor version of this ICC profile.
+     * 
+     * @return the minor version of this ICC profile.
+     */
+    public int getMinorVersion() {
+        return getByteFromHeader(icHdrVersion + 1);
+    }
+
+    /**
+     * Gets the major version of this ICC profile.
+     * 
+     * @return the major version of this ICC profile.
+     */
+    public int getMajorVersion() {
+        return getByteFromHeader(icHdrVersion);
+    }
+
+    /**
+     * Gets the color space type of this ICC_Profile.
+     * 
+     * @return the color space type.
+     */
+    public int getColorSpaceType() {
+        return csFromSignature(getIntFromHeader(icHdrColorSpace));
+    }
+
+    /**
+     * Tries to open the file at the specified path. Path entries can be divided
+     * by a separator character.
+     * 
+     * @param path
+     *            the path to the file.
+     * @param fileName
+     *            the file name.
+     * @return the input stream to read the file.
+     */
+    private static FileInputStream tryPath(String path, String fileName) {
+        FileInputStream fiStream = null;
+
+        if (path == null) {
+            return null;
+        }
+
+        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+
+        while (st.hasMoreTokens()) {
+            String pathEntry = st.nextToken();
+            try {
+                fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
+                if (fiStream != null) {
+                    return fiStream;
+                }
+            } catch (FileNotFoundException e) {
+            }
+        }
+
+        return fiStream;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from data in the specified file.
+     * 
+     * @param fileName
+     *            the specified name of file with ICC profile data.
+     * @return single instance of ICC_Profile.
+     * @throws IOException
+     *             signals that an I/O error occurred while reading the file or
+     *             the file does not exist.
+     */
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        final String fName = fileName; // to use in the privileged block
+
+        FileInputStream fiStream = (FileInputStream)AccessController
+                .doPrivileged(new PrivilegedAction<FileInputStream>() {
+                    public FileInputStream run() {
+                        FileInputStream fiStream = null;
+
+                        // Open absolute path
+                        try {
+                            fiStream = new FileInputStream(fName);
+                            if (fiStream != null) {
+                                return fiStream;
+                            }
+                        } catch (FileNotFoundException e) {
+                        }
+
+                        // Check java.iccprofile.path entries
+                        fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check java.class.path entries
+                        fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check directory with java sample profiles
+                        String home = System.getProperty("java.home"); //$NON-NLS-1$
+                        if (home != null) {
+                            fiStream = tryPath(home + File.separatorChar
+                                    + "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
+                            );
+                        }
+
+                        return fiStream;
+                    }
+                });
+
+        if (fiStream == null) {
+            // awt.161=Unable to open file {0}
+            throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
+        }
+
+        ICC_Profile pf = getInstance(fiStream);
+        fiStream.close();
+        return pf;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with data in the specified
+     * InputStream.
+     * 
+     * @param s
+     *            the InputStream with ICC profile data.
+     * @return single instance of ICC_Profile.
+     * @throws IOException
+     *             if an I/O exception has occurred during reading from
+     *             InputStream.
+     * @throws IllegalArgumentException
+     *             if the file does not contain valid ICC Profile data.
+     */
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        byte[] header = new byte[headerSize];
+        // awt.162=Invalid ICC Profile Data
+        String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
+
+        // Get header from the input stream
+        if (s.read(header) != headerSize) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Check the profile data for consistency
+        if (ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) != headerMagicNumber) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Get profile size from header, create an array for profile data
+        int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
+        byte[] profileData = new byte[profileSize];
+
+        // Copy header into it
+        System.arraycopy(header, 0, profileData, 0, headerSize);
+
+        // Read the profile itself
+        if (s.read(profileData, headerSize, profileSize - headerSize) != profileSize - headerSize) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        return getInstance(profileData);
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from the specified data in a byte
+     * array.
+     * 
+     * @param data
+     *            the byte array of ICC profile.
+     * @return single instance of ICC_Profile from the specified data in a byte
+     *         array.
+     * @throws IllegalArgumentException
+     *             if the file does not contain valid ICC Profile data.
+     */
+    public static ICC_Profile getInstance(byte[] data) {
+        ICC_Profile res = null;
+
+        try {
+            res = new ICC_Profile(data);
+        } catch (CMMException e) {
+            // awt.162=Invalid ICC Profile Data
+            throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
+        }
+
+        if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
+            try {
+                if (res.getColorSpaceType() == ColorSpace.TYPE_RGB
+                        && res.getDataSize(icSigMediaWhitePointTag) > 0
+                        && res.getDataSize(icSigRedColorantTag) > 0
+                        && res.getDataSize(icSigGreenColorantTag) > 0
+                        && res.getDataSize(icSigBlueColorantTag) > 0
+                        && res.getDataSize(icSigRedTRCTag) > 0
+                        && res.getDataSize(icSigGreenTRCTag) > 0
+                        && res.getDataSize(icSigBlueTRCTag) > 0) {
+                    res = new ICC_ProfileRGB(res.getProfileHandle());
+                } else if (res.getColorSpaceType() == ColorSpace.TYPE_GRAY
+                        && res.getDataSize(icSigMediaWhitePointTag) > 0
+                        && res.getDataSize(icSigGrayTRCTag) > 0) {
+                    res = new ICC_ProfileGray(res.getProfileHandle());
+                }
+
+            } catch (CMMException e) { /* return res in this case */
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with the specific color space
+     * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
+     * CS_PYCC, CS_GRAY.
+     * 
+     * @param cspace
+     *            the type of color space defined in the ColorSpace class.
+     * @return single instance of ICC_Profile.
+     * @throws IllegalArgumentException
+     *             is not one of the defined color space types.
+     */
+    public static ICC_Profile getInstance(int cspace) {
+        try {
+            switch (cspace) {
+
+                case ColorSpace.CS_sRGB:
+                    if (sRGBProfile == null) {
+                        sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
+                    }
+                    return sRGBProfile;
+
+                case ColorSpace.CS_CIEXYZ:
+                    if (xyzProfile == null) {
+                        xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
+                    }
+                    return xyzProfile;
+
+                case ColorSpace.CS_GRAY:
+                    if (grayProfile == null) {
+                        grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
+                    }
+                    return grayProfile;
+
+                case ColorSpace.CS_PYCC:
+                    if (pyccProfile == null) {
+                        pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
+                    }
+                    return pyccProfile;
+
+                case ColorSpace.CS_LINEAR_RGB:
+                    if (linearRGBProfile == null) {
+                        linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
+                    }
+                    return linearRGBProfile;
+            }
+
+        } catch (IOException e) {
+            // awt.163=Can't open color profile
+            throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
+        }
+
+        // awt.164=Not a predefined color space
+        throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
+    }
+
+    /**
+     * Reads an integer from the profile header at the specified position.
+     * 
+     * @param idx
+     *            - offset in bytes from the beginning of the header
+     * @return the integer value from header
+     */
+    private int getIntFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return ((headerData[idx] & 0xFF) << 24) | ((headerData[idx + 1] & 0xFF) << 16)
+                | ((headerData[idx + 2] & 0xFF) << 8) | ((headerData[idx + 3] & 0xFF));
+    }
+
+    /**
+     * Reads byte from the profile header at the specified position.
+     * 
+     * @param idx
+     *            - offset in bytes from the beginning of the header
+     * @return the byte from header
+     */
+    private byte getByteFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return headerData[idx];
+    }
+
+    /**
+     * Converts ICC color space signature to the java predefined color space
+     * type.
+     * 
+     * @param signature
+     *            the signature
+     * @return the int
+     */
+    private int csFromSignature(int signature) {
+        switch (signature) {
+            case icSigRgbData:
+                return ColorSpace.TYPE_RGB;
+            case icSigXYZData:
+                return ColorSpace.TYPE_XYZ;
+            case icSigCmykData:
+                return ColorSpace.TYPE_CMYK;
+            case icSigLabData:
+                return ColorSpace.TYPE_Lab;
+            case icSigGrayData:
+                return ColorSpace.TYPE_GRAY;
+            case icSigHlsData:
+                return ColorSpace.TYPE_HLS;
+            case icSigLuvData:
+                return ColorSpace.TYPE_Luv;
+            case icSigYCbCrData:
+                return ColorSpace.TYPE_YCbCr;
+            case icSigYxyData:
+                return ColorSpace.TYPE_Yxy;
+            case icSigHsvData:
+                return ColorSpace.TYPE_HSV;
+            case icSigCmyData:
+                return ColorSpace.TYPE_CMY;
+            case icSigSpace2CLR:
+                return ColorSpace.TYPE_2CLR;
+            case icSigSpace3CLR:
+                return ColorSpace.TYPE_3CLR;
+            case icSigSpace4CLR:
+                return ColorSpace.TYPE_4CLR;
+            case icSigSpace5CLR:
+                return ColorSpace.TYPE_5CLR;
+            case icSigSpace6CLR:
+                return ColorSpace.TYPE_6CLR;
+            case icSigSpace7CLR:
+                return ColorSpace.TYPE_7CLR;
+            case icSigSpace8CLR:
+                return ColorSpace.TYPE_8CLR;
+            case icSigSpace9CLR:
+                return ColorSpace.TYPE_9CLR;
+            case icSigSpaceACLR:
+                return ColorSpace.TYPE_ACLR;
+            case icSigSpaceBCLR:
+                return ColorSpace.TYPE_BCLR;
+            case icSigSpaceCCLR:
+                return ColorSpace.TYPE_CCLR;
+            case icSigSpaceDCLR:
+                return ColorSpace.TYPE_DCLR;
+            case icSigSpaceECLR:
+                return ColorSpace.TYPE_ECLR;
+            case icSigSpaceFCLR:
+                return ColorSpace.TYPE_FCLR;
+            default:
+        }
+
+        // awt.165=Color space doesn't comply with ICC specification
+        throw new IllegalArgumentException(Messages.getString("awt.165")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the profile handle.
+     * 
+     * @return the profile handle
+     */
+    private long getProfileHandle() {
+        handleStolen = true;
+        return profileHandle;
+    }
+
+    /**
+     * Gets the data size.
+     * 
+     * @param tagSignature
+     *            the tag signature
+     * @return the data size
+     */
+    private int getDataSize(int tagSignature) {
+        return NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature);
+    }
+
+    /**
+     * Reads XYZ value from the tag data.
+     * 
+     * @param tagSignature
+     *            the tag signature
+     * @return the XYZ value
+     */
+    float[] getXYZValue(int tagSignature) {
+        float[] res = new float[3];
+        byte[] data = getData(tagSignature);
+
+        // Convert from ICC s15Fixed16Number type
+        // 1 (float) = 0x10000 (s15Fixed16Number),
+        // hence dividing by 0x10000
+        res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
+        res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
+        res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
+
+        return res;
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point.
+     */
+    float[] getMediaWhitePoint() {
+        return getXYZValue(icSigMediaWhitePointTag);
+    }
+
+    /**
+     * If TRC is not a table returns gamma via return value and sets dataTRC to
+     * null. If TRC is a table returns 0 and fills dataTRC with values.
+     * 
+     * @param tagSignature
+     *            the tag signature
+     * @param dataTRC
+     *            the data trc
+     * @return - gamma or zero if TRC is a table
+     */
+    private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
+        byte[] data = getData(tagSignature);
+        int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
+
+        dataTRC = null;
+
+        if (trcSize == 0) {
+            return 1.0f;
+        }
+
+        if (trcSize == 1) {
+            // Cast from ICC u8Fixed8Number to float
+            return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
+        }
+
+        // TRC is a table
+        dataTRC = new short[trcSize];
+        for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
+            dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the gamma.
+     * 
+     * @param tagSignature
+     *            the tag signature
+     * @return the gamma
+     */
+    float getGamma(int tagSignature) {
+        short[] dataTRC = null;
+        float gamma = getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            return gamma;
+        }
+        // awt.166=TRC is not a simple gamma value.
+        throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the TRC.
+     * 
+     * @param tagSignature
+     *            the tag signature
+     * @return the tRC
+     */
+    short[] getTRC(int tagSignature) {
+        short[] dataTRC = null;
+        getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            // awt.167=TRC is a gamma value, not a table.
+            throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
+        }
+        return dataTRC;
+    }
+}
diff --git a/awt/java/awt/color/ICC_ProfileGray.java b/awt/java/awt/color/ICC_ProfileGray.java
new file mode 100644
index 0000000..f748101
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileGray.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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ICC_ProfileGray class represent profiles with TYPE_GRAY color space type,
+ * and includes the grayTRCTag and mediaWhitePointTag tags. The gray component
+ * can be transformed from a GRAY device profile color space to the CIEXYZ
+ * Profile through the tone reproduction curve (TRC):
+ * <p>
+ * PCSY = grayTRC[deviceGray]
+ * 
+ * @since Android 1.0
+ */
+public class ICC_ProfileGray extends ICC_Profile {
+    
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -1124721290732002649L;
+
+    /**
+     * Instantiates a new iC c_ profile gray.
+     * 
+     * @param profileHandle
+     *            the profile handle
+     */
+    ICC_ProfileGray(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /**
+     * Gets the TRC as an array of shorts.
+     * 
+     * @return the short array of the TRC.
+     */
+    public short[] getTRC() {
+        return super.getTRC(icSigGrayTRCTag);
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point
+     */
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+    /**
+     * Gets a gamma value representing the tone reproduction curve (TRC).
+     * 
+     * @return the gamma value representing the tone reproduction curve (TRC).
+     */
+    public float getGamma() {
+        return super.getGamma(icSigGrayTRCTag);
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileRGB.java b/awt/java/awt/color/ICC_ProfileRGB.java
new file mode 100644
index 0000000..9c6010f
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileRGB.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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_ProfileRGB class represents profiles with RGB color space type and
+ * contains the redColorantTag, greenColorantTag, blueColorantTag, redTRCTag,
+ * greenTRCTag, blueTRCTag, and mediaWhitePointTag tags.
+ * 
+ * @since Android 1.0
+ */
+public class ICC_ProfileRGB extends ICC_Profile {
+    
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 8505067385152579334L;
+
+    /**
+     * Instantiates a new RGB ICC_Profile.
+     * 
+     * @param profileHandle
+     *            the profile handle
+     */
+    ICC_ProfileRGB(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /**
+     * The Constant REDCOMPONENT indicates the red component.
+     */
+    public static final int REDCOMPONENT = 0;
+
+    /**
+     * The Constant GREENCOMPONENT indicates the green component.
+     */
+    public static final int GREENCOMPONENT = 1;
+
+    /**
+     * The Constant BLUECOMPONENT indicates the blue component.
+     */
+    public static final int BLUECOMPONENT = 2;
+
+    // awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+    /**
+     * The Constant UNKNOWN_COMPONENT_MSG.
+     */
+    private static final String UNKNOWN_COMPONENT_MSG = Messages
+            .getString("awt.15E"); //$NON-NLS-1$
+
+    /**
+     * Gets the TRC.
+     * 
+     * @param component
+     *            the tag signature.
+     * @return the TRC value.
+     */
+    @Override
+    public short[] getTRC(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getTRC(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getTRC(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getTRC(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    /**
+     * Gets the gamma.
+     * 
+     * @param component
+     *            the tag signature.
+     * @return the gamma value.
+     */
+    @Override
+    public float getGamma(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getGamma(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getGamma(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getGamma(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    /**
+     * Gets a float matrix which contains the X, Y, and Z components of the
+     * profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     * 
+     * @return the float matrix which contains the X, Y, and Z components of the
+     *         profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     */
+    public float[][] getMatrix() {
+        float [][] m = new float[3][3]; // The matrix
+
+        float[] redXYZ = getXYZValue(icSigRedColorantTag);
+        float[] greenXYZ = getXYZValue(icSigGreenColorantTag);
+        float[] blueXYZ = getXYZValue(icSigBlueColorantTag);
+
+        m[0][0] = redXYZ[0];
+        m[1][0] = redXYZ[1];
+        m[2][0] = redXYZ[2];
+
+        m[0][1] = greenXYZ[0];
+        m[1][1] = greenXYZ[1];
+        m[2][1] = greenXYZ[2];
+
+        m[0][2] = blueXYZ[0];
+        m[1][2] = blueXYZ[1];
+        m[2][2] = blueXYZ[2];
+
+        return m;
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point.
+     */
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileStub.java b/awt/java/awt/color/ICC_ProfileStub.java
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..335f314
--- /dev/null
+++ b/awt/java/awt/color/ProfileDataException.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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ProfileDataException class represents an error which occurs while
+ * accessing or processing an ICC_Profile object.
+ * 
+ * @since Android 1.0
+ */
+public class ProfileDataException extends RuntimeException {
+    
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 7286140888240322498L;
+
+    /**
+     * Instantiates a new profile data exception with detailed message.
+     * 
+     * @param s
+     *            the detailed message of the exception.
+     */
+    public ProfileDataException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/color/package.html b/awt/java/awt/color/package.html
new file mode 100644
index 0000000..609d963
--- /dev/null
+++ b/awt/java/awt/color/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes representing color spaces and profiles based on the International Color Consortium (ICC) Profile Format Specification. 
+    </p>
+    @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
new file mode 100644
index 0000000..76293b3
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListener.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.event;
+
+import java.awt.AWTEvent;
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface AWTEventListener extends EventListener {
+
+    public void eventDispatched(AWTEvent event);
+
+}
diff --git a/awt/java/awt/event/AWTEventListenerProxy.java b/awt/java/awt/event/AWTEventListenerProxy.java
new file mode 100644
index 0000000..3edc41f3
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListenerProxy.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;
+
+import java.awt.AWTEvent;
+
+import java.util.EventListenerProxy;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class AWTEventListenerProxy extends EventListenerProxy implements AWTEventListener {
+
+    private AWTEventListener listener;
+    private long eventMask;
+
+    public AWTEventListenerProxy(long eventMask, AWTEventListener listener) {
+        super(listener);
+
+        // awt.193=Listener can't be zero
+        assert listener != null : Messages.getString("awt.193"); //$NON-NLS-1$
+
+        this.listener = listener;
+        this.eventMask = eventMask;
+    }
+
+    public void eventDispatched(AWTEvent evt) {
+        listener.eventDispatched(evt);
+    }
+
+    public long getEventMask() {
+        return eventMask;
+    }
+
+}
diff --git a/awt/java/awt/event/ActionEvent.java b/awt/java/awt/event/ActionEvent.java
new file mode 100644
index 0000000..e882e0d
--- /dev/null
+++ b/awt/java/awt/event/ActionEvent.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.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class ActionEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -7671078796273832149L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ACTION_FIRST = 1001;
+
+    public static final int ACTION_LAST = 1001;
+
+    public static final int ACTION_PERFORMED = 1001;
+
+    private long when;
+    private int modifiers;
+    private String command;
+
+    public ActionEvent(Object source, int id, String command) {
+        this(source, id, command, 0);
+    }
+
+    public ActionEvent(Object source, int id, String command, int modifiers) {
+        this(source, id, command, 0l, modifiers);
+    }
+
+    public ActionEvent(Object source, int id, String command, long when, int modifiers) {
+        super(source, id);
+
+        this.command = command;
+        this.when = when;
+        this.modifiers = modifiers;
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getActionCommand() {
+        return command;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ActionEvent e = new ActionEvent(new Component(){},
+         *       ActionEvent.ACTION_PERFORMED, "Command",
+         *       ActionEvent.SHIFT_MASK|ActionEvent.CTRL_MASK|
+         *       ActionEvent.META_MASK|ActionEvent.ALT_MASK);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ACTION_PERFORMED) ? 
+                          "ACTION_PERFORMED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+        String modifiersString = ""; //$NON-NLS-1$
+
+        if ((modifiers & SHIFT_MASK) > 0) {
+            modifiersString += "Shift"; //$NON-NLS-1$
+        }
+        if ((modifiers & CTRL_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Ctrl" : "+Ctrl"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & META_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Meta" : "+Meta"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & ALT_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Alt" : "+Alt"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return (idString + ",cmd=" + command + ",when=" + when +  //$NON-NLS-1$ //$NON-NLS-2$
+                ",modifiers=" + modifiersString); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ActionListener.java b/awt/java/awt/event/ActionListener.java
new file mode 100644
index 0000000..a6eee7a
--- /dev/null
+++ b/awt/java/awt/event/ActionListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface ActionListener extends EventListener {
+
+    public void actionPerformed(ActionEvent e);
+
+}
diff --git a/awt/java/awt/event/AdjustmentEvent.java b/awt/java/awt/event/AdjustmentEvent.java
new file mode 100644
index 0000000..be2d6c4
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Adjustable;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class AdjustmentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 5700290645205279921L;
+
+    public static final int ADJUSTMENT_FIRST = 601;
+
+    public static final int ADJUSTMENT_LAST = 601;
+
+    public static final int ADJUSTMENT_VALUE_CHANGED = 601;
+
+    public static final int UNIT_INCREMENT = 1;
+
+    public static final int UNIT_DECREMENT = 2;
+
+    public static final int BLOCK_DECREMENT = 3;
+
+    public static final int BLOCK_INCREMENT = 4;
+
+    public static final int TRACK = 5;
+
+    private int type;
+    private int value;
+    private boolean isAdjusting;
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value) {
+        this(source, id, type, value, false);
+    }
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value, 
+                           boolean isAdjusting) {
+        super(source, id);
+        this.type = type;
+        this.value = value;
+        this.isAdjusting = isAdjusting;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public int getAdjustmentType() {
+        return type;
+    }
+
+    public boolean getValueIsAdjusting() {
+        return isAdjusting;
+    }
+
+    public Adjustable getAdjustable() {
+        return (Adjustable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AdjustmentEvent e = new AdjustmentEvent(new Scrollbar(), 
+         *       AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 
+         *       AdjustmentEvent.UNIT_INCREMENT, 1);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ADJUSTMENT_VALUE_CHANGED ?
+                "ADJUSTMENT_VALUE_CHANGED" : "unknown type"); //$NON-NLS-1$ //$NON-NLS-2$
+        String adjType = null;
+
+        switch (type) {
+        case UNIT_INCREMENT:
+            adjType = "UNIT_INCREMENT"; //$NON-NLS-1$
+            break;
+        case UNIT_DECREMENT:
+            adjType = "UNIT_DECREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_INCREMENT:
+            adjType = "BLOCK_INCREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_DECREMENT:
+            adjType = "BLOCK_DECREMENT"; //$NON-NLS-1$
+            break;
+        case TRACK:
+            adjType = "TRACK"; //$NON-NLS-1$
+            break;
+        default:
+            adjType = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",adjType=" + adjType + ",value=" + value + //$NON-NLS-1$ //$NON-NLS-2$
+                ",isAdjusting=" + isAdjusting); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/AdjustmentListener.java b/awt/java/awt/event/AdjustmentListener.java
new file mode 100644
index 0000000..5f6a724
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface AdjustmentListener extends EventListener {
+
+    public void adjustmentValueChanged(AdjustmentEvent e);
+
+}
diff --git a/awt/java/awt/event/ComponentAdapter.java b/awt/java/awt/event/ComponentAdapter.java
new file mode 100644
index 0000000..c42235f
--- /dev/null
+++ b/awt/java/awt/event/ComponentAdapter.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class ComponentAdapter implements ComponentListener {
+
+    public ComponentAdapter() {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+
+    public void componentMoved(ComponentEvent e) {
+    }
+
+    public void componentResized(ComponentEvent e) {
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentEvent.java b/awt/java/awt/event/ComponentEvent.java
new file mode 100644
index 0000000..760d3ab
--- /dev/null
+++ b/awt/java/awt/event/ComponentEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class ComponentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 8101406823902992965L;
+
+    public static final int COMPONENT_FIRST = 100;
+
+    public static final int COMPONENT_LAST = 103;
+
+    public static final int COMPONENT_MOVED = 100;
+
+    public static final int COMPONENT_RESIZED = 101;
+
+    public static final int COMPONENT_SHOWN = 102;
+
+    public static final int COMPONENT_HIDDEN = 103;
+
+    public ComponentEvent(Component source, int id) {
+        super(source, id);
+    }
+
+    public Component getComponent() {
+        return (Component) source;
+    }
+    
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ComponentEvent e = new ComponentEvent(new Button("Button"), 
+         *          ComponentEvent.COMPONENT_SHOWN);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        Component c = getComponent();
+
+        switch (id) {
+        case COMPONENT_MOVED:
+            idString = "COMPONENT_MOVED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_RESIZED:
+            idString = "COMPONENT_RESIZED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_SHOWN:
+            return "COMPONENT_SHOWN"; //$NON-NLS-1$
+        case COMPONENT_HIDDEN:
+            return "COMPONENT_HIDDEN"; //$NON-NLS-1$
+        default:
+            return "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + " (" + c.getX() + "," + c.getY() +  //$NON-NLS-1$ //$NON-NLS-2$
+                " " + c.getWidth()+ "x" + c.getHeight() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentListener.java b/awt/java/awt/event/ComponentListener.java
new file mode 100644
index 0000000..a5adba2
--- /dev/null
+++ b/awt/java/awt/event/ComponentListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface ComponentListener extends EventListener {
+
+    public void componentHidden(ComponentEvent e);
+
+    public void componentMoved(ComponentEvent e);
+
+    public void componentResized(ComponentEvent e);
+
+    public void componentShown(ComponentEvent e);
+
+}
diff --git a/awt/java/awt/event/ContainerAdapter.java b/awt/java/awt/event/ContainerAdapter.java
new file mode 100644
index 0000000..44983c7
--- /dev/null
+++ b/awt/java/awt/event/ContainerAdapter.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class ContainerAdapter implements ContainerListener {
+
+    public ContainerAdapter() {
+    }
+
+    public void componentAdded(ContainerEvent e) {
+    }
+
+    public void componentRemoved(ContainerEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerEvent.java b/awt/java/awt/event/ContainerEvent.java
new file mode 100644
index 0000000..372c9e4
--- /dev/null
+++ b/awt/java/awt/event/ContainerEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class ContainerEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -4114942250539772041L;
+
+    public static final int CONTAINER_FIRST = 300;
+
+    public static final int CONTAINER_LAST = 301;
+
+    public static final int COMPONENT_ADDED = 300;
+
+    public static final int COMPONENT_REMOVED = 301;
+
+    private Component child;
+
+    public ContainerEvent(Component src, int id, Component child) {
+        super(src, id);
+        this.child = child;
+    }
+
+    public Component getChild() {
+        return child;
+    }
+
+    //???AWT
+    /*
+    public Container getContainer() {
+        return (Container) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ContainerEvent e = new ContainerEvent(new Panel(),
+         *          ContainerEvent.COMPONENT_ADDED,
+         *          new Button("Button"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case COMPONENT_ADDED:
+            idString = "COMPONENT_ADDED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_REMOVED:
+            idString = "COMPONENT_REMOVED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",child=" + child.getName()); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerListener.java b/awt/java/awt/event/ContainerListener.java
new file mode 100644
index 0000000..517859e
--- /dev/null
+++ b/awt/java/awt/event/ContainerListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface ContainerListener extends EventListener {
+
+    public void componentAdded(ContainerEvent e);
+
+    public void componentRemoved(ContainerEvent e);
+
+}
diff --git a/awt/java/awt/event/FocusAdapter.java b/awt/java/awt/event/FocusAdapter.java
new file mode 100644
index 0000000..3a3e37f
--- /dev/null
+++ b/awt/java/awt/event/FocusAdapter.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class FocusAdapter implements FocusListener {
+
+    public FocusAdapter() {
+    }
+
+    public void focusGained(FocusEvent e) {
+    }
+
+    public void focusLost(FocusEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/FocusEvent.java b/awt/java/awt/event/FocusEvent.java
new file mode 100644
index 0000000..4a18689
--- /dev/null
+++ b/awt/java/awt/event/FocusEvent.java
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class FocusEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 523753786457416396L;
+
+    public static final int FOCUS_FIRST = 1004;
+
+    public static final int FOCUS_LAST = 1005;
+
+    public static final int FOCUS_GAINED = 1004;
+
+    public static final int FOCUS_LOST = 1005;
+
+    private boolean temporary;
+    private Component opposite;
+
+    public FocusEvent(Component source, int id) {
+        this(source, id, false);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary) {
+        this(source, id, temporary, null);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary, Component opposite) {
+        super(source, id);
+        this.temporary = temporary;
+        this.opposite = opposite;
+    }
+
+    public Component getOppositeComponent() {
+        return opposite;
+    }
+
+    public boolean isTemporary() {
+        return temporary;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * FocusEvent e = new FocusEvent(new Button("Button0"),
+         *       FocusEvent.FOCUS_GAINED, false, new Button("Button1"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case FOCUS_GAINED:
+            idString = "FOCUS_GAINED"; //$NON-NLS-1$
+            break;
+        case FOCUS_LOST:
+            idString = "FOCUS_LOST"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString +
+                (temporary ? ",temporary" : ",permanent") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",opposite=" + opposite); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/FocusListener.java b/awt/java/awt/event/FocusListener.java
new file mode 100644
index 0000000..6bbbd00
--- /dev/null
+++ b/awt/java/awt/event/FocusListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface FocusListener extends EventListener {
+
+    public void focusGained(FocusEvent e);
+
+    public void focusLost(FocusEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsAdapter.java b/awt/java/awt/event/HierarchyBoundsAdapter.java
new file mode 100644
index 0000000..bbfe8ff
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsAdapter.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener {
+
+    public HierarchyBoundsAdapter() {
+    }
+
+    public void ancestorMoved(HierarchyEvent e) {
+    }
+
+    public void ancestorResized(HierarchyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsListener.java b/awt/java/awt/event/HierarchyBoundsListener.java
new file mode 100644
index 0000000..3e8f2e7
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface HierarchyBoundsListener extends EventListener {
+
+    public void ancestorMoved(HierarchyEvent e);
+
+    public void ancestorResized(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyEvent.java b/awt/java/awt/event/HierarchyEvent.java
new file mode 100644
index 0000000..c1d22f4
--- /dev/null
+++ b/awt/java/awt/event/HierarchyEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class HierarchyEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -5337576970038043990L;
+
+    public static final int HIERARCHY_FIRST = 1400;
+
+    public static final int HIERARCHY_CHANGED = 1400;
+
+    public static final int ANCESTOR_MOVED = 1401;
+
+    public static final int ANCESTOR_RESIZED = 1402;
+
+    public static final int HIERARCHY_LAST = 1402;
+
+    public static final int PARENT_CHANGED = 1;
+
+    public static final int DISPLAYABILITY_CHANGED = 2;
+
+    public static final int SHOWING_CHANGED = 4;
+
+    //???AWT: private Container changedParent;
+    private Component changed;
+    private long changeFlag;
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed, 
+                          Container changedParent) {
+        this(source, id, changed, changedParent, 0l);
+    }
+    */
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed,
+            Container changedParent, long changeFlags) {
+        super(source, id);
+
+        this.changed = changed;
+        this.changedParent = changedParent;
+        this.changeFlag = changeFlags;
+    }
+    */
+    //???AWT: Fake constructor, should be as above.
+    public HierarchyEvent(Component source, int id, Component changed,
+            Object changedParent, long changeFlags) {
+        super(source, id);
+
+//        this.changed = changed;
+//        this.changedParent = changedParent;
+//        this.changeFlag = changeFlags;
+    }
+    
+    public Component getComponent() {
+        return (Component) source;
+    }
+
+    public long getChangeFlags() {
+        return changeFlag;
+    }
+
+    public Component getChanged() {
+        return changed;
+    }
+
+    //???AWT
+    /*
+    public Container getChangedParent() {
+        return changedParent;
+
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * HierarchyEvent e = new HierarchyEvent(new Button("Button"),
+         *          HierarchyEvent.HIERARCHY_CHANGED,
+         *          new Panel(), new Container());
+         * System.out.println(e);
+         */
+        String paramString = null;
+
+        switch (id) {
+        case HIERARCHY_CHANGED:
+            paramString = "HIERARCHY_CHANGED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_MOVED:
+            paramString = "ANCESTOR_MOVED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_RESIZED:
+            paramString = "ANCESTOR_RESIZED"; //$NON-NLS-1$
+            break;
+        default:
+            paramString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += " ("; //$NON-NLS-1$
+
+        if (id == HIERARCHY_CHANGED) {
+            if ((changeFlag & PARENT_CHANGED) > 0) {
+                paramString += "PARENT_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & DISPLAYABILITY_CHANGED) > 0) {
+                paramString += "DISPLAYABILITY_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & SHOWING_CHANGED) > 0) {
+                paramString += "SHOWING_CHANGED,"; //$NON-NLS-1$
+            }
+        }
+
+        //???AWT
+        /*
+        return paramString + "changed=" + changed +  //$NON-NLS-1$
+                ",changedParent=" + changedParent + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyListener.java b/awt/java/awt/event/HierarchyListener.java
new file mode 100644
index 0000000..ff3d9bc
--- /dev/null
+++ b/awt/java/awt/event/HierarchyListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface HierarchyListener extends EventListener {
+
+    public void hierarchyChanged(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/InputEvent.java b/awt/java/awt/event/InputEvent.java
new file mode 100644
index 0000000..343b7a3
--- /dev/null
+++ b/awt/java/awt/event/InputEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class InputEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -2482525981698309786L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ALT_GRAPH_MASK = 32;
+
+    public static final int BUTTON1_MASK = 16;
+
+    public static final int BUTTON2_MASK = 8;
+
+    public static final int BUTTON3_MASK = 4;
+
+    public static final int SHIFT_DOWN_MASK = 64;
+
+    public static final int CTRL_DOWN_MASK = 128;
+
+    public static final int META_DOWN_MASK = 256;
+
+    public static final int ALT_DOWN_MASK = 512;
+
+    public static final int BUTTON1_DOWN_MASK = 1024;
+
+    public static final int BUTTON2_DOWN_MASK = 2048;
+
+    public static final int BUTTON3_DOWN_MASK = 4096;
+
+    public static final int ALT_GRAPH_DOWN_MASK = 8192;
+
+    private static final int DOWN_MASKS = SHIFT_DOWN_MASK | CTRL_DOWN_MASK |
+            META_DOWN_MASK | ALT_DOWN_MASK | BUTTON1_DOWN_MASK |
+            BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | ALT_GRAPH_DOWN_MASK;
+
+    private long when;
+    private int modifiersEx;
+
+    public static String getModifiersExText(int modifiers/*Ex*/) {
+        return MouseEvent.addMouseModifiersExText(
+                KeyEvent.getKeyModifiersExText(modifiers), modifiers);
+    }
+
+    static int extractExFlags(int modifiers) {
+        int exFlags = modifiers & DOWN_MASKS;
+
+        if ((modifiers & SHIFT_MASK) != 0) {
+            exFlags |= SHIFT_DOWN_MASK;
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            exFlags |= CTRL_DOWN_MASK;
+        }
+        if ((modifiers & META_MASK) != 0) {
+            exFlags |= META_DOWN_MASK;
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            exFlags |= ALT_DOWN_MASK;
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            exFlags |= ALT_GRAPH_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            exFlags |= BUTTON1_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            exFlags |= BUTTON2_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            exFlags |= BUTTON3_DOWN_MASK;
+        }
+
+        return exFlags;
+    }
+
+    InputEvent(Component source, int id, long when, int modifiers) {
+        super(source, id);
+
+        this.when = when;
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public int getModifiers() {
+        int modifiers = 0;
+
+        if ((modifiersEx & SHIFT_DOWN_MASK) != 0) {
+            modifiers |= SHIFT_MASK;
+        }
+        if ((modifiersEx & CTRL_DOWN_MASK) != 0) {
+            modifiers |= CTRL_MASK;
+        }
+        if ((modifiersEx & META_DOWN_MASK) != 0) {
+            modifiers |= META_MASK;
+        }
+        if ((modifiersEx & ALT_DOWN_MASK) != 0) {
+            modifiers |= ALT_MASK;
+        }
+        if ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0) {
+            modifiers |= ALT_GRAPH_MASK;
+        }
+        if ((modifiersEx & BUTTON1_DOWN_MASK) != 0) {
+            modifiers |= BUTTON1_MASK;
+        }
+        if ((modifiersEx & BUTTON2_DOWN_MASK) != 0) {
+            modifiers |= BUTTON2_MASK;
+        }
+        if ((modifiersEx & BUTTON3_DOWN_MASK) != 0) {
+            modifiers |= BUTTON3_MASK;
+        }
+
+        return modifiers;
+    }
+
+    public int getModifiersEx() {
+        return modifiersEx;
+    }
+
+    void setModifiers(int modifiers) {
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public boolean isAltDown() {
+        return ((modifiersEx & ALT_DOWN_MASK) != 0);
+    }
+
+    public boolean isAltGraphDown() {
+        return ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
+    }
+
+    public boolean isControlDown() {
+        return ((modifiersEx & CTRL_DOWN_MASK) != 0);
+    }
+
+    public boolean isMetaDown() {
+        return ((modifiersEx & META_DOWN_MASK) != 0);
+    }
+
+    public boolean isShiftDown() {
+        return ((modifiersEx & SHIFT_DOWN_MASK) != 0);
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodEvent.java b/awt/java/awt/event/InputMethodEvent.java
new file mode 100644
index 0000000..be001a5
--- /dev/null
+++ b/awt/java/awt/event/InputMethodEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class InputMethodEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 4727190874778922661L;
+
+    public static final int INPUT_METHOD_FIRST = 1100;
+
+    public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
+
+    public static final int CARET_POSITION_CHANGED = 1101;
+
+    public static final int INPUT_METHOD_LAST = 1101;
+
+    private AttributedCharacterIterator text;
+    private TextHitInfo visiblePosition;
+    private TextHitInfo caret;
+    private int committedCharacterCount;
+    private long when;
+
+    public InputMethodEvent(Component src, int id,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, null, 0, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, 
+                            AttributedCharacterIterator text,
+                            int commitedCharCount,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, 0l, text, commitedCharCount, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, long when,
+                            AttributedCharacterIterator text, 
+                            int committedCharacterCount,
+                            TextHitInfo caret,
+                            TextHitInfo visiblePos) {
+        super(src, id);
+
+        if ((id < INPUT_METHOD_FIRST) || (id > INPUT_METHOD_LAST)) {
+            // awt.18E=Wrong event id
+            throw new IllegalArgumentException(Messages.getString("awt.18E")); //$NON-NLS-1$
+        }
+        if ((id == CARET_POSITION_CHANGED) && (text != null)) {
+            // awt.18F=Text must be null for CARET_POSITION_CHANGED
+            throw new IllegalArgumentException(Messages.getString("awt.18F")); //$NON-NLS-1$
+        }
+        if ((text != null) &&
+                ((committedCharacterCount < 0) ||
+                 (committedCharacterCount > 
+                        (text.getEndIndex() - text.getBeginIndex())))) {
+            // awt.190=Wrong committedCharacterCount
+            throw new IllegalArgumentException(Messages.getString("awt.190")); //$NON-NLS-1$
+        }
+
+        this.when = when;
+        this.text = text;
+        this.caret = caret;
+        this.visiblePosition = visiblePos;
+        this.committedCharacterCount = committedCharacterCount;
+    }
+
+    public TextHitInfo getCaret() {
+        return caret;
+    }
+
+    public int getCommittedCharacterCount() {
+        return committedCharacterCount;
+    }
+
+    public AttributedCharacterIterator getText() {
+        return text;
+    }
+
+    public TextHitInfo getVisiblePosition() {
+        return visiblePosition;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InputMethodEvent e = new InputMethodEvent(new Component(){},
+         *          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+         *          TextHitInfo.leading(1), TextHitInfo.trailing(2));
+         * System.out.println(e);
+         */
+        String typeString = null;
+
+        switch (id) {
+        case INPUT_METHOD_TEXT_CHANGED:
+            typeString = "INPUT_METHOD_TEXT_CHANGED"; //$NON-NLS-1$
+            break;
+        case CARET_POSITION_CHANGED:
+            typeString = "CARET_POSITION_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",text=" + text +  //$NON-NLS-1$
+                ",commitedCharCount=" + committedCharacterCount + //$NON-NLS-1$
+                ",caret=" + caret + ",visiblePosition=" + visiblePosition; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodListener.java b/awt/java/awt/event/InputMethodListener.java
new file mode 100644
index 0000000..85eaa7e
--- /dev/null
+++ b/awt/java/awt/event/InputMethodListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface InputMethodListener extends EventListener {
+
+    public void caretPositionChanged(InputMethodEvent e);
+
+    public void inputMethodTextChanged(InputMethodEvent e);
+
+}
diff --git a/awt/java/awt/event/InvocationEvent.java b/awt/java/awt/event/InvocationEvent.java
new file mode 100644
index 0000000..58e3b72
--- /dev/null
+++ b/awt/java/awt/event/InvocationEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class InvocationEvent extends AWTEvent implements ActiveEvent {
+
+    private static final long serialVersionUID = 436056344909459450L;
+
+    public static final int INVOCATION_FIRST = 1200;
+
+    public static final int INVOCATION_DEFAULT = 1200;
+
+    public static final int INVOCATION_LAST = 1200;
+
+    protected Runnable runnable;
+
+    protected Object notifier;
+
+    protected boolean catchExceptions;
+
+    private long when;
+    private Throwable throwable;
+
+    public InvocationEvent(Object source, Runnable runnable) {
+        this(source, runnable, null, false);
+    }
+
+    public InvocationEvent(Object source, Runnable runnable, 
+                           Object notifier, boolean catchExceptions) {
+        this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
+    }
+
+    protected InvocationEvent(Object source, int id, Runnable runnable,
+            Object notifier, boolean catchExceptions)
+    {
+        super(source, id);
+
+        // awt.18C=Cannot invoke null runnable
+        assert runnable != null : Messages.getString("awt.18C"); //$NON-NLS-1$
+
+        if (source == null) {
+            // awt.18D=Source is null
+            throw new IllegalArgumentException(Messages.getString("awt.18D")); //$NON-NLS-1$
+        }
+        this.runnable = runnable;
+        this.notifier = notifier;
+        this.catchExceptions = catchExceptions;
+
+        throwable = null;
+        when = System.currentTimeMillis();
+    }
+
+    public void dispatch() {
+        if (!catchExceptions) {
+            runAndNotify();
+        } else {
+            try {
+                runAndNotify();
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    private void runAndNotify() {
+        if (notifier != null) {
+            synchronized(notifier) {
+                try {
+                    runnable.run();
+                } finally {
+                    notifier.notifyAll();
+                }
+            }
+        } else {
+            runnable.run();
+        }
+    }
+
+    public Exception getException() {
+        return (throwable != null && throwable instanceof Exception) ?
+                (Exception)throwable : null;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InvocationEvent e = new InvocationEvent(new Component(){},
+         *       new Runnable() { public void run(){} });
+         * System.out.println(e);
+         */
+
+        return ((id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",runnable=" + runnable + //$NON-NLS-1$
+                ",notifier=" + notifier + //$NON-NLS-1$
+                ",catchExceptions=" + catchExceptions + //$NON-NLS-1$
+                ",when=" + when); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemEvent.java b/awt/java/awt/event/ItemEvent.java
new file mode 100644
index 0000000..09908f2
--- /dev/null
+++ b/awt/java/awt/event/ItemEvent.java
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ItemSelectable;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class ItemEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -608708132447206933L;
+
+    public static final int ITEM_FIRST = 701;
+
+    public static final int ITEM_LAST = 701;
+
+    public static final int ITEM_STATE_CHANGED = 701;
+
+    public static final int SELECTED = 1;
+
+    public static final int DESELECTED = 2;
+
+    private Object item;
+    private int stateChange;
+
+    public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) {
+        super(source, id);
+
+        this.item = item;
+        this.stateChange = stateChange;
+    }
+
+    public Object getItem() {
+        return item;
+    }
+
+    public int getStateChange() {
+        return stateChange;
+    }
+
+    public ItemSelectable getItemSelectable() {
+        return (ItemSelectable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Checkbox c = new Checkbox("Checkbox", true);
+         * ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, 
+         *                             c, ItemEvent.SELECTED);
+         * System.out.println(e);
+         */
+
+        String stateString = null;
+
+        switch (stateChange) {
+        case SELECTED:
+            stateString = "SELECTED"; //$NON-NLS-1$
+            break;
+        case DESELECTED:
+            stateString = "DESELECTED"; //$NON-NLS-1$
+            break;
+        default:
+            stateString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return ((id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",item=" + item + ",stateChange=" + stateString); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemListener.java b/awt/java/awt/event/ItemListener.java
new file mode 100644
index 0000000..8dec673
--- /dev/null
+++ b/awt/java/awt/event/ItemListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface ItemListener extends EventListener {
+
+    public void itemStateChanged(ItemEvent e);
+
+}
diff --git a/awt/java/awt/event/KeyAdapter.java b/awt/java/awt/event/KeyAdapter.java
new file mode 100644
index 0000000..a96cca8
--- /dev/null
+++ b/awt/java/awt/event/KeyAdapter.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class KeyAdapter implements KeyListener {
+
+    public KeyAdapter() {
+    }
+
+    public void keyPressed(KeyEvent e) {
+    }
+
+    public void keyReleased(KeyEvent e) {
+    }
+
+    public void keyTyped(KeyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/KeyEvent.java b/awt/java/awt/event/KeyEvent.java
new file mode 100644
index 0000000..8627f70
--- /dev/null
+++ b/awt/java/awt/event/KeyEvent.java
@@ -0,0 +1,687 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class KeyEvent extends InputEvent {
+
+    private static final long serialVersionUID = -2352130953028126954L;
+
+    public static final int KEY_FIRST = 400;
+
+    public static final int KEY_LAST = 402;
+
+    public static final int KEY_TYPED = 400;
+
+    public static final int KEY_PRESSED = 401;
+
+    public static final int KEY_RELEASED = 402;
+
+    public static final int VK_ENTER = 10;
+
+    public static final int VK_BACK_SPACE = 8;
+
+    public static final int VK_TAB = 9;
+
+    public static final int VK_CANCEL = 3;
+
+    public static final int VK_CLEAR = 12;
+
+    public static final int VK_SHIFT = 16;
+
+    public static final int VK_CONTROL = 17;
+
+    public static final int VK_ALT = 18;
+
+    public static final int VK_PAUSE = 19;
+
+    public static final int VK_CAPS_LOCK = 20;
+
+    public static final int VK_ESCAPE = 27;
+
+    public static final int VK_SPACE = 32;
+
+    public static final int VK_PAGE_UP = 33;
+
+    public static final int VK_PAGE_DOWN = 34;
+
+    public static final int VK_END = 35;
+
+    public static final int VK_HOME = 36;
+
+    public static final int VK_LEFT = 37;
+
+    public static final int VK_UP = 38;
+
+    public static final int VK_RIGHT = 39;
+
+    public static final int VK_DOWN = 40;
+
+    public static final int VK_COMMA = 44;
+
+    public static final int VK_MINUS = 45;
+
+    public static final int VK_PERIOD = 46;
+
+    public static final int VK_SLASH = 47;
+
+    public static final int VK_0 = 48;
+
+    public static final int VK_1 = 49;
+
+    public static final int VK_2 = 50;
+
+    public static final int VK_3 = 51;
+
+    public static final int VK_4 = 52;
+
+    public static final int VK_5 = 53;
+
+    public static final int VK_6 = 54;
+
+    public static final int VK_7 = 55;
+
+    public static final int VK_8 = 56;
+
+    public static final int VK_9 = 57;
+
+    public static final int VK_SEMICOLON = 59;
+
+    public static final int VK_EQUALS = 61;
+
+    public static final int VK_A = 65;
+
+    public static final int VK_B = 66;
+
+    public static final int VK_C = 67;
+
+    public static final int VK_D = 68;
+
+    public static final int VK_E = 69;
+
+    public static final int VK_F = 70;
+
+    public static final int VK_G = 71;
+
+    public static final int VK_H = 72;
+
+    public static final int VK_I = 73;
+
+    public static final int VK_J = 74;
+
+    public static final int VK_K = 75;
+
+    public static final int VK_L = 76;
+
+    public static final int VK_M = 77;
+
+    public static final int VK_N = 78;
+
+    public static final int VK_O = 79;
+
+    public static final int VK_P = 80;
+
+    public static final int VK_Q = 81;
+
+    public static final int VK_R = 82;
+
+    public static final int VK_S = 83;
+
+    public static final int VK_T = 84;
+
+    public static final int VK_U = 85;
+
+    public static final int VK_V = 86;
+
+    public static final int VK_W = 87;
+
+    public static final int VK_X = 88;
+
+    public static final int VK_Y = 89;
+
+    public static final int VK_Z = 90;
+
+    public static final int VK_OPEN_BRACKET = 91;
+
+    public static final int VK_BACK_SLASH = 92;
+
+    public static final int VK_CLOSE_BRACKET = 93;
+
+    public static final int VK_NUMPAD0 = 96;
+
+    public static final int VK_NUMPAD1 = 97;
+
+    public static final int VK_NUMPAD2 = 98;
+
+    public static final int VK_NUMPAD3 = 99;
+
+    public static final int VK_NUMPAD4 = 100;
+
+    public static final int VK_NUMPAD5 = 101;
+
+    public static final int VK_NUMPAD6 = 102;
+
+    public static final int VK_NUMPAD7 = 103;
+
+    public static final int VK_NUMPAD8 = 104;
+
+    public static final int VK_NUMPAD9 = 105;
+
+    public static final int VK_MULTIPLY = 106;
+
+    public static final int VK_ADD = 107;
+
+    public static final int VK_SEPARATER = 108;
+
+    public static final int VK_SEPARATOR = 108;
+
+    public static final int VK_SUBTRACT = 109;
+
+    public static final int VK_DECIMAL = 110;
+
+    public static final int VK_DIVIDE = 111;
+
+    public static final int VK_DELETE = 127;
+
+    public static final int VK_NUM_LOCK = 144;
+
+    public static final int VK_SCROLL_LOCK = 145;
+
+    public static final int VK_F1 = 112;
+
+    public static final int VK_F2 = 113;
+
+    public static final int VK_F3 = 114;
+
+    public static final int VK_F4 = 115;
+
+    public static final int VK_F5 = 116;
+
+    public static final int VK_F6 = 117;
+
+    public static final int VK_F7 = 118;
+
+    public static final int VK_F8 = 119;
+
+    public static final int VK_F9 = 120;
+
+    public static final int VK_F10 = 121;
+
+    public static final int VK_F11 = 122;
+
+    public static final int VK_F12 = 123;
+
+    public static final int VK_F13 = 61440;
+
+    public static final int VK_F14 = 61441;
+
+    public static final int VK_F15 = 61442;
+
+    public static final int VK_F16 = 61443;
+
+    public static final int VK_F17 = 61444;
+
+    public static final int VK_F18 = 61445;
+
+    public static final int VK_F19 = 61446;
+
+    public static final int VK_F20 = 61447;
+
+    public static final int VK_F21 = 61448;
+
+    public static final int VK_F22 = 61449;
+
+    public static final int VK_F23 = 61450;
+
+    public static final int VK_F24 = 61451;
+
+    public static final int VK_PRINTSCREEN = 154;
+
+    public static final int VK_INSERT = 155;
+
+    public static final int VK_HELP = 156;
+
+    public static final int VK_META = 157;
+
+    public static final int VK_BACK_QUOTE = 192;
+
+    public static final int VK_QUOTE = 222;
+
+    public static final int VK_KP_UP = 224;
+
+    public static final int VK_KP_DOWN = 225;
+
+    public static final int VK_KP_LEFT = 226;
+
+    public static final int VK_KP_RIGHT = 227;
+
+    public static final int VK_DEAD_GRAVE = 128;
+
+    public static final int VK_DEAD_ACUTE = 129;
+
+    public static final int VK_DEAD_CIRCUMFLEX = 130;
+
+    public static final int VK_DEAD_TILDE = 131;
+
+    public static final int VK_DEAD_MACRON = 132;
+
+    public static final int VK_DEAD_BREVE = 133;
+
+    public static final int VK_DEAD_ABOVEDOT = 134;
+
+    public static final int VK_DEAD_DIAERESIS = 135;
+
+    public static final int VK_DEAD_ABOVERING = 136;
+
+    public static final int VK_DEAD_DOUBLEACUTE = 137;
+
+    public static final int VK_DEAD_CARON = 138;
+
+    public static final int VK_DEAD_CEDILLA = 139;
+
+    public static final int VK_DEAD_OGONEK = 140;
+
+    public static final int VK_DEAD_IOTA = 141;
+
+    public static final int VK_DEAD_VOICED_SOUND = 142;
+
+    public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
+
+    public static final int VK_AMPERSAND = 150;
+
+    public static final int VK_ASTERISK = 151;
+
+    public static final int VK_QUOTEDBL = 152;
+
+    public static final int VK_LESS = 153;
+
+    public static final int VK_GREATER = 160;
+
+    public static final int VK_BRACELEFT = 161;
+
+    public static final int VK_BRACERIGHT = 162;
+
+    public static final int VK_AT = 512;
+
+    public static final int VK_COLON = 513;
+
+    public static final int VK_CIRCUMFLEX = 514;
+
+    public static final int VK_DOLLAR = 515;
+
+    public static final int VK_EURO_SIGN = 516;
+
+    public static final int VK_EXCLAMATION_MARK = 517;
+
+    public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
+
+    public static final int VK_LEFT_PARENTHESIS = 519;
+
+    public static final int VK_NUMBER_SIGN = 520;
+
+    public static final int VK_PLUS = 521;
+
+    public static final int VK_RIGHT_PARENTHESIS = 522;
+
+    public static final int VK_UNDERSCORE = 523;
+
+    public static final int VK_FINAL = 24;
+
+    public static final int VK_WINDOWS = 524; 
+
+    public static final int VK_CONTEXT_MENU = 525;
+
+    public static final int VK_CONVERT = 28;
+
+    public static final int VK_NONCONVERT = 29;
+
+    public static final int VK_ACCEPT = 30;
+
+    public static final int VK_MODECHANGE = 31;
+
+    public static final int VK_KANA = 21;
+
+    public static final int VK_KANJI = 25;
+
+    public static final int VK_ALPHANUMERIC = 240;
+
+    public static final int VK_KATAKANA = 241;
+
+    public static final int VK_HIRAGANA = 242;
+
+    public static final int VK_FULL_WIDTH = 243;
+
+    public static final int VK_HALF_WIDTH = 244;
+
+    public static final int VK_ROMAN_CHARACTERS = 245;
+
+    public static final int VK_ALL_CANDIDATES = 256;
+
+    public static final int VK_PREVIOUS_CANDIDATE = 257;
+
+    public static final int VK_CODE_INPUT = 258;
+
+    public static final int VK_JAPANESE_KATAKANA = 259;
+
+    public static final int VK_JAPANESE_HIRAGANA = 260;
+
+    public static final int VK_JAPANESE_ROMAN = 261;
+
+    public static final int VK_KANA_LOCK = 262;
+
+    public static final int VK_INPUT_METHOD_ON_OFF = 263;
+
+    public static final int VK_CUT = 65489;
+
+    public static final int VK_COPY = 65485;
+
+    public static final int VK_PASTE = 65487;
+
+    public static final int VK_UNDO = 65483;
+
+    public static final int VK_AGAIN = 65481;
+
+    public static final int VK_FIND = 65488;
+
+    public static final int VK_PROPS = 65482;
+
+    public static final int VK_STOP = 65480;
+
+    public static final int VK_COMPOSE = 65312;
+
+    public static final int VK_ALT_GRAPH = 65406;
+
+    public static final int VK_BEGIN = 65368;
+
+    public static final int VK_UNDEFINED = 0;
+
+    public static final char CHAR_UNDEFINED = (char)(-1);
+
+    public static final int KEY_LOCATION_UNKNOWN = 0;
+
+    public static final int KEY_LOCATION_STANDARD = 1;
+
+    public static final int KEY_LOCATION_LEFT = 2;
+
+    public static final int KEY_LOCATION_RIGHT = 3;
+
+    public static final int KEY_LOCATION_NUMPAD = 4;
+
+    private int keyCode;
+    private char keyChar;
+    private int keyLocation;
+
+    public static String getKeyModifiersText(int modifiers) {
+        return getKeyModifiersExText(extractExFlags(modifiers));
+    }
+
+    static String getKeyModifiersExText(int modifiersEx) {
+        String text = ""; //$NON-NLS-1$
+
+        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
+            text += Toolkit.getProperty("AWT.meta", "Meta"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.control", "Ctrl"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.alt", "Alt"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.shift", "Shift"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.altGraph", "Alt Graph"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public static String getKeyText(int keyCode) {
+        String[] rawName = getPublicStaticFinalIntFieldName(keyCode); //$NON-NLS-1$
+
+        if ((rawName == null) || (rawName.length == 0)) {
+            return ("Unknown keyCode: " + (keyCode >= 0 ? "0x" : "-0x") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Integer.toHexString(Math.abs(keyCode)));
+        }
+
+        String propertyName = getPropertyName(rawName);
+        String defaultName = getDefaultName(rawName);
+
+        return Toolkit.getProperty(propertyName, defaultName);
+    }
+
+    private static String getDefaultName(String[] rawName) {
+        String name = ""; //$NON-NLS-1$
+
+        for (int i = 0; true; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+
+            if (i == (rawName.length - 1)) {
+                break;
+            }
+            name += " "; //$NON-NLS-1$
+        }
+
+        return name;
+    }
+
+    private static String getPropertyName(String[] rawName) {
+        String name = rawName[0].toLowerCase();
+
+        for (int i = 1; i < rawName.length; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+        }
+
+        return ("AWT." + name); //$NON-NLS-1$
+    }
+
+    private static String[] getPublicStaticFinalIntFieldName(int value) {
+        Field[] allFields = KeyEvent.class.getDeclaredFields();
+
+        try {
+            for (Field field : allFields) {
+                Class<?> ssalc = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (ssalc.isPrimitive() && ssalc.getName().equals("int") && //$NON-NLS-1$
+                        Modifier.isFinal(modifiers) && Modifier.isPublic(modifiers) &&
+                        Modifier.isStatic(modifiers))
+                {
+                    if (field.getInt(null) == value){
+                        final String name = field.getName();
+                        final int prefixLength = name.indexOf("_") + 1;
+                        return name.substring(prefixLength).split("_"); //$NON-NLS-1$
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return null;
+    }
+
+    @Deprecated
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode) {
+        this(src, id, when, modifiers, keyCode,
+                (keyCode > (2 << 7) - 1) ? CHAR_UNDEFINED : (char) keyCode);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar) {
+        this(src, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar,
+                    int keyLocation) {
+        super(src, id, when, modifiers);
+
+        if (id == KEY_TYPED) {
+            if (keyCode != VK_UNDEFINED) {
+                // awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.191")); //$NON-NLS-1$
+            }
+            if (keyChar == CHAR_UNDEFINED) {
+                // awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.192")); //$NON-NLS-1$
+            }
+        }
+        
+        if ((keyLocation < KEY_LOCATION_UNKNOWN)
+                || (keyLocation > KEY_LOCATION_NUMPAD)) {
+            // awt.297=Invalid keyLocation
+            throw new IllegalArgumentException(Messages.getString("awt.297")); //$NON-NLS-1$
+        }
+
+        this.keyChar = keyChar;
+        this.keyLocation = keyLocation;
+        this.keyCode = keyCode;
+    }
+
+    public int getKeyCode() {
+        return keyCode;
+    }
+
+    public void setKeyCode(int keyCode) {
+        this.keyCode = keyCode;
+    }
+
+    public char getKeyChar() {
+        return keyChar;
+    }
+
+    public void setKeyChar(char keyChar) {
+        this.keyChar = keyChar;
+    }
+
+    public int getKeyLocation() {
+        return keyLocation;
+    }
+
+    @Override
+    @Deprecated
+    public void setModifiers(int modifiers) {
+        super.setModifiers(modifiers);
+    }
+
+    public boolean isActionKey() {
+        return ((keyChar == CHAR_UNDEFINED) && (keyCode != VK_UNDEFINED) &&
+                !((keyCode == VK_ALT) || (keyCode == VK_ALT_GRAPH) ||
+                    (keyCode == VK_CONTROL) || (keyCode == VK_META) || (keyCode == VK_SHIFT)));
+    }
+
+    @Override
+    public String paramString() {
+        /*
+         * The format is based on 1.5 release behavior
+         * which can be revealed by the following code:
+         *
+         * KeyEvent e = new KeyEvent(new Component() {}, 
+         *       KeyEvent.KEY_PRESSED, 0, 
+         *       KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK, 
+         *       KeyEvent.VK_A, 'A', KeyEvent.KEY_LOCATION_STANDARD);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String locString = null;
+        String paramString = null;
+        String keyCharString = (keyChar == '\n') ?
+                keyCharString = getKeyText(VK_ENTER) : "'" + keyChar + "'"; //$NON-NLS-1$ //$NON-NLS-2$
+
+        switch (id) {
+        case KEY_PRESSED:
+            idString = "KEY_PRESSED"; //$NON-NLS-1$
+            break;
+        case KEY_RELEASED:
+            idString = "KEY_RELEASED"; //$NON-NLS-1$
+            break;
+        case KEY_TYPED:
+            idString = "KEY_TYPED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        switch(keyLocation){
+        case KEY_LOCATION_STANDARD:
+            locString = "KEY_LOCATION_STANDARD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_LEFT:
+            locString = "KEY_LOCATION_LEFT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_RIGHT:
+            locString = "KEY_LOCATION_RIGHT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_NUMPAD:
+            locString = "KEY_LOCATION_NUMPAD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_UNKNOWN:
+            locString = "KEY_LOCATION_UNKNOWN"; //$NON-NLS-1$
+            break;
+        default:
+            locString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",keyCode=" + keyCode; //$NON-NLS-1$
+        if (isActionKey()) {
+            paramString += "," + getKeyText(keyCode); //$NON-NLS-1$
+        } else {
+            paramString += ",keyChar=" + keyCharString; //$NON-NLS-1$
+        }
+        if (getModifiersEx() > 0) {
+            paramString += ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",keyLocation=" + locString; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/KeyListener.java b/awt/java/awt/event/KeyListener.java
new file mode 100644
index 0000000..ec144df
--- /dev/null
+++ b/awt/java/awt/event/KeyListener.java
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface KeyListener extends EventListener {
+
+    public void keyPressed(KeyEvent e);
+
+    public void keyReleased(KeyEvent e);
+
+    public void keyTyped(KeyEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseAdapter.java b/awt/java/awt/event/MouseAdapter.java
new file mode 100644
index 0000000..dc19173
--- /dev/null
+++ b/awt/java/awt/event/MouseAdapter.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class MouseAdapter implements MouseListener {
+
+    public MouseAdapter() {
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+    }
+
+    public void mouseReleased(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseEvent.java b/awt/java/awt/event/MouseEvent.java
new file mode 100644
index 0000000..2b1fa8b
--- /dev/null
+++ b/awt/java/awt/event/MouseEvent.java
@@ -0,0 +1,232 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class MouseEvent extends InputEvent {
+
+    private static final long serialVersionUID = -991214153494842848L;
+
+    public static final int MOUSE_FIRST = 500;
+
+    public static final int MOUSE_LAST = 507;
+
+    public static final int MOUSE_CLICKED = 500;
+
+    public static final int MOUSE_PRESSED = 501;
+
+    public static final int MOUSE_RELEASED = 502;
+
+    public static final int MOUSE_MOVED = 503;
+
+    public static final int MOUSE_ENTERED = 504;
+
+    public static final int MOUSE_EXITED = 505;
+
+    public static final int MOUSE_DRAGGED = 506;
+
+    public static final int MOUSE_WHEEL = 507;
+
+    public static final int NOBUTTON = 0;
+
+    public static final int BUTTON1 = 1;
+
+    public static final int BUTTON2 = 2;
+
+    public static final int BUTTON3 = 3;
+
+    private boolean popupTrigger;
+    private int clickCount;
+    private int button;
+    private int x;
+    private int y;
+
+    public static String getMouseModifiersText(int modifiers) {
+        final StringBuffer text = new StringBuffer();
+
+        if ((modifiers & META_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.meta", "Meta")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & SHIFT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.shift", "Shift")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.control", "Ctrl")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.alt", "Alt")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button1", "Button1")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button2", "Button2")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button3", "Button3")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        return text.length() == 0 ? text.toString() : text.substring(0, text
+                .length() - 1);
+    }
+
+    static String addMouseModifiersExText(String text, int modifiersEx) {
+        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button1", "Button1"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button2", "Button2"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button3", "Button3"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger) {
+        this(source, id, when, modifiers, x, y,
+             clickCount, popupTrigger, NOBUTTON);
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger, int button) {
+        super(source, id, when, modifiers);
+
+        if ((button != NOBUTTON) && (button != BUTTON1) &&
+                (button != BUTTON2) && (button != BUTTON3)) {
+            // awt.18B=Invalid button value
+            throw new IllegalArgumentException(Messages.getString("awt.18B")); //$NON-NLS-1$
+        }
+
+        this.popupTrigger = popupTrigger;
+        this.clickCount = clickCount;
+        this.button = button;
+        this.x = x;
+        this.y = y;
+    }
+
+    public int getButton() {
+        return button;
+    }
+
+    public int getClickCount() {
+        return clickCount;
+    }
+
+    public Point getPoint() {
+        return new Point(x, y);
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public boolean isPopupTrigger() {
+        return popupTrigger;
+    }
+
+    public void translatePoint(int x, int y) {
+        this.x += x;
+        this.y += y;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseEvent e = new MouseEvent(new Component(){}, 
+         *          MouseEvent.MOUSE_PRESSED, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseEvent.BUTTON1);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String paramString = null;
+
+        switch (id) {
+        case MOUSE_MOVED:
+            idString = "MOUSE_MOVED"; //$NON-NLS-1$
+            break;
+        case MOUSE_CLICKED:
+            idString = "MOUSE_CLICKED"; //$NON-NLS-1$
+            break;
+        case MOUSE_PRESSED:
+            idString = "MOUSE_PRESSED"; //$NON-NLS-1$
+            break;
+        case MOUSE_RELEASED:
+            idString = "MOUSE_RELEASED"; //$NON-NLS-1$
+            break;
+        case MOUSE_DRAGGED:
+            idString = "MOUSE_DRAGGED"; //$NON-NLS-1$
+            break;
+        case MOUSE_ENTERED:
+            idString = "MOUSE_ENTERED"; //$NON-NLS-1$
+            break;
+        case MOUSE_EXITED:
+            idString = "MOUSE_EXITED"; //$NON-NLS-1$
+            break;
+        case MOUSE_WHEEL:
+            idString = "MOUSE_WHEEL"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",(" + getX() + "," + getY() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                ",button=" + button; //$NON-NLS-1$
+        if (getModifiersEx() > 0) {
+            paramString += 
+                    ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",clickCount=" + getClickCount(); //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseListener.java b/awt/java/awt/event/MouseListener.java
new file mode 100644
index 0000000..95879b9
--- /dev/null
+++ b/awt/java/awt/event/MouseListener.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;
+
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface MouseListener extends EventListener {
+
+    public void mouseClicked(MouseEvent e);
+
+    public void mouseEntered(MouseEvent e);
+
+    public void mouseExited(MouseEvent e);
+
+    public void mousePressed(MouseEvent e);
+
+    public void mouseReleased(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseMotionAdapter.java b/awt/java/awt/event/MouseMotionAdapter.java
new file mode 100644
index 0000000..1ecd0d5
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionAdapter.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class MouseMotionAdapter implements MouseMotionListener {
+
+    public MouseMotionAdapter() {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseMotionListener.java b/awt/java/awt/event/MouseMotionListener.java
new file mode 100644
index 0000000..e1313c3
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface MouseMotionListener extends EventListener {
+
+    public void mouseDragged(MouseEvent e);
+
+    public void mouseMoved(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseWheelEvent.java b/awt/java/awt/event/MouseWheelEvent.java
new file mode 100644
index 0000000..a3ed424
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class MouseWheelEvent extends MouseEvent {
+
+    private static final long serialVersionUID = -9187413581993563929L;
+
+    public static final int WHEEL_UNIT_SCROLL = 0;
+
+    public static final int WHEEL_BLOCK_SCROLL = 1;
+
+    private int wheelRotation;
+    private int scrollAmount;
+    private int scrollType;
+
+    public MouseWheelEvent(Component source, int id, long when, int modifiers,
+            int x, int y, int clickCount, boolean popupTrigger, int scrollType,
+            int scrollAmount, int wheelRotation) {
+        super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
+
+        this.scrollType = scrollType;
+        this.scrollAmount = scrollAmount;
+        this.wheelRotation = wheelRotation;
+    }
+
+    public int getScrollAmount() {
+        return scrollAmount;
+    }
+
+    public int getScrollType() {
+        return scrollType;
+    }
+
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+
+    public int getUnitsToScroll() {
+        return (scrollAmount * wheelRotation);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseWheelEvent e = new MouseWheelEvent(new Component(){}, 
+         *          MouseWheelEvent.MOUSE_WHEEL, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseWheelEvent.WHEEL_UNIT_SCROLL,
+         *          1, 3);
+         * System.out.println(e);
+         */
+
+        String paramString = super.paramString();
+        String typeString = null;
+
+        switch (scrollType) {
+        case WHEEL_UNIT_SCROLL:
+            typeString = "WHEEL_UNIT_SCROLL"; //$NON-NLS-1$
+            break;
+        case WHEEL_BLOCK_SCROLL:
+            typeString = "WHEEL_BLOCK_SCROLL"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += ",scrollType=" + typeString + //$NON-NLS-1$
+                ",scrollAmount=" + scrollAmount +  //$NON-NLS-1$
+                ",wheelRotation=" + wheelRotation; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseWheelListener.java b/awt/java/awt/event/MouseWheelListener.java
new file mode 100644
index 0000000..2d6a982
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface MouseWheelListener extends EventListener {
+
+    public void mouseWheelMoved(MouseWheelEvent e);
+
+}
diff --git a/awt/java/awt/event/PaintEvent.java b/awt/java/awt/event/PaintEvent.java
new file mode 100644
index 0000000..22ac090
--- /dev/null
+++ b/awt/java/awt/event/PaintEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class PaintEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 1267492026433337593L;
+
+    public static final int PAINT_FIRST = 800;
+
+    public static final int PAINT_LAST = 801;
+
+    public static final int PAINT = 800;
+
+    public static final int UPDATE = 801;
+
+    private Rectangle updateRect;
+
+    public PaintEvent(Component source, int id, Rectangle updateRect) {
+        super(source, id);
+
+        this.updateRect = updateRect;
+    }
+
+    public Rectangle getUpdateRect() {
+        return updateRect;
+    }
+
+    public void setUpdateRect(Rectangle updateRect) {
+        this.updateRect = updateRect;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * PaintEvent e = new PaintEvent(new Component(){}, 
+         *          PaintEvent.PAINT, new Rectangle(0, 0, 10, 20)); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case PAINT:
+            typeString = "PAINT"; //$NON-NLS-1$
+            break;
+        case UPDATE:
+            typeString = "UPDATE"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",updateRect=" + updateRect; //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/TextEvent.java b/awt/java/awt/event/TextEvent.java
new file mode 100644
index 0000000..2a690ad
--- /dev/null
+++ b/awt/java/awt/event/TextEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class TextEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 6269902291250941179L;
+
+    public static final int TEXT_FIRST = 900;
+
+    public static final int TEXT_LAST = 900;
+
+    public static final int TEXT_VALUE_CHANGED = 900;
+
+    public TextEvent(Object src, int id) {
+        super(src, id);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * TextEvent e = new TextEvent(new Component(){}, 
+         *          TextEvent.TEXT_VALUE_CHANGED); 
+         * System.out.println(e);
+         */
+
+        return (id == TEXT_VALUE_CHANGED) ? 
+                "TEXT_VALUE_CHANGED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/TextListener.java b/awt/java/awt/event/TextListener.java
new file mode 100644
index 0000000..05757c4
--- /dev/null
+++ b/awt/java/awt/event/TextListener.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.event;
+
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface TextListener extends EventListener {
+
+    public void textValueChanged(TextEvent e);
+
+}
+
diff --git a/awt/java/awt/event/WindowAdapter.java b/awt/java/awt/event/WindowAdapter.java
new file mode 100644
index 0000000..970aa8d
--- /dev/null
+++ b/awt/java/awt/event/WindowAdapter.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener {
+
+    public WindowAdapter() {
+    }
+
+    public void windowActivated(WindowEvent e) {
+    }
+
+    public void windowClosed(WindowEvent e) {
+    }
+
+    public void windowClosing(WindowEvent e) {
+    }
+
+    public void windowDeactivated(WindowEvent e) {
+    }
+
+    public void windowDeiconified(WindowEvent e) {
+    }
+
+    public void windowGainedFocus(WindowEvent e) {
+    }
+
+    public void windowIconified(WindowEvent e) {
+    }
+
+    public void windowLostFocus(WindowEvent e) {
+    }
+
+    public void windowOpened(WindowEvent e) {
+    }
+
+    public void windowStateChanged(WindowEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/WindowEvent.java b/awt/java/awt/event/WindowEvent.java
new file mode 100644
index 0000000..474d2ac
--- /dev/null
+++ b/awt/java/awt/event/WindowEvent.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+
+//???AWT
+//import java.awt.Window;
+//import java.awt.Frame;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class WindowEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -1567959133147912127L;
+
+    public static final int WINDOW_FIRST = 200;
+
+    public static final int WINDOW_OPENED = 200;
+
+    public static final int WINDOW_CLOSING = 201;
+
+    public static final int WINDOW_CLOSED = 202;
+
+    public static final int WINDOW_ICONIFIED = 203;
+
+    public static final int WINDOW_DEICONIFIED = 204;
+
+    public static final int WINDOW_ACTIVATED = 205;
+
+    public static final int WINDOW_DEACTIVATED = 206;
+
+    public static final int WINDOW_GAINED_FOCUS = 207;
+
+    public static final int WINDOW_LOST_FOCUS = 208;
+
+    public static final int WINDOW_STATE_CHANGED = 209;
+
+    public static final int WINDOW_LAST = 209;
+
+    //???AWT: private Window oppositeWindow;
+    private int oldState;
+    private int newState;
+
+    //???AWT
+    /*
+    public WindowEvent(Window source, int id) {
+        this(source, id, null);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite) {
+        this(source, id, opposite, Frame.NORMAL, Frame.NORMAL);
+    }
+
+    public WindowEvent(Window source, int id, int oldState, int newState) {
+        this(source, id, null, oldState, newState);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite, 
+                       int oldState, int newState) {
+        super(source, id);
+
+        oppositeWindow = opposite;
+        this.oldState = oldState;
+        this.newState = newState;
+    }
+    */
+    //???AWT: Fake constructor
+    public WindowEvent() {
+        super(null, 0);
+    }
+    
+    public int getNewState() {
+        return newState;
+    }
+
+    public int getOldState() {
+        return oldState;
+    }
+
+    //???AWT
+    /*
+    public Window getOppositeWindow() {
+        return oppositeWindow;
+    }
+
+    public Window getWindow() {
+        return (Window) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * WindowEvent e = new WindowEvent(new Frame(), 
+         *          WindowEvent.WINDOW_OPENED); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case WINDOW_OPENED:
+            typeString = "WINDOW_OPENED"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSING:
+            typeString = "WINDOW_CLOSING"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSED:
+            typeString = "WINDOW_CLOSED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ICONIFIED:
+            typeString = "WINDOW_ICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEICONIFIED:
+            typeString = "WINDOW_DEICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ACTIVATED:
+            typeString = "WINDOW_ACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEACTIVATED:
+            typeString = "WINDOW_DEACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_GAINED_FOCUS:
+            typeString = "WINDOW_GAINED_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_LOST_FOCUS:
+            typeString = "WINDOW_LOST_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_STATE_CHANGED:
+            typeString = "WINDOW_STATE_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        //???AWT
+        /*
+        return typeString + ",opposite=" + oppositeWindow + //$NON-NLS-1$
+                ",oldState=" + oldState + ",newState=" + newState; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return typeString;
+    }
+
+}
diff --git a/awt/java/awt/event/WindowFocusListener.java b/awt/java/awt/event/WindowFocusListener.java
new file mode 100644
index 0000000..528459f
--- /dev/null
+++ b/awt/java/awt/event/WindowFocusListener.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;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface WindowFocusListener extends EventListener {
+
+    public void windowGainedFocus(WindowEvent e);
+
+    public void windowLostFocus(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowListener.java b/awt/java/awt/event/WindowListener.java
new file mode 100644
index 0000000..31bd547
--- /dev/null
+++ b/awt/java/awt/event/WindowListener.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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface WindowListener extends EventListener {
+
+    public void windowActivated(WindowEvent e);
+
+    public void windowClosed(WindowEvent e);
+
+    public void windowClosing(WindowEvent e);
+
+    public void windowDeactivated(WindowEvent e);
+
+    public void windowDeiconified(WindowEvent e);
+
+    public void windowIconified(WindowEvent e);
+
+    public void windowOpened(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowStateListener.java b/awt/java/awt/event/WindowStateListener.java
new file mode 100644
index 0000000..ba14d9e
--- /dev/null
+++ b/awt/java/awt/event/WindowStateListener.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.event;
+
+import java.util.EventListener;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface WindowStateListener extends EventListener {
+
+    public void windowStateChanged(WindowEvent e);
+
+}
+
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..d7de00f
--- /dev/null
+++ b/awt/java/awt/font/FontRenderContext.java
@@ -0,0 +1,178 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * The FontRenderContext class contains the information about text measurement.
+ * Anti-aliasing and fractional-metrics modes are defined by an application and
+ * affect the size of a character.
+ * 
+ * @since Android 1.0
+ */
+public class FontRenderContext {
+
+    // Affine transform of this mode
+    /**
+     * The transform.
+     */
+    private AffineTransform transform;
+
+    // Is the anti-aliased mode used
+    /**
+     * The anti aliased.
+     */
+    private boolean fAntiAliased;
+
+    // Is the fractional metrics used
+    /**
+     * The fractional metrics.
+     */
+    private boolean fFractionalMetrics;
+
+
+    /**
+     * Instantiates a new FontRenderContext object with the specified
+     * AffineTransform, anti-aliasing and fractional metrics flags.
+     * 
+     * @param trans
+     *            the AffineTransform.
+     * @param antiAliased
+     *            the anti-aliasing flag.
+     * @param usesFractionalMetrics
+     *            the fractional metrics flag.
+     */
+    public FontRenderContext(AffineTransform trans, boolean antiAliased, 
+            boolean usesFractionalMetrics) {
+        if (trans != null){
+            transform = new AffineTransform(trans);
+        }
+        fAntiAliased = antiAliased;
+        fFractionalMetrics = usesFractionalMetrics;
+    }
+
+    /**
+     * Instantiates a new FontRenderContext object.
+     */
+    protected FontRenderContext() {
+    }
+
+    /**
+     * Compares the specified Object with current FontRenderContext object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified Object is equal to current
+     *         FontRenderContext object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                return equals((FontRenderContext) obj);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+        return false;
+
+    }
+
+    /**
+     * Gets the transform which is used for scaling typographical points to
+     * pixels in this FontRenderContext.
+     * 
+     * @return the AffineTransform which is used for scaling typographical
+     *         points to pixels in this FontRenderContext.
+     */
+    public AffineTransform getTransform() {
+        if (transform != null){
+            return new AffineTransform(transform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Compares the specified FontRenderContext object with current
+     * FontRenderContext.
+     * 
+     * @param frc
+     *            the FontRenderContext object to be compared.
+     * @return true, if the specified FontRenderContext object is equal to
+     *         current FontRenderContext.
+     */
+    public boolean equals(FontRenderContext frc) {
+        if (this == frc){
+            return true;
+        }
+
+        if (frc == null){
+            return false;
+        }
+
+        if (!frc.getTransform().equals(this.getTransform()) &&
+            !frc.isAntiAliased() == this.fAntiAliased &&
+            !frc.usesFractionalMetrics() == this.fFractionalMetrics){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the text fractional metrics are used in this
+     * FontRenderContext.
+     * 
+     * @return true, if the text fractional metrics are used in this
+     *         FontRenderContext, false otherwise.
+     */
+    public boolean usesFractionalMetrics() {
+        return this.fFractionalMetrics;
+    }
+
+    /**
+     * Returns true if anti-aliasing is used in this FontRenderContext.
+     * 
+     * @return true, if is anti-aliasing is used in this FontRenderContext,
+     *         false otherwise.
+     */
+    public boolean isAntiAliased() {
+        return this.fAntiAliased;
+    }
+
+    /**
+     * Returns hash code of the FontRenderContext object.
+     * 
+     * @return the hash code of the FontRenderContext object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getTransform().hashCode() ^
+                new Boolean(this.fFractionalMetrics).hashCode() ^
+                new Boolean(this.fAntiAliased).hashCode();
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..b03de0a
--- /dev/null
+++ b/awt/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,197 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GlyphJustificationInfo class provides information about the glyph's
+ * justification properties. There are four justification properties: weight,
+ * priority, absorb, and limit.
+ * <p>
+ * There are two sets of metrics: growing and shrinking. Growing metrics are
+ * used when the glyphs are to be spread apart to fit a larger width. Shrinking
+ * metrics are used when the glyphs are to be moved together to fit a smaller
+ * width.
+ * </p>
+ * 
+ * @since Android 1.0
+ */
+public final class GlyphJustificationInfo {
+
+    /**
+     * The Constant PRIORITY_KASHIDA indicates the highest justification
+     * priority.
+     */
+    public static final int PRIORITY_KASHIDA = 0;
+
+    /**
+     * The Constant PRIORITY_WHITESPACE indicates the second highest
+     * justification priority.
+     */
+    public static final int PRIORITY_WHITESPACE = 1;
+
+    /**
+     * The Constant PRIORITY_INTERCHAR indicates the second lowest justification
+     * priority.
+     */
+    public static final int PRIORITY_INTERCHAR = 2;
+
+    /**
+     * The Constant PRIORITY_NONE indicates the lowest justification priority.
+     */
+    public static final int PRIORITY_NONE = 3;
+
+    /**
+     * The grow absorb flag indicates if this glyph absorbs all extra space at
+     * this and lower priority levels when it grows.
+     */
+    public final boolean growAbsorb;
+
+    /**
+     * The grow left limit value represents the maximum value by which the left
+     * side of this glyph grows.
+     */
+    public final float growLeftLimit;
+
+    /**
+     * The grow right limit value repesents the maximum value by which the right
+     * side of this glyph grows.
+     */
+    public final float growRightLimit;
+
+    /**
+     * The grow priority value represents the priority level of this glyph as it
+     * is growing.
+     */
+    public final int growPriority;
+
+    /**
+     * The shrink absorb fleg indicates this glyph absorbs all remaining
+     * shrinkage at this and lower priority levels as it shrinks.
+     */
+    public final boolean shrinkAbsorb;
+
+    /**
+     * The shrink left limit value represents the maximum value by which the
+     * left side of this glyph shrinks.
+     */
+    public final float shrinkLeftLimit;
+
+    /**
+     * The shrink right limit value represents the maximum value by which the
+     * right side of this glyph shrinks.
+     */
+    public final float shrinkRightLimit;
+
+    /**
+     * The shrink priority represents the glyth's priority level as it is
+     * shrinking.
+     */
+    public final int shrinkPriority;
+
+    /**
+     * The weight of the glyph.
+     */
+    public final float weight;
+
+    /**
+     * Instantiates a new GlyphJustificationInfo object which contains glyph's
+     * justification properties.
+     * 
+     * @param weight
+     *            the weight of glyph.
+     * @param growAbsorb
+     *            indicates if this glyph contais all space at this priority and
+     *            lower priority levels when it grows.
+     * @param growPriority
+     *            indicates the priority level of this glyph when it grows.
+     * @param growLeftLimit
+     *            indicates the maximum value of which the left side of this
+     *            glyph can grow.
+     * @param growRightLimit
+     *            the maximum value of which the right side of this glyph can
+     *            grow.
+     * @param shrinkAbsorb
+     *            indicates if this glyph contains all remaining shrinkage at
+     *            this and lower priority levels when it shrinks.
+     * @param shrinkPriority
+     *            indicates the glyph's priority level when it shrinks.
+     * @param shrinkLeftLimit
+     *            indicates the maximum value of which the left side of this
+     *            glyph can shrink.
+     * @param shrinkRightLimit
+     *            indicates the maximum amount by which the right side of this
+     *            glyph can shrink.
+     */
+    public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
+            float growLeftLimit, float growRightLimit, boolean shrinkAbsorb, int shrinkPriority,
+            float shrinkLeftLimit, float shrinkRightLimit) {
+
+        if (weight < 0) {
+            // awt.19C=weight must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
+        }
+        this.weight = weight;
+
+        if (growLeftLimit < 0) {
+            // awt.19D=growLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
+        }
+        this.growLeftLimit = growLeftLimit;
+
+        if (growRightLimit < 0) {
+            // awt.19E=growRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
+        }
+        this.growRightLimit = growRightLimit;
+
+        if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
+            // awt.19F=incorrect value for shrinkPriority, more than
+            // PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
+        }
+        this.shrinkPriority = shrinkPriority;
+
+        if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
+            // awt.200=incorrect value for growPriority, more than PRIORITY_NONE
+            // or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
+        }
+        this.growPriority = growPriority;
+
+        if (shrinkLeftLimit < 0) {
+            // awt.201=shrinkLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
+        }
+        this.shrinkLeftLimit = shrinkLeftLimit;
+
+        if (shrinkRightLimit < 0) {
+            // awt.202=shrinkRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
+        }
+        this.shrinkRightLimit = shrinkRightLimit;
+
+        this.shrinkAbsorb = shrinkAbsorb;
+        this.growAbsorb = growAbsorb;
+    }
+}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..2871722
--- /dev/null
+++ b/awt/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,266 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphMetrics class provides information about the size and shape of a
+ * single glyph. Each glyph has information to specify whether its baseline is
+ * horizontal or vertical as well as information on how it interacts with other
+ * characters in a text, given as one of the following types: STANDARD,
+ * LIGATURE, COMBINING, or COMPONENT.
+ * 
+ * @since Android 1.0
+ */
+public final class GlyphMetrics {
+
+    // advance width of the glyph character cell
+    /**
+     * The advance x.
+     */
+    private float advanceX;
+
+    // advance height of the glyph character cell
+    /**
+     * The advance y.
+     */
+    private float advanceY;
+
+    // flag if the glyph horizontal
+    /**
+     * The horizontal.
+     */
+    private boolean horizontal;
+
+    // glyph type code
+    /**
+     * The glyph type.
+     */
+    private byte glyphType;
+
+    // bounding box for outline of the glyph
+    /**
+     * The bounds.
+     */
+    private Rectangle2D.Float bounds;
+
+    /**
+     * The Constant STANDARD indicates a glyph that represents a single
+     * character.
+     */
+    public static final byte STANDARD = 0;
+
+    /**
+     * The Constant LIGATURE indicates a glyph that represents multiple
+     * characters as a ligature.
+     */
+    public static final byte LIGATURE = 1;
+
+    /**
+     * The Constant COMBINING indicates a glyph which has no caret position
+     * between glyphs (for example umlaut).
+     */
+    public static final byte COMBINING = 2;
+
+    /**
+     * The Constant COMPONENT indicates a glyph with no corresponding character
+     * in the backing store.
+     */
+    public static final byte COMPONENT = 3;
+
+    /**
+     * The Constant WHITESPACE indicates a glyph without visual representation.
+     */
+    public static final byte WHITESPACE = 4;
+
+    /**
+     * Instantiates a new GlyphMetrics object with the specified parameters.
+     * 
+     * @param horizontal
+     *            specifies if metrics are for a horizontal baseline (true
+     *            value), or a vertical baseline (false value).
+     * @param advanceX
+     *            the X component of the glyph's advance.
+     * @param advanceY
+     *            the Y component of the glyph's advance.
+     * @param bounds
+     *            the glyph's bounds.
+     * @param glyphType
+     *            the glyph's type.
+     */
+    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, Rectangle2D bounds,
+            byte glyphType) {
+        this.horizontal = horizontal;
+        this.advanceX = advanceX;
+        this.advanceY = advanceY;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
+     * 
+     * @param advanceX
+     *            the X component of the glyph's advance.
+     * @param bounds
+     *            the glyph's bounds.
+     * @param glyphType
+     *            the glyph's type.
+     */
+    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
+        this.advanceX = advanceX;
+        this.advanceY = 0;
+
+        this.horizontal = true;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Gets the glyph's bounds.
+     * 
+     * @return glyph's bounds.
+     */
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D.Float)this.bounds.clone();
+    }
+
+    /**
+     * Checks if this glyph is whitespace or not.
+     * 
+     * @return true, if this glyph is whitespace, false otherwise.
+     */
+    public boolean isWhitespace() {
+        return ((this.glyphType & 4) == WHITESPACE);
+    }
+
+    /**
+     * Checks if this glyph is standard or not.
+     * 
+     * @return true, if this glyph is standard, false otherwise.
+     */
+    public boolean isStandard() {
+        return ((this.glyphType & 3) == STANDARD);
+    }
+
+    /**
+     * Checks if this glyph is ligature or not.
+     * 
+     * @return true, if this glyph is ligature, false otherwise.
+     */
+    public boolean isLigature() {
+        return ((this.glyphType & 3) == LIGATURE);
+    }
+
+    /**
+     * Checks if this glyph is component or not.
+     * 
+     * @return true, if this glyph is component, false otherwise.
+     */
+    public boolean isComponent() {
+        return ((this.glyphType & 3) == COMPONENT);
+    }
+
+    /**
+     * Checks if this glyph is combining or not.
+     * 
+     * @return true, if this glyph is combining, false otherwise.
+     */
+    public boolean isCombining() {
+        return ((this.glyphType & 3) == COMBINING);
+    }
+
+    /**
+     * Gets the glyph's type.
+     * 
+     * @return the glyph's type.
+     */
+    public int getType() {
+        return this.glyphType;
+    }
+
+    /**
+     * Gets the distance from the right (for horizontal) or bottom (for
+     * vertical) of the glyph bounds to the advance.
+     * 
+     * @return the distance from the right (for horizontal) or bottom (for
+     *         vertical) of the glyph bounds to the advance.
+     */
+    public float getRSB() {
+        if (this.horizontal) {
+            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
+        }
+        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
+    }
+
+    /**
+     * Gets the distance from 0, 0 to the left (for horizontal) or top (for
+     * vertical) of the glyph bounds.
+     * 
+     * @return the distance from 0, 0 to the left (for horizontal) or top (for
+     *         vertical) of the glyph bounds.
+     */
+    public float getLSB() {
+        if (this.horizontal) {
+            return this.bounds.x;
+        }
+        return this.bounds.y;
+    }
+
+    /**
+     * Gets the Y component of the glyph's advance.
+     * 
+     * @return the Y component of the glyph's advance.
+     */
+    public float getAdvanceY() {
+        return this.advanceY;
+    }
+
+    /**
+     * Gets the X component of the glyph's advance.
+     * 
+     * @return the X component of the glyph's advance.
+     */
+    public float getAdvanceX() {
+        return this.advanceX;
+    }
+
+    /**
+     * Gets the glyph's advance along the baseline.
+     * 
+     * @return the glyph's advance.
+     */
+    public float getAdvance() {
+        if (this.horizontal) {
+            return this.advanceX;
+        }
+        return this.advanceY;
+    }
+
+}
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..a72b774
--- /dev/null
+++ b/awt/java/awt/font/GlyphVector.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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphVector class contains a collection of glyphs with geometric
+ * information and each glyph's location. Each GlyphVector can be associated
+ * with only one Font. GlyphVector contains the following properties for each
+ * glyph:
+ * <ul>
+ * <li>the glyph position;</li>
+ * <li>the transform of the glyph;</li>
+ * <li>the metrics of the glyph in the context of the GlyphVector.</li>
+ * </ul>
+ * 
+ * @since Android 1.0
+ */
+public abstract class GlyphVector implements Cloneable {
+
+    /**
+     * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector has
+     * per-glyph transforms.
+     */
+    public static final int FLAG_HAS_TRANSFORMS = 1;
+
+    /**
+     * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that the GlyphVector
+     * has per-glyph position adjustments.
+     */
+    public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+
+    /**
+     * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a right to
+     * left run direction.
+     */
+    public static final int FLAG_RUN_RTL = 4;
+
+    /**
+     * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector has a
+     * complex glyph to char mapping.
+     */
+    public static final int FLAG_COMPLEX_GLYPHS = 8;
+
+    /**
+     * The Constant FLAG_MASK indicates a mask for supported flags from
+     * getLayoutFlags.
+     */
+    public static final int FLAG_MASK = 15; // (|) mask of other flags
+
+    /**
+     * Instantiates a new GlyphVector.
+     */
+    public GlyphVector() {
+    }
+
+    /**
+     * Gets the pixel bounds of the GlyphVector when rendered at the specified
+     * location with the specified FontRenderContext.
+     * 
+     * @param frc
+     *            the FontRenderContext.
+     * @param x
+     *            the X coordinate of the GlyphVector's location.
+     * @param y
+     *            the Y coordinate of the GlyphVector's location.
+     * @return the pixel bounds
+     */
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+        // default implementation - integer Rectangle, that encloses visual
+        // bounds rectangle
+        Rectangle2D visualRect = getVisualBounds();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the pixel bounds of the glyph with the specified index in this
+     * GlyphVector which is rendered with the specified FontRenderContext at the
+     * specified location.
+     * 
+     * @param index
+     *            the glyph index in this GlyphVector.
+     * @param frc
+     *            the FontRenderContext.
+     * @param x
+     *            the X coordinate of the GlyphVector's location.
+     * @param y
+     *            the Y coordinate of the GlyphVector's location.
+     * @return a Rectangle bounds.
+     */
+    public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, float x, float y) {
+        Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the visual bounds of the GlyphVector.
+     * 
+     * @return the visual bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Gets the logical bounds of the GlyphVector.
+     * 
+     * @return the logical bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Sets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyph index in this GlyphVector.
+     * @param newPos
+     *            the new position of the glyph at the specified glyphIndex.
+     */
+    public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
+
+    /**
+     * Gets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyph index in this GlyphVector.
+     * @return the position of the specified glyph in this GlyphVector.
+     */
+    public abstract Point2D getGlyphPosition(int glyphIndex);
+
+    /**
+     * Sets the affine transform to a glyph with the specified index in this
+     * GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyth index in this GlyphVector.
+     * @param trans
+     *            the AffineTransform to be assigned to the specified glyph.
+     */
+    public abstract void setGlyphTransform(int glyphIndex, AffineTransform trans);
+
+    /**
+     * Gets the transform of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyph index in this GlyphVector.
+     * @return the new transform of the glyph.
+     */
+    public abstract AffineTransform getGlyphTransform(int glyphIndex);
+
+    /**
+     * Compares this GlyphVector with the specified GlyphVector objects.
+     * 
+     * @param glyphVector
+     *            the GlyphVector object to be compared.
+     * @return true, if this GlyphVector is equal to the specified GlyphVector
+     *         object, false otherwise.
+     */
+    public abstract boolean equals(GlyphVector glyphVector);
+
+    /**
+     * Gets the metrics of the glyph with the specified index in this
+     * GlyphVector.
+     * 
+     * @param glyphIndex
+     *            index in this GlyphVector.
+     * @return the metrics of the glyph with the specified index in this
+     *         GlyphVector.
+     */
+    public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
+
+    /**
+     * Gets the justification information of the glyph whose index is specified.
+     * 
+     * @param glyphIndex
+     *            the glyph index.
+     * @return the GlyphJustificationInfo for the specified glyph.
+     */
+    public abstract GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex);
+
+    /**
+     * Gets the FontRenderContext of this GlyphVector.
+     * 
+     * @return the FontRenderContext of this GlyphVector.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets a Shape object which defines the visual representation of the
+     * specified glyph in this GlyphVector, translated a distance of x in the X
+     * direction and y in the Y direction.
+     * 
+     * @param glyphIndex
+     *            the glyth index in this GlyphVector.
+     * @param x
+     *            the distance in the X direction to translate the shape object
+     *            before returning it.
+     * @param y
+     *            the distance in the Y direction to translate the shape object
+     *            before returning it.
+     * @return a Shape object which represents the visual representation of the
+     *         specified glyph in this GlyphVector - glyph outline.
+     */
+    public Shape getGlyphOutline(int glyphIndex, float x, float y) {
+        Shape initialShape = getGlyphOutline(glyphIndex);
+        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
+        return trans.createTransformedShape(initialShape);
+    }
+
+    /**
+     * Gets the visual bounds of the specified glyph in the GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyph index in this GlyphVector.
+     * @return the glyph visual bounds of the glyph with the specified index in
+     *         the GlyphVector.
+     */
+    public abstract Shape getGlyphVisualBounds(int glyphIndex);
+
+    /**
+     * Gets a Shape object which defines the visual representation of the
+     * specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the glyth index in this GlyphVector.
+     * @return a Shape object which represents the visual representation of the
+     *         specified glyph in this GlyphVector - glyph outline.
+     */
+    public abstract Shape getGlyphOutline(int glyphIndex);
+
+    /**
+     * Gets the logical bounds of the specified glyph in the GlyphVector.
+     * 
+     * @param glyphIndex
+     *            the index in this GlyphVector of the glyph from which to
+     *            retrieve its logical bounds
+     * @return the logical bounds of the specified glyph in the GlyphVector.
+     */
+    public abstract Shape getGlyphLogicalBounds(int glyphIndex);
+
+    /**
+     * Gets the visual representation of this GlyphVector rendered in x, y
+     * location as a Shape object.
+     * 
+     * @param x
+     *            the x coordinate of the GlyphVector.
+     * @param y
+     *            the y coordinate of the GlyphVector.
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline(float x, float y);
+
+    /**
+     * Gets the visual representation of this GlyphVector as a Shape object.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline();
+
+    /**
+     * Gets the font of this GlyphVector.
+     * 
+     * @return the font of this GlyphVector.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets an array of the glyph codes of the specified glyphs.
+     * 
+     * @param beginGlyphIndex
+     *            the index into this GlyphVector at which to start retrieving
+     *            glyph codes.
+     * @param numEntries
+     *            the number of glyph codes.
+     * @param codeReturn
+     *            the array into which the resulting glyphcodes will be written.
+     * @return the array of the glyph codes.
+     */
+    public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, int[] codeReturn);
+
+    /**
+     * Gets an array of the character indices of the specified glyphs.
+     * 
+     * @param beginGlyphIndex
+     *            the index of the first glyph to return information for.
+     * @param numEntries
+     *            the number of glyph indices to return.
+     * @param codeReturn
+     *            the array into which the resulting character indices will be
+     *            written.
+     * @return an array of character indices for the specifies glyphs.
+     */
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, int[] codeReturn) {
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++) {
+            codeReturn[i] = getGlyphCharIndex(i + beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Gets an array of the positions of the specified glyphs in this
+     * GlyphVector.
+     * 
+     * @param beginGlyphIndex
+     *            the index of the first glyph to return information for.
+     * @param numEntries
+     *            the number of glyphs to return information for.
+     * @param positionReturn
+     *            the array where the result will be stored.
+     * @return an array of glyph positions.
+     */
+    public abstract float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+            float[] positionReturn);
+
+    /**
+     * Gets the glyph code of the specified glyph.
+     * 
+     * @param glyphIndex
+     *            the index in this GlyphVector which corresponds to the glyph
+     *            from which to retrieve the glyphcode.
+     * @return the glyphcode of the specified glyph.
+     */
+    public abstract int getGlyphCode(int glyphIndex);
+
+    /**
+     * Gets the first logical character's index of the specified glyph.
+     * 
+     * @param glyphIndex
+     *            the glyph index.
+     * @return the the first logical character's index.
+     */
+    public int getGlyphCharIndex(int glyphIndex) {
+        // default implemetation one-to-one
+        return glyphIndex;
+    }
+
+    /**
+     * Sets default layout to this GlyphVector.
+     */
+    public abstract void performDefaultLayout();
+
+    /**
+     * Gets the number of glyphs in the GlyphVector.
+     * 
+     * @return the number of glyphs in the GlyphVector.
+     */
+    public abstract int getNumGlyphs();
+
+    /**
+     * Gets flags which describe the global state of the GlyphVector. The
+     * default implementation returns 0.
+     * 
+     * @return the layout flags
+     */
+    public int getLayoutFlags() {
+        // default implementation - returned value is 0
+        return 0;
+    }
+
+}
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..8480e0f
--- /dev/null
+++ b/awt/java/awt/font/GraphicAttribute.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.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicAttribute abstract class provides an opportunity to insert
+ * graphical elements in printed text.
+ * 
+ * @since Android 1.0
+ */
+public abstract class GraphicAttribute {
+
+    /**
+     * The Constant TOP_ALIGNMENT indicates using the top line to calculate
+     * placement of graphics.
+     */
+    public static final int TOP_ALIGNMENT = -1;
+
+    /**
+     * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to
+     * calculate placement of graphics.
+     */
+    public static final int BOTTOM_ALIGNMENT = -2;
+
+    /**
+     * The Constant ROMAN_BASELINE indicates the placement of the roman baseline
+     * with respect to the graphics origin.
+     */
+    public static final int ROMAN_BASELINE = 0;
+
+    /**
+     * The Constant CENTER_BASELINE indicates the placement of the center
+     * baseline with respect to the graphics origin.
+     */
+    public static final int CENTER_BASELINE = 1;
+
+    /**
+     * The Constant HANGING_BASELINE indicates the placement of the hanging
+     * baseline with respect to the graphics origin.
+     */
+    public static final int HANGING_BASELINE = 2;
+
+    // the alignment of this GraphicAttribute
+    /**
+     * The alignment.
+     */
+    private int alignment;
+
+    /**
+     * Instantiates a new graphic attribute with the specified alignment.
+     * 
+     * @param align
+     *            the specified alignment.
+     */
+    protected GraphicAttribute(int align) {
+        if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
+            // awt.198=Illegal alignment argument
+            throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
+        }
+        this.alignment = align;
+    }
+
+    /**
+     * Draws the GraphicAttribute at the specified location.
+     * 
+     * @param graphics
+     *            the Graphics.
+     * @param x
+     *            the X coordinate of GraphicAttribute location.
+     * @param y
+     *            the Y coordinate of GraphicAttribute location.
+     */
+    public abstract void draw(Graphics2D graphics, float x, float y);
+
+    /**
+     * Gets the GraphicAttribute's advance. It's the distance from the point at
+     * which the graphic is rendered and the point where the next character or
+     * graphic is rendered.
+     * 
+     * @return the GraphicAttribute's advance.
+     */
+    public abstract float getAdvance();
+
+    /**
+     * Gets the alignment of this GraphicAttribute.
+     * 
+     * @return the alignment of this GraphicAttribute.
+     */
+    public final int getAlignment() {
+        return this.alignment;
+    }
+
+    /**
+     * Gets the ascent of this GraphicAttribute.
+     * 
+     * @return the ascent of this GraphicAttribute.
+     */
+    public abstract float getAscent();
+
+    /**
+     * Gets the bounds of this GraphicAttribute.
+     * 
+     * @return the bounds of this GraphicAttribute.
+     */
+    public Rectangle2D getBounds() {
+        float ascent = getAscent();
+        float advance = getAdvance();
+        float descent = getDescent();
+
+        // Default implementation - see API documentation.
+        return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
+    }
+
+    /**
+     * Gets the descent of this GraphicAttribute.
+     * 
+     * @return the descent of this GraphicAttribute.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the GlyphJustificationInfo of this GraphicAttribute.
+     * 
+     * @return the GlyphJustificationInfo of this GraphicAttribute.
+     */
+    public GlyphJustificationInfo getJustificationInfo() {
+
+        /*
+         * Default implementation. Since documentation doesn't describe default
+         * values, they were calculated based on 1.5 release behavior and can be
+         * obtained using next test sample: // Create GraphicAttribute class
+         * implementation public class MyGraphicAttribute extends
+         * GraphicAttribute { protected MyGraphicAttribute(int align) {
+         * super(align); } public float getDescent() { return 0; } public float
+         * getAdvance() { return 1; } public void draw(Graphics2D g2, float x,
+         * float y) { } public float getAscent() { return 0; } }
+         * MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0); // print
+         * justification parameters
+         * System.out.println(myGA.getJustificationInfo().growAbsorb);
+         * System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
+         * System.out.println(myGA.getJustificationInfo().growLeftLimit);
+         * System.out.println(myGA.getJustificationInfo().growPriority);
+         * System.out.println(myGA.getJustificationInfo().growRightLimit);
+         * System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
+         * System.out.println(myGA.getJustificationInfo().shrinkPriority);
+         * System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
+         * System.out.println(myGA.getJustificationInfo().weight);
+         */
+        float advance = getAdvance();
+        return new GlyphJustificationInfo(advance, false,
+                GlyphJustificationInfo.PRIORITY_INTERCHAR, advance / 3, advance / 3, false,
+                GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, 0);
+    }
+
+}
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..d6d4758
--- /dev/null
+++ b/awt/java/awt/font/ImageGraphicAttribute.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 java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ImageGraphicAttribute class provides an opportunity to insert images to a
+ * text.
+ * 
+ * @since Android 1.0
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute {
+
+    // Image object rendered by this ImageGraphicAttribute
+    /**
+     * The image.
+     */
+    private Image fImage;
+
+    // X coordinate of the origin point
+    /**
+     * The origin x.
+     */
+    private float fOriginX;
+
+    // Y coordinate of the origin point
+    /**
+     * The origin y.
+     */
+    private float fOriginY;
+
+    // the width of the image object
+    /**
+     * The img width.
+     */
+    private float fImgWidth;
+
+    // the height of the image object
+    /**
+     * The img height.
+     */
+    private float fImgHeight;
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image,
+     * alignment and origins.
+     * 
+     * @param image
+     *            the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment
+     *            the alignment of the ImageGraphicAttribute.
+     * @param originX
+     *            the origin X coordinate in the image of ImageGraphicAttribute.
+     * @param originY
+     *            the origin Y coordinate in the image of ImageGraphicAttribute.
+     */
+    public ImageGraphicAttribute(Image image, int alignment, float originX, float originY) {
+        super(alignment);
+
+        this.fImage = image;
+        this.fOriginX = originX;
+        this.fOriginY = originY;
+
+        this.fImgWidth = fImage.getWidth(null);
+        this.fImgHeight = fImage.getHeight(null);
+
+    }
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image and
+     * alignment.
+     * 
+     * @param image
+     *            the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment
+     *            the alignment of the ImageGraphicAttribute.
+     */
+    public ImageGraphicAttribute(Image image, int alignment) {
+        this(image, alignment, 0, 0);
+    }
+
+    /**
+     * Returns a hash code of this ImageGraphicAttribute object.
+     * 
+     * @return the hash code of this ImageGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fImage.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares the specified ImageGraphicAttribute object with this
+     * ImageGraphicAttribute object.
+     * 
+     * @param iga
+     *            the ImageGraphicAttribute object to be compared.
+     * @return true, if the specified ImageGraphicAttribute object is equal to
+     *         this ImageGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ImageGraphicAttribute iga) {
+        if (iga == null) {
+            return false;
+        }
+
+        if (iga == this) {
+            return true;
+        }
+
+        return (fOriginX == iga.fOriginX && fOriginY == iga.fOriginY
+                && getAlignment() == iga.getAlignment() && fImage.equals(iga.fImage));
+    }
+
+    /**
+     * Compares the specified Object with this ImageGraphicAttribute object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified Object is equal to this
+     *         ImageGraphicAttribute object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ImageGraphicAttribute)obj);
+        } catch (ClassCastException e) {
+            return false;
+        }
+
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
+    }
+
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fImgWidth - fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
+    }
+
+    @Override
+    public float getDescent() {
+        return Math.max(0, fImgHeight - fOriginY);
+    }
+
+}
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..4800093
--- /dev/null
+++ b/awt/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,238 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator; //???AWT: import java.text.BreakIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class LineBreakMeasurer provides methods to measure the graphical
+ * representation of a text in order to determine where to add line breaks so
+ * the resulting line of text fits its wrapping width. The wrapping width
+ * defines the visual width of the paragraph.
+ * 
+ * @since Android 1.0
+ */
+public final class LineBreakMeasurer {
+
+    /**
+     * The tm.
+     */
+    private TextMeasurer tm = null;
+
+    // ???AWT private BreakIterator bi = null;
+    /**
+     * The position.
+     */
+    private int position = 0;
+
+    /**
+     * The maxpos.
+     */
+    int maxpos = 0;
+
+    /**
+     * Instantiates a new LineBreakMeasurer object for the specified text.
+     * 
+     * @param text
+     *            the AttributedCharacterIterator object which contains text
+     *            with at least one character.
+     * @param frc
+     *            the FontRenderContext represented information about graphic
+     *            device.
+     */
+    public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        // ???AWT: this(text, BreakIterator.getLineInstance(), frc);
+    }
+
+    /*
+     * ???AWT public LineBreakMeasurer( AttributedCharacterIterator text,
+     * BreakIterator bi, FontRenderContext frc ) { tm = new TextMeasurer(text,
+     * frc); this.bi = bi; this.bi.setText(text); position =
+     * text.getBeginIndex(); maxpos = tm.aci.getEndIndex(); }
+     */
+
+    /**
+     * Deletes a character from the specified position of the text, updates this
+     * LineBreakMeasurer object.
+     * 
+     * @param newText
+     *            the new text.
+     * @param pos
+     *            the position of the character which is deleted.
+     */
+    public void deleteChar(AttributedCharacterIterator newText, int pos) {
+        tm.deleteChar(newText, pos);
+        // ???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos--;
+    }
+
+    /**
+     * Gets current position of this LineBreakMeasurer.
+     * 
+     * @return the current position of this LineBreakMeasurer
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    /**
+     * Inserts a character at the specified position in the text, updates this
+     * LineBreakMeasurer object.
+     * 
+     * @param newText
+     *            the new text.
+     * @param pos
+     *            the position of the character which is inserted.
+     */
+    public void insertChar(AttributedCharacterIterator newText, int pos) {
+        tm.insertChar(newText, pos);
+        // ???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos++;
+    }
+
+    /**
+     * Returns the next line of text, updates current position in this
+     * LineBreakMeasurer.
+     * 
+     * @param wrappingWidth
+     *            the maximum visible line width.
+     * @param offsetLimit
+     *            the limit point within the text indicating that no further
+     *            text should be included on the line; the paragraph break.
+     * @param requireNextWord
+     *            if true, null is returned (the entire word at the current
+     *            position does not fit within the wrapping width); if false, a
+     *            valid layout is returned that includes at least the character
+     *            at the current position.
+     * @return the next TextLayout which begins at the current position and
+     *         represents the next line of text with width wrappingWidth, null
+     *         is returned if the entire word at the current position does not
+     *         fit within the wrapping width.
+     */
+    public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (position == maxpos) {
+            return null;
+        }
+
+        int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
+
+        if (nextPosition == position) {
+            return null;
+        }
+        TextLayout layout = tm.getLayout(position, nextPosition);
+        position = nextPosition;
+        return layout;
+    }
+
+    /**
+     * Returns the next line of text.
+     * 
+     * @param wrappingWidth
+     *            the maximum visible line width.
+     * @return the next line of text.
+     */
+    public TextLayout nextLayout(float wrappingWidth) {
+        return nextLayout(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth
+     *            the maximum visible line width.
+     * @return the end position of the next line of text.
+     */
+    public int nextOffset(float wrappingWidth) {
+        return nextOffset(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth
+     *            the maximum visible line width.
+     * @param offsetLimit
+     *            the limit point withing the text indicating that no further
+     *            text should be included on the line; the paragraph break.
+     * @param requireNextWord
+     *            if true, the current position is returned if the entire next
+     *            word does not fit within wrappingWidth; if false, the offset
+     *            returned is at least one greater than the current position.
+     * @return the end position of the next line of text.
+     * @throws IllegalArgumentException
+     *             if the offsetLimit is less than the current position.
+     */
+    public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (offsetLimit <= position) {
+            // awt.203=Offset limit should be greater than current position.
+            throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
+        }
+
+        if (position == maxpos) {
+            return position;
+        }
+
+        int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
+        int correctedPos = breakPos;
+
+        // This check is required because bi.preceding(maxpos) throws an
+        // exception
+        /*
+         * ???AWT if (breakPos == maxpos) { correctedPos = maxpos; } else if
+         * (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
+         * correctedPos = bi.following(breakPos); } else { correctedPos =
+         * bi.preceding(breakPos); }
+         */
+
+        if (position >= correctedPos) {
+            if (requireNextWord) {
+                correctedPos = position;
+            } else {
+                correctedPos = Math.max(position + 1, breakPos);
+            }
+        }
+
+        return Math.min(correctedPos, offsetLimit);
+    }
+
+    /**
+     * Sets the new position of this LineBreakMeasurer.
+     * 
+     * @param pos
+     *            the new position of this LineBreakMeasurer.
+     */
+    public void setPosition(int pos) {
+        if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
+            // awt.33=index is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
+        }
+        position = pos;
+    }
+}
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..4b03e5d
--- /dev/null
+++ b/awt/java/awt/font/LineMetrics.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.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+/**
+ * The LineMetrics class provides information such as concerning how the text is
+ * positioned with respect to the base line, such as ascent, descent, and
+ * leading.
+ * 
+ * @since Android 1.0
+ */
+public abstract class LineMetrics {
+
+    /**
+     * Gets the baseline offsets of the text according to the the baseline of
+     * this text.
+     * 
+     * @return the baseline offsets of the text according to the the baseline of
+     *         this text.
+     */
+    public abstract float[] getBaselineOffsets();
+
+    /**
+     * Gets the number of characters of the text.
+     * 
+     * @return the number of characters of the text.
+     */
+    public abstract int getNumChars();
+
+    /**
+     * Gets the baseline index, returns one of the following index:
+     * ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
+     * 
+     * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE or
+     *         HANGING_BASELINE.
+     */
+    public abstract int getBaselineIndex();
+
+    /**
+     * Gets the thickness of the underline.
+     * 
+     * @return the thickness of the underline.
+     */
+    public abstract float getUnderlineThickness();
+
+    /**
+     * Gets the offset of the underline.
+     * 
+     * @return the offset of the underline.
+     */
+    public abstract float getUnderlineOffset();
+
+    /**
+     * Gets the thickness of strike through line.
+     * 
+     * @return the thickness of strike through line.
+     */
+    public abstract float getStrikethroughThickness();
+
+    /**
+     * Gets the offset of the strike through line.
+     * 
+     * @return the offset of the strike through line.
+     */
+    public abstract float getStrikethroughOffset();
+
+    /**
+     * Gets the leading of the text.
+     * 
+     * @return the leading of the text.
+     */
+    public abstract float getLeading();
+
+    /**
+     * Gets the height of the text as a sum of the ascent, the descent and the
+     * leading.
+     * 
+     * @return the height of the text as a sum of the ascent, the descent and
+     *         the leading.
+     */
+    public abstract float getHeight();
+
+    /**
+     * Gets the descent of the text.
+     * 
+     * @return the descent of the text.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the ascent of the text.
+     * 
+     * @return the ascent of the text.
+     */
+    public abstract float getAscent();
+
+}
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..d264f24
--- /dev/null
+++ b/awt/java/awt/font/MultipleMaster.java
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * The MultipleMaster interface provides methods to manipulate MultipleMaster
+ * type fonts and retrieve graphical and design data from them.
+ * 
+ * @since Android 1.0
+ */
+public interface MultipleMaster {
+
+    /**
+     * Derives a new multiple master font based on the specified parameters.
+     * 
+     * @param glyphWidths
+     *            float array which represents width of each glyph in font
+     *            space.
+     * @param avgStemWidth
+     *            the average stem width in font space.
+     * @param typicalCapHeight
+     *            the typical upper case char height.
+     * @param typicalXHeight
+     *            the typical lower case char height.
+     * @param italicAngle
+     *            the slope angle for italics.
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] glyphWidths, float avgStemWidth, float typicalCapHeight,
+            float typicalXHeight, float italicAngle);
+
+    /**
+     * Derives a new multiple master font based on the design axis values
+     * contained in the specified array.
+     * 
+     * @param axes
+     *            an float array which contains axis values.
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] axes);
+
+    /**
+     * Gets default design values for the axes.
+     * 
+     * @return the default design values for the axes.
+     */
+    public float[] getDesignAxisDefaults();
+
+    /**
+     * Gets the array of design axis names.
+     * 
+     * @return the array of design axis names.
+     */
+    public String[] getDesignAxisNames();
+
+    /**
+     * Gets the array of design axis ranges.
+     * 
+     * @return the array of design axis ranges.
+     */
+    public float[] getDesignAxisRanges();
+
+    /**
+     * Gets the number of multiple master design controls.
+     * 
+     * @return the number of multiple master design controls.
+     */
+    public int getNumDesignAxes();
+
+}
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
new file mode 100644
index 0000000..db66911
--- /dev/null
+++ b/awt/java/awt/font/OpenType.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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+/**
+ * The OpenType interface provides constants and methods for getting instance
+ * data for fonts of type OpenType and TrueType. For more information, see the
+ * <a
+ * href="http://partners.adobe.com/public/developer/opentype/index_spec.html">
+ * OpenType specification</a>.
+ * 
+ * @since Android 1.0
+ */
+public interface OpenType {
+
+    /**
+     * The Constant TAG_ACNT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_ACNT = 1633906292;
+
+    /**
+     * The Constant TAG_AVAR indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_AVAR = 1635148146;
+
+    /**
+     * The Constant TAG_BASE indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_BASE = 1111577413;
+
+    /**
+     * The Constant TAG_BDAT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_BDAT = 1650745716;
+
+    /**
+     * The Constant TAG_BLOC indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_BLOC = 1651273571;
+
+    /**
+     * The Constant TAG_BSLN indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_BSLN = 1651731566;
+
+    /**
+     * The Constant TAG_CFF indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_CFF = 1128678944;
+
+    /**
+     * The Constant TAG_CMAP indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_CMAP = 1668112752;
+
+    /**
+     * The Constant TAG_CVAR indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_CVAR = 1668702578;
+
+    /**
+     * The Constant TAG_CVT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_CVT = 1668707360;
+
+    /**
+     * The Constant TAG_DSIG indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_DSIG = 1146308935;
+
+    /**
+     * The Constant TAG_EBDT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_EBDT = 1161970772;
+
+    /**
+     * The Constant TAG_EBLC indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_EBLC = 1161972803;
+
+    /**
+     * The Constant TAG_EBSC indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_EBSC = 1161974595;
+
+    /**
+     * The Constant TAG_FDSC indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_FDSC = 1717859171;
+
+    /**
+     * The Constant TAG_FEAT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_FEAT = 1717920116;
+
+    /**
+     * The Constant TAG_FMTX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_FMTX = 1718449272;
+
+    /**
+     * The Constant TAG_FPGM indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_FPGM = 1718642541;
+
+    /**
+     * The Constant TAG_FVAR indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_FVAR = 1719034226;
+
+    /**
+     * The Constant TAG_GASP indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GASP = 1734439792;
+
+    /**
+     * The Constant TAG_GDEF indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GDEF = 1195656518;
+
+    /**
+     * The Constant TAG_GLYF indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GLYF = 1735162214;
+
+    /**
+     * The Constant TAG_GPOS indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GPOS = 1196445523;
+
+    /**
+     * The Constant TAG_GSUB indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GSUB = 1196643650;
+
+    /**
+     * The Constant TAG_GVAR indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_GVAR = 1735811442;
+
+    /**
+     * The Constant TAG_HDMX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_HDMX = 1751412088;
+
+    /**
+     * The Constant TAG_HEAD indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_HEAD = 1751474532;
+
+    /**
+     * The Constant TAG_HHEA indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_HHEA = 1751672161;
+
+    /**
+     * The Constant TAG_HMTX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_HMTX = 1752003704;
+
+    /**
+     * The Constant TAG_JSTF indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_JSTF = 1246975046;
+
+    /**
+     * The Constant TAG_JUST indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_JUST = 1786082164;
+
+    /**
+     * The Constant TAG_KERN indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_KERN = 1801810542;
+
+    /**
+     * The Constant TAG_LCAR indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_LCAR = 1818452338;
+
+    /**
+     * The Constant TAG_LOCA indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_LOCA = 1819239265;
+
+    /**
+     * The Constant TAG_LTSH indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_LTSH = 1280594760;
+
+    /**
+     * The Constant TAG_MAXP indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_MAXP = 1835104368;
+
+    /**
+     * The Constant TAG_MMFX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_MMFX = 1296909912;
+
+    /**
+     * The Constant TAG_MMSD indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_MMSD = 1296913220;
+
+    /**
+     * The Constant TAG_MORT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_MORT = 1836020340;
+
+    /**
+     * The Constant TAG_NAME indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_NAME = 1851878757;
+
+    /**
+     * The Constant TAG_OPBD indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_OPBD = 1836020340;
+
+    /**
+     * The Constant TAG_OS2 indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_OS2 = 1330851634;
+
+    /**
+     * The Constant TAG_PCLT indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_PCLT = 1346587732;
+
+    /**
+     * The Constant TAG_POST indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_POST = 1886352244;
+
+    /**
+     * The Constant TAG_PREP indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_PREP = 1886545264;
+
+    /**
+     * The Constant TAG_PROP indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_PROP = 1886547824;
+
+    /**
+     * The Constant TAG_TRAK indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_TRAK = 1953653099;
+
+    /**
+     * The Constant TAG_TYP1 indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_TYP1 = 1954115633;
+
+    /**
+     * The Constant TAG_VDMX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_VDMX = 1447316824;
+
+    /**
+     * The Constant TAG_VHEA indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_VHEA = 1986553185;
+
+    /**
+     * The Constant TAG_VMTX indicates corresponding table tag in the Open Type
+     * Specification.
+     */
+    public static final int TAG_VMTX = 1986884728;
+
+    /**
+     * Returns the OpenType font version.
+     * 
+     * @return the the OpenType font version.
+     */
+    public int getVersion();
+
+    /**
+     * Gets the table for a specified tag. Sfnt tables include cmap, name and
+     * head items.
+     * 
+     * @param sfntTag
+     *            the sfnt tag.
+     * @return a byte array contains the font data corresponding to the
+     *         specified tag.
+     */
+    public byte[] getFontTable(int sfntTag);
+
+    /**
+     * Gets the table for a specified tag. Sfnt tables include cmap, name and
+     * head items.
+     * 
+     * @param sfntTag
+     *            the sfnt tag.
+     * @param offset
+     *            the offset of the returned table.
+     * @param count
+     *            the number of returned table.
+     * @return the table corresponding to sfntTag and containing the bytes
+     *         starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(int sfntTag, int offset, int count);
+
+    /**
+     * Gets the table for a specified tag. Sfnt tables include cmap, name and
+     * head items.
+     * 
+     * @param strSfntTag
+     *            the str sfnt tag as a String.
+     * @return a byte array contains the font data corresponding to the
+     *         specified tag.
+     */
+    public byte[] getFontTable(String strSfntTag);
+
+    /**
+     * Gets the table for a specified tag. Sfnt tables include cmap, name and
+     * head items.
+     * 
+     * @param strSfntTag
+     *            the sfnt tag as a String.
+     * @param offset
+     *            the offset of the returned table.
+     * @param count
+     *            the number of returned table.
+     * @return the table corresponding to sfntTag and containing the bytes
+     *         starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(String strSfntTag, int offset, int count);
+
+    /**
+     * Gets the table size for a specified tag.
+     * 
+     * @param strSfntTag
+     *            the sfnt tag as a String.
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(String strSfntTag);
+
+    /**
+     * Gets the table size for a specified tag.
+     * 
+     * @param sfntTag
+     *            the sfnt tag.
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(int sfntTag);
+
+}
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..182bffd
--- /dev/null
+++ b/awt/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,206 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ShapeGraphicAttribute class provides an opportunity to insert shapes to a
+ * text.
+ * 
+ * @since Android 1.0
+ */
+public final class ShapeGraphicAttribute extends GraphicAttribute {
+
+    // shape to render
+    /**
+     * The shape.
+     */
+    private Shape fShape;
+
+    // flag, if the shape should be stroked (true) or filled (false)
+    /**
+     * The stroke.
+     */
+    private boolean fStroke;
+
+    // bounds of the shape
+    /**
+     * The bounds.
+     */
+    private Rectangle2D fBounds;
+
+    // X coordinate of the origin point
+    /**
+     * The origin x.
+     */
+    private float fOriginX;
+
+    // Y coordinate of the origin point
+    /**
+     * The origin y.
+     */
+    private float fOriginY;
+
+    // width of the shape
+    /**
+     * The shape width.
+     */
+    private float fShapeWidth;
+
+    // height of the shape
+    /**
+     * The shape height.
+     */
+    private float fShapeHeight;
+
+    /**
+     * The Constant STROKE indicates whether the Shape is stroked or not.
+     */
+    public static final boolean STROKE = true;
+
+    /**
+     * The Constant FILL indicates whether the Shape is filled or not.
+     */
+    public static final boolean FILL = false;
+
+    /**
+     * Instantiates a new ShapeGraphicAttribute object for the specified Shape.
+     * 
+     * @param shape
+     *            the shape to be rendered by this ShapeGraphicAttribute.
+     * @param alignment
+     *            the alignment of this ShapeGraphicAttribute.
+     * @param stroke
+     *            true if the Shape is stroked, false if the Shape is filled.
+     */
+    public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
+        super(alignment);
+
+        this.fShape = shape;
+        this.fStroke = stroke;
+
+        this.fBounds = fShape.getBounds2D();
+
+        this.fOriginX = (float)fBounds.getMinX();
+        this.fOriginY = (float)fBounds.getMinY();
+
+        this.fShapeWidth = (float)fBounds.getWidth();
+        this.fShapeHeight = (float)fBounds.getHeight();
+    }
+
+    /**
+     * Returns a hash code of this ShapeGraphicAttribute object.
+     * 
+     * @return a hash code of this ShapeGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fShape.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * ShapeGraphicAttribute object.
+     * 
+     * @param sga
+     *            the ShapeGraphicAttribute object to be compared.
+     * @return true, if this ShapeGraphicAttribute object is equal to the
+     *         specified ShapeGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ShapeGraphicAttribute sga) {
+        if (sga == null) {
+            return false;
+        }
+
+        if (sga == this) {
+            return true;
+        }
+
+        return (fStroke == sga.fStroke && getAlignment() == sga.getAlignment() && fShape
+                .equals(sga.fShape));
+
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified Object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if this ShapeGraphicAttribute object is equal to the
+     *         specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ShapeGraphicAttribute)obj);
+        } catch (ClassCastException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+        if (fStroke == STROKE) {
+            Stroke oldStroke = g2.getStroke();
+            g2.setStroke(new BasicStroke());
+            g2.draw(at.createTransformedShape(fShape));
+            g2.setStroke(oldStroke);
+        } else {
+            g2.fill(at.createTransformedShape(fShape));
+        }
+
+    }
+
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fShapeWidth + fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, -fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return (Rectangle2D)fBounds.clone();
+    }
+
+    @Override
+    public float getDescent() {
+        return Math.max(0, fShapeHeight + fOriginY);
+    }
+
+}
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..6460eba
--- /dev/null
+++ b/awt/java/awt/font/TextHitInfo.java
@@ -0,0 +1,215 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The TextHitInfo class provides information about a caret position in a text
+ * model for insertion or deletion of a character in a text. The TextHitInfo
+ * defines two biases of the character: leading or trailing. Leading position
+ * means the left edge of the specified character (TextHitInfo.leading(2) method
+ * for "text" returns the left side of "x"). Trailing position means the right
+ * edge of the specified character (TextHitInfo.trailing(2) method for "text"
+ * returns the right side of "x").
+ * 
+ * @since Android 1.0
+ */
+public final class TextHitInfo {
+
+    /**
+     * The char idx.
+     */
+    private int charIdx; // Represents character index in the line
+
+    /**
+     * The is trailing.
+     */
+    private boolean isTrailing;
+
+    /**
+     * Instantiates a new text hit info.
+     * 
+     * @param idx
+     *            the idx.
+     * @param isTrailing
+     *            the is trailing.
+     */
+    private TextHitInfo(int idx, boolean isTrailing) {
+        charIdx = idx;
+        this.isTrailing = isTrailing;
+    }
+
+    /**
+     * Returns the textual string representation of this TextHitInfo instance.
+     * 
+     * @return the string representation.
+     */
+    @Override
+    public String toString() {
+        return new String("TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
+                (isTrailing ? "Trailing" : "Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        );
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if the specified object is a TextHitInfo object with the
+     *         same data values as this TextHitInfo, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof TextHitInfo) {
+            return equals((TextHitInfo)obj);
+        }
+        return false;
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified TextHitInfo object.
+     * 
+     * @param thi
+     *            the TextHitInfo object to be compared.
+     * @return true, if this TextHitInfo object has the same data values as the
+     *         specified TextHitInfo object, false otherwise.
+     */
+    public boolean equals(TextHitInfo thi) {
+        return thi != null && thi.charIdx == charIdx && thi.isTrailing == isTrailing;
+    }
+
+    /**
+     * Gets a TextHitInfo object with its character index at the specified
+     * offset from the character index of this TextHitInfo.
+     * 
+     * @param offset
+     *            the offset.
+     * @return the TextHitInfo.
+     */
+    public TextHitInfo getOffsetHit(int offset) {
+        return new TextHitInfo(charIdx + offset, isTrailing);
+    }
+
+    /**
+     * Gets a TextHitInfo associated with the other side of the insertion point.
+     * 
+     * @return the other hit.
+     */
+    public TextHitInfo getOtherHit() {
+        return isTrailing ? new TextHitInfo(charIdx + 1, false)
+                : new TextHitInfo(charIdx - 1, true);
+    }
+
+    /**
+     * Returns true if the leading edge of the character is hit, false if the
+     * trailing edge of the character is hit.
+     * 
+     * @return true if the leading edge of the character is hit, false if the
+     *         trailing edge of the character is hit.
+     */
+    public boolean isLeadingEdge() {
+        return !isTrailing;
+    }
+
+    /**
+     * Returns the hash code value of this TextHitInfo instance.
+     * 
+     * @return the hash code value.
+     */
+    @Override
+    public int hashCode() {
+        return HashCode.combine(charIdx, isTrailing);
+    }
+
+    /**
+     * Gets the insertion index.
+     * 
+     * @return the insertion index: character index if the leading edge is hit,
+     *         or character index + 1 if the trailing edge is hit.
+     */
+    public int getInsertionIndex() {
+        return isTrailing ? charIdx + 1 : charIdx;
+    }
+
+    /**
+     * Gets the index of the character hit.
+     * 
+     * @return the character hit's index.
+     */
+    public int getCharIndex() {
+        return charIdx;
+    }
+
+    /**
+     * Returns a TextHitInfo associated with the trailing edge of the character
+     * at the specified char index.
+     * 
+     * @param charIndex
+     *            the char index.
+     * @return the TextHitInfo associated with the trailing edge of the
+     *         character at the specified char index.
+     */
+    public static TextHitInfo trailing(int charIndex) {
+        return new TextHitInfo(charIndex, true);
+    }
+
+    /**
+     * Returns a TextHitInfo object associated with the leading edge of the
+     * character at the specified char index.
+     * 
+     * @param charIndex
+     *            the char index.
+     * @return the TextHitInfo object associated with the leading edge of the
+     *         character at the specified char index.
+     */
+    public static TextHitInfo leading(int charIndex) {
+        return new TextHitInfo(charIndex, false);
+    }
+
+    /**
+     * Returns a (trailing) TextHitInfo object associated with the character
+     * before the specified offset.
+     * 
+     * @param offset
+     *            the offset.
+     * @return the TextHitInfo object associated with the character before the
+     *         specified offset.
+     */
+    public static TextHitInfo beforeOffset(int offset) {
+        return new TextHitInfo(offset - 1, true);
+    }
+
+    /**
+     * Returns a (leading) TextHitInfo object associated with the character
+     * after the specified offset.
+     * 
+     * @param offset
+     *            the offset.
+     * @return the TextHitInfo object associated with the character after the
+     *         specified offset.
+     */
+    public static TextHitInfo afterOffset(int offset) {
+        return new TextHitInfo(offset, false);
+    }
+}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..cc6f0ba
--- /dev/null
+++ b/awt/java/awt/font/TextLayout.java
@@ -0,0 +1,927 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.font.BasicMetrics;
+import org.apache.harmony.awt.gl.font.CaretManager;
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TextLayout class defines the graphical representation of character data.
+ * This class provides method for obtaining information about cursor positioning
+ * and movement, split cursors for text with different directions, logical and
+ * visual highlighting, multiple baselines, hits, justification, ascent,
+ * descent, and advance, and rendering. A TextLayout object can be rendered
+ * using Graphics context.
+ * 
+ * @since Android 1.0
+ */
+public final class TextLayout implements Cloneable {
+
+    /**
+     * The CaretPolicy class provides a policy for obtaining the caret location.
+     * The single getStrongCaret method specifies the policy.
+     */
+    public static class CaretPolicy {
+
+        /**
+         * Instantiates a new CaretPolicy.
+         */
+        public CaretPolicy() {
+            // Nothing to do
+        }
+
+        /**
+         * Returns whichever of the two specified TextHitInfo objects has the
+         * stronger caret (higher character level) in the specified TextLayout.
+         * 
+         * @param hit1
+         *            the first TextHitInfo of the specified TextLayout.
+         * @param hit2
+         *            the second TextHitInfo of the specified TextLayout.
+         * @param layout
+         *            the TextLayout.
+         * @return the TextHitInfo with the stronger caret.
+         */
+        public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
+            // Stronger hit is the one with greater level.
+            // If the level is same, leading edge is stronger.
+
+            int level1 = layout.getCharacterLevel(hit1.getCharIndex());
+            int level2 = layout.getCharacterLevel(hit2.getCharIndex());
+
+            if (level1 == level2) {
+                return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
+            }
+            return level1 > level2 ? hit1 : hit2;
+        }
+
+    }
+
+    /**
+     * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
+     */
+    public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+
+    /**
+     * The breaker.
+     */
+    private TextRunBreaker breaker;
+
+    /**
+     * The metrics valid.
+     */
+    private boolean metricsValid = false;
+
+    /**
+     * The tmc.
+     */
+    private TextMetricsCalculator tmc;
+
+    /**
+     * The metrics.
+     */
+    private BasicMetrics metrics;
+
+    /**
+     * The caret manager.
+     */
+    private CaretManager caretManager;
+
+    /**
+     * The justification width.
+     */
+    float justificationWidth = -1;
+
+    /**
+     * Instantiates a new TextLayout object from the specified string and Font.
+     * 
+     * @param string
+     *            the string to be displayed.
+     * @param font
+     *            the font of the text.
+     * @param frc
+     *            the FontRenderContext object for obtaining information about a
+     *            graphics device.
+     */
+    public TextLayout(String string, Font font, FontRenderContext frc) {
+        if (string == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (font == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (string.length() == 0) {
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        AttributedString as = new AttributedString(string);
+        as.addAttribute(TextAttribute.FONT, font);
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the specified text and a map of
+     * attributes.
+     * 
+     * @param string
+     *            the string to be displayed.
+     * @param attributes
+     *            the attributes to be used for obtaining the text style.
+     * @param frc
+     *            the FontRenderContext object for obtaining information about a
+     *            graphics device.
+     */
+    public TextLayout(String string,
+            Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
+            FontRenderContext frc) {
+        if (string == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (attributes == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (string.length() == 0) {
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        AttributedString as = new AttributedString(string);
+        as.addAttributes(attributes, 0, string.length());
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the AttributedCharacterIterator.
+     * 
+     * @param text
+     *            the AttributedCharacterIterator.
+     * @param frc
+     *            the FontRenderContext object for obtaining information about a
+     *            graphics device.
+     */
+    public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
+        if (text == null) {
+            // awt.03='{0}' iterator parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (text.getBeginIndex() == text.getEndIndex()) {
+            // awt.04='{0}' iterator parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        this.breaker = new TextRunBreaker(text, frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new text layout.
+     * 
+     * @param breaker
+     *            the breaker.
+     */
+    TextLayout(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        caretManager = new CaretManager(this.breaker);
+    }
+
+    /**
+     * Returns a hash code of this TextLayout object.
+     * 
+     * @return a hash code of this TextLayout object.
+     */
+    @Override
+    public int hashCode() {
+        return breaker.hashCode();
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        TextLayout res = new TextLayout((TextRunBreaker)breaker.clone());
+
+        if (justificationWidth >= 0) {
+            res.handleJustify(justificationWidth);
+        }
+
+        return res;
+    }
+
+    /**
+     * Compares this TextLayout object to the specified TextLayout object.
+     * 
+     * @param layout
+     *            the TextLayout object to be compared.
+     * @return true, if this TextLayout object is equal to the specified
+     *         TextLayout object, false otherwise.
+     */
+    public boolean equals(TextLayout layout) {
+        if (layout == null) {
+            return false;
+        }
+        return this.breaker.equals(layout.breaker);
+    }
+
+    /**
+     * Compares this TextLayout object to the specified Object.
+     * 
+     * @param obj
+     *            the Object to be compared.
+     * @return true, if this TextLayout object is equal to the specified Object,
+     *         false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof TextLayout ? equals((TextLayout)obj) : false;
+    }
+
+    /**
+     * Gets the string representation for this TextLayout.
+     * 
+     * @return the string representation for this TextLayout.
+     */
+    @Override
+    public String toString() { // what for?
+        return super.toString();
+    }
+
+    /**
+     * Draws this TextLayout at the specified location with the specified
+     * Graphics2D context.
+     * 
+     * @param g2d
+     *            the Graphics2D object which renders this TextLayout.
+     * @param x
+     *            the X coordinate of the TextLayout origin.
+     * @param y
+     *            the Y coordinate of the TextLayout origin.
+     */
+    public void draw(Graphics2D g2d, float x, float y) {
+        updateMetrics();
+        breaker.drawSegments(g2d, x, y);
+    }
+
+    /**
+     * Update metrics.
+     */
+    private void updateMetrics() {
+        if (!metricsValid) {
+            breaker.createAllSegments();
+            tmc = new TextMetricsCalculator(breaker);
+            metrics = tmc.createMetrics();
+            metricsValid = true;
+        }
+    }
+
+    /**
+     * Gets the advance of this TextLayout object.
+     * 
+     * @return the advance of this TextLayout object.
+     */
+    public float getAdvance() {
+        updateMetrics();
+        return metrics.getAdvance();
+    }
+
+    /**
+     * Gets the ascent of this TextLayout object.
+     * 
+     * @return the ascent of this TextLayout object.
+     */
+    public float getAscent() {
+        updateMetrics();
+        return metrics.getAscent();
+    }
+
+    /**
+     * Gets the baseline of this TextLayout object.
+     * 
+     * @return the baseline of this TextLayout object.
+     */
+    public byte getBaseline() {
+        updateMetrics();
+        return (byte)metrics.getBaseLineIndex();
+    }
+
+    /**
+     * Gets the float array of offsets for the baselines which are used in this
+     * TextLayout.
+     * 
+     * @return the float array of offsets for the baselines which are used in
+     *         this TextLayout.
+     */
+    public float[] getBaselineOffsets() {
+        updateMetrics();
+        return tmc.getBaselineOffsets();
+    }
+
+    /**
+     * Gets the black box bounds of the characters in the specified area. The
+     * black box bounds is an Shape which contains all bounding boxes of all the
+     * glyphs of the characters between firstEndpoint and secondEndpoint
+     * parameters values.
+     * 
+     * @param firstEndpoint
+     *            the first point of the area.
+     * @param secondEndpoint
+     *            the second point of the area.
+     * @return the Shape which contains black box bounds.
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        if (firstEndpoint < secondEndpoint) {
+            return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+        }
+        return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
+    }
+
+    /**
+     * Gets the bounds of this TextLayout.
+     * 
+     * @return the bounds of this TextLayout.
+     */
+    public Rectangle2D getBounds() {
+        updateMetrics();
+        return breaker.getVisualBounds();
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo.
+     * 
+     * @param hitInfo
+     *            the TextHitInfo.
+     * @return the information about the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo of a
+     * character in this TextLayout.
+     * 
+     * @param hitInfo
+     *            the TextHitInfo of a character in this TextLayout.
+     * @param bounds
+     *            the bounds to which the caret info is constructed.
+     * @return the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo in
+     * the bounds of this TextLayout.
+     * 
+     * @param hitInfo
+     *            the TextHitInfo.
+     * @param bounds
+     *            the bounds to which the caret info is constructed.
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo in
+     * the bounds of this TextLayout.
+     * 
+     * @param hitInfo
+     *            the TextHitInfo.
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with default caret policy
+     * and null bounds: the first element is the strong caret, the second is the
+     * weak caret or null.
+     * 
+     * @param offset
+     *            an offset in the TextLayout.
+     * @return an array of two Shapes corresponded to the strong and weak
+     *         carets.
+     */
+    public Shape[] getCaretShapes(int offset) {
+        return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with the default caret
+     * policy: the first element is the strong caret, the second is the weak
+     * caret or null.
+     * 
+     * @param offset
+     *            an offset in the TextLayout.
+     * @param bounds
+     *            the bounds to which to extend the carets.
+     * @return an array of two Shapes corresponded to the strong and weak
+     *         carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
+        return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets: the first element is the
+     * strong caret, the second is the weak caret or null.
+     * 
+     * @param offset
+     *            an offset in the TextLayout.
+     * @param bounds
+     *            the bounds to which to extend the carets.
+     * @param policy
+     *            the specified CaretPolicy.
+     * @return an array of two Shapes corresponded to the strong and weak
+     *         carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        updateMetrics();
+        return caretManager.getCaretShapes(offset, bounds, policy, this);
+    }
+
+    /**
+     * Gets the number of characters in this TextLayout.
+     * 
+     * @return the number of characters in this TextLayout.
+     */
+    public int getCharacterCount() {
+        return breaker.getCharCount();
+    }
+
+    /**
+     * Gets the level of the character with the specified index.
+     * 
+     * @param index
+     *            the specified index of the character.
+     * @return the level of the character.
+     */
+    public byte getCharacterLevel(int index) {
+        if (index == -1 || index == getCharacterCount()) {
+            return (byte)breaker.getBaseLevel();
+        }
+        return breaker.getLevel(index);
+    }
+
+    /**
+     * Gets the descent of this TextLayout.
+     * 
+     * @return the descent of this TextLayout.
+     */
+    public float getDescent() {
+        updateMetrics();
+        return metrics.getDescent();
+    }
+
+    /**
+     * Gets the TextLayout wich is justified with the specified width related to
+     * this TextLayout.
+     * 
+     * @param justificationWidth
+     *            the width which is used for justification.
+     * @return a TextLayout justified to the specified width.
+     * @throws Error
+     *             the error occures if this TextLayout has been already
+     *             justified.
+     */
+    public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return this;
+        }
+
+        TextLayout justifiedLayout = new TextLayout((TextRunBreaker)breaker.clone());
+        justifiedLayout.handleJustify(justificationWidth);
+        return justifiedLayout;
+    }
+
+    /**
+     * Gets the leading of this TextLayout.
+     * 
+     * @return the leading of this TextLayout.
+     */
+    public float getLeading() {
+        updateMetrics();
+        return metrics.getLeading();
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen the specified
+     * endpoints and extended to the natural bounds of this TextLayout.
+     * 
+     * @param firstEndpoint
+     *            the first selected endpoint within the area of characters
+     * @param secondEndpoint
+     *            the second selected endpoint within the area of characters
+     * @return a Shape represented the logical selection betweeen the specified
+     *         endpoints.
+     */
+    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen the specified
+     * endpoints and extended to the specified bounds of this TextLayout.
+     * 
+     * @param firstEndpoint
+     *            the first selected endpoint within the area of characters
+     * @param secondEndpoint
+     *            the second selected endpoint within the area of characters
+     * @param bounds
+     *            the specified bounds of this TextLayout.
+     * @return a Shape represented the logical selection betweeen the specified
+     *         endpoints.
+     */
+    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint, Rectangle2D bounds) {
+        updateMetrics();
+
+        if (firstEndpoint > secondEndpoint) {
+            if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
+                // awt.197=Endpoints are out of range
+                throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+            }
+            return caretManager.getLogicalHighlightShape(secondEndpoint, firstEndpoint, bounds,
+                    this);
+        }
+        if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
+            // awt.197=Endpoints are out of range
+            throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+        }
+        return caretManager.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds, this);
+    }
+
+    /**
+     * Gets the logical ranges of text which corresponds to a visual selection.
+     * 
+     * @param hit1
+     *            the first endpoint of the visual range.
+     * @param hit2
+     *            the second endpoint of the visual range.
+     * @return the logical ranges of text which corresponds to a visual
+     *         selection.
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or up at the end of
+     * the line) of the specified offset.
+     * 
+     * @param offset
+     *            the offset in this TextLayout.
+     * @return the TextHitInfo for the next caret to the left (or up at the end
+     *         of the line) of the specified hit, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset) {
+        return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or up at the end of
+     * the line) of the specified hit.
+     * 
+     * @param hitInfo
+     *            the initial hit.
+     * @return the TextHitInfo for the next caret to the left (or up at the end
+     *         of the line) of the specified hit, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextLeftHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or up at the end of
+     * the line) of the specified offset, given the specified caret policy.
+     * 
+     * @param offset
+     *            the offset in this TextLayout.
+     * @param policy
+     *            the policy to be used for obtaining the strong caret.
+     * @return the TextHitInfo for the next caret to the left of the specified
+     *         offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
+
+        if (nextLeftHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or down at the end
+     * of the line) of the specified hit.
+     * 
+     * @param hitInfo
+     *            the initial hit.
+     * @return the TextHitInfo for the next caret to the right (or down at the
+     *         end of the line) of the specified hit, or null if there is no
+     *         hit.
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextRightHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or down at the end
+     * of the line) of the specified offset.
+     * 
+     * @param offset
+     *            the offset in this TextLayout.
+     * @return the TextHitInfo for the next caret to the right of the specified
+     *         offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset) {
+        return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or down at the end
+     * of the line) of the specified offset, given the specified caret policy.
+     * 
+     * @param offset
+     *            the offset in this TextLayout.
+     * @param policy
+     *            the policy to be used for obtaining the strong caret.
+     * @return the TextHitInfo for the next caret to the right of the specified
+     *         offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextRightHit = getNextRightHit(strongHit);
+
+        if (nextRightHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the outline of this TextLayout as a Shape.
+     * 
+     * @param xform
+     *            the AffineTransform to be used to transform the outline before
+     *            returning it, or null if no transformation is desired.
+     * @return the outline of this TextLayout as a Shape.
+     */
+    public Shape getOutline(AffineTransform xform) {
+        breaker.createAllSegments();
+
+        GeneralPath outline = breaker.getOutline();
+
+        if (outline != null && xform != null) {
+            outline.transform(xform);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Gets the visible advance of this TextLayout which is defined as diffence
+     * between leading (advance) and trailing whitespace.
+     * 
+     * @return the visible advance of this TextLayout.
+     */
+    public float getVisibleAdvance() {
+        updateMetrics();
+
+        // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
+        // base direction, so it is also trailing
+        // in logical representation. We use this fact.
+        int lastNonWhitespace = breaker.getLastNonWhitespace();
+
+        if (lastNonWhitespace < 0) {
+            return 0;
+        } else if (lastNonWhitespace == getCharacterCount() - 1) {
+            return getAdvance();
+        } else if (justificationWidth >= 0) { // Layout is justified
+            return justificationWidth;
+        } else {
+            breaker.pushSegments(breaker.getACI().getBeginIndex(), lastNonWhitespace
+                    + breaker.getACI().getBeginIndex() + 1);
+
+            breaker.createAllSegments();
+
+            float visAdvance = tmc.createMetrics().getAdvance();
+
+            breaker.popSegments();
+            return visAdvance;
+        }
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area based
+     * on two hit locations within the text and extends to the bounds.
+     * 
+     * @param hit1
+     *            the first text hit location.
+     * @param hit2
+     *            the second text hit location.
+     * @param bounds
+     *            the rectangle that the highlighted area should be extended or
+     *            restricted to.
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
+        return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area based
+     * on two hit locations within the text.
+     * 
+     * @param hit1
+     *            the first text hit location.
+     * @param hit2
+     *            the second text hit location.
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
+        breaker.createAllSegments();
+        return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
+    }
+
+    /**
+     * Gets the TextHitInfo for a hit on the opposite side of the specified
+     * hit's caret.
+     * 
+     * @param hitInfo
+     *            the specified TextHitInfo.
+     * @return the TextHitInfo for a hit on the opposite side of the specified
+     *         hit's caret.
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        return caretManager.getVisualOtherHit(hitInfo);
+    }
+
+    /**
+     * Justifies the text; this method should be overridden by subclasses.
+     * 
+     * @param justificationWidth
+     *            the width for justification.
+     */
+    protected void handleJustify(float justificationWidth) {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return;
+        }
+
+        float gap = (justificationWidth - getVisibleAdvance()) * justification;
+        breaker.justify(gap);
+        this.justificationWidth = justificationWidth;
+
+        // Correct metrics
+        tmc = new TextMetricsCalculator(breaker);
+        tmc.correctAdvance(metrics);
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which division
+     * point (between two characters) is corresponds to a hit (such as a mouse
+     * click) at the specified coordinates.
+     * 
+     * @param x
+     *            the X coordinate in this TextLayout.
+     * @param y
+     *            the Y coordinate in this TextLayout. TextHitInfo object
+     *            corresponding to the given coordinates within the text.
+     * @return the information about the character at the specified position.
+     */
+    public TextHitInfo hitTestChar(float x, float y) {
+        return hitTestChar(x, y, getBounds());
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which division
+     * point (between two characters) is corresponds to a hit (such as a mouse
+     * click) at the specified coordinates within the specified text rectangle.
+     * 
+     * @param x
+     *            the X coordinate in this TextLayout.
+     * @param y
+     *            the Y coordinate in this TextLayout.
+     * @param bounds
+     *            the bounds of the text area. TextHitInfo object corresponding
+     *            to the given coordinates within the text.
+     * @return the information about the character at the specified position.
+     */
+    public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
+        if (x > bounds.getMaxX()) {
+            return breaker.isLTR() ? TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo
+                    .leading(0);
+        }
+
+        if (x < bounds.getMinX()) {
+            return breaker.isLTR() ? TextHitInfo.leading(0) : TextHitInfo.trailing(breaker
+                    .getCharCount() - 1);
+        }
+
+        return breaker.hitTest(x, y);
+    }
+
+    /**
+     * Returns true if this TextLayout has a "left to right" direction.
+     * 
+     * @return true if this TextLayout has a "left to right" direction, false if
+     *         this TextLayout has a "right to left" direction.
+     */
+    public boolean isLeftToRight() {
+        return breaker.isLTR();
+    }
+
+    /**
+     * Returns true if this TextLayout is vertical, false otherwise.
+     * 
+     * @return true if this TextLayout is vertical, false if horizontal.
+     */
+    public boolean isVertical() {
+        return false;
+    }
+}
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..9741f59
--- /dev/null
+++ b/awt/java/awt/font/TextMeasurer.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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+
+/**
+ * The TextMeasurer class provides utilities for line break operations.
+ * 
+ * @since Android 1.0
+ */
+public final class TextMeasurer implements Cloneable {
+
+    /**
+     * The aci.
+     */
+    AttributedCharacterIterator aci;
+
+    /**
+     * The frc.
+     */
+    FontRenderContext frc;
+
+    /**
+     * The breaker.
+     */
+    TextRunBreaker breaker = null;
+
+    /**
+     * The tmc.
+     */
+    TextMetricsCalculator tmc = null;
+
+    /**
+     * Instantiates a new text measurer from the specified text.
+     * 
+     * @param text
+     *            the source text.
+     * @param frc
+     *            the FontRenderContext.
+     */
+    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        this.aci = text;
+        this.frc = frc;
+        breaker = new TextRunBreaker(aci, this.frc);
+        tmc = new TextMetricsCalculator(breaker);
+    }
+
+    /**
+     * Replaces the current text with the new text, inserting a break character
+     * at the specified insert position.
+     * 
+     * @param newParagraph
+     *            the new paragraph text.
+     * @param insertPos
+     *            the position in the text where the character is inserted.
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
+                - (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.insertChar(newParagraph, insertPos);
+        }
+    }
+
+    /**
+     * Replaces the current text with the new text and deletes a character at
+     * the specified position.
+     * 
+     * @param newParagraph
+     *            the paragraph text after deletion.
+     * @param deletePos
+     *            the position in the text where the character is removed.
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex())
+                - (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.deleteChar(newParagraph, deletePos);
+        }
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        return new TextMeasurer((AttributedCharacterIterator)aci.clone(), frc);
+    }
+
+    /**
+     * Returns a TextLayout of the specified character range.
+     * 
+     * @param start
+     *            the index of the first character.
+     * @param limit
+     *            the index after the last character.
+     * @return a TextLayout for the characters beginning at "start" up to "end".
+     */
+    public TextLayout getLayout(int start, int limit) {
+        breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        TextLayout layout = new TextLayout((TextRunBreaker)breaker.clone());
+
+        breaker.popSegments();
+        return layout;
+    }
+
+    /**
+     * Returns the graphical width of a line beginning at "start" parameter and
+     * including characters up to "end" parameter. "start" and "end" are
+     * absolute indices, not relative to the "start" of the paragraph.
+     * 
+     * @param start
+     *            the character index at which to start measuring.
+     * @param end
+     *            the character index at which to stop measuring.
+     * @return the graphical width of a line beginning at "start" and including
+     *         characters up to "end".
+     */
+    public float getAdvanceBetween(int start, int end) {
+        breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        float retval = tmc.createMetrics().getAdvance();
+
+        breaker.popSegments();
+        return retval;
+    }
+
+    /**
+     * Returns the index of the first character which is not fit on a line
+     * beginning at start and possible measuring up to maxAdvance in graphical
+     * width.
+     * 
+     * @param start
+     *            he character index at which to start measuring.
+     * @param maxAdvance
+     *            the graphical width in which the line must fit.
+     * @return the index after the last character that is fit on a line
+     *         beginning at start, which is not longer than maxAdvance in
+     *         graphical width.
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        breaker.createAllSegments();
+        return breaker.getLineBreakIndex(start - aci.getBeginIndex(), maxAdvance)
+                + aci.getBeginIndex();
+    }
+}
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..ff2caa2
--- /dev/null
+++ b/awt/java/awt/font/TransformAttribute.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.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TransformAttribute class is a wrapper for the AffineTransform class in
+ * order to use it as attribute.
+ * 
+ * @since Android 1.0
+ */
+public final class TransformAttribute implements Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 3356247357827709530L;
+
+    // affine transform of this TransformAttribute instance
+    /**
+     * The transform.
+     */
+    private AffineTransform fTransform;
+
+    /**
+     * Instantiates a new TransformAttribute from the specified AffineTransform.
+     * 
+     * @param transform
+     *            the AffineTransform to be wrapped.
+     */
+    public TransformAttribute(AffineTransform transform) {
+        if (transform == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        if (!transform.isIdentity()) {
+            this.fTransform = new AffineTransform(transform);
+        }
+    }
+
+    /**
+     * Gets the initial AffineTransform which is wrapped.
+     * 
+     * @return the initial AffineTransform which is wrapped.
+     */
+    public AffineTransform getTransform() {
+        if (fTransform != null) {
+            return new AffineTransform(fTransform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Checks if this transform is an identity transform.
+     * 
+     * @return true, if this transform is an identity transform, false
+     *         otherwise.
+     */
+    public boolean isIdentity() {
+        return (fTransform == null);
+    }
+
+}
diff --git a/awt/java/awt/font/package.html b/awt/java/awt/font/package.html
new file mode 100644
index 0000000..788dcc0
--- /dev/null
+++ b/awt/java/awt/font/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes to support the representation of different types of fonts for example TrueType fonts.
+    </p>
+    @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
new file mode 100644
index 0000000..8a6938c
--- /dev/null
+++ b/awt/java/awt/geom/AffineTransform.java
@@ -0,0 +1,1267 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Shape;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class AffineTransform represents a linear transformation (rotation,
+ * scaling, or shear) followed by a translation that acts on a coordinate space.
+ * It preserves collinearity of points and ratios of distances between collinear
+ * points: so if A, B, and C are on a line, then after the space has been
+ * transformed via the affine transform, the images of the three points will
+ * still be on a line, and the ratio of the distance from A to B with the
+ * distance from B to C will be the same as the corresponding ratio in the image
+ * space.
+ * 
+ * @since Android 1.0
+ */
+public class AffineTransform implements Cloneable, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 1330973210523860834L;
+
+    /**
+     * The Constant TYPE_IDENTITY.
+     */
+    public static final int TYPE_IDENTITY = 0;
+
+    /**
+     * The Constant TYPE_TRANSLATION.
+     */
+    public static final int TYPE_TRANSLATION = 1;
+
+    /**
+     * The Constant TYPE_UNIFORM_SCALE.
+     */
+    public static final int TYPE_UNIFORM_SCALE = 2;
+
+    /**
+     * The Constant TYPE_GENERAL_SCALE.
+     */
+    public static final int TYPE_GENERAL_SCALE = 4;
+
+    /**
+     * The Constant TYPE_QUADRANT_ROTATION.
+     */
+    public static final int TYPE_QUADRANT_ROTATION = 8;
+
+    /**
+     * The Constant TYPE_GENERAL_ROTATION.
+     */
+    public static final int TYPE_GENERAL_ROTATION = 16;
+
+    /**
+     * The Constant TYPE_GENERAL_TRANSFORM.
+     */
+    public static final int TYPE_GENERAL_TRANSFORM = 32;
+
+    /**
+     * The Constant TYPE_FLIP.
+     */
+    public static final int TYPE_FLIP = 64;
+
+    /**
+     * The Constant TYPE_MASK_SCALE.
+     */
+    public static final int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
+
+    /**
+     * The Constant TYPE_MASK_ROTATION.
+     */
+    public static final int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
+
+    /**
+     * The <code>TYPE_UNKNOWN</code> is an initial type value.
+     */
+    static final int TYPE_UNKNOWN = -1;
+
+    /**
+     * The min value equivalent to zero. If absolute value less then ZERO it
+     * considered as zero.
+     */
+    static final double ZERO = 1E-10;
+
+    /**
+     * The values of transformation matrix.
+     */
+    double m00;
+
+    /**
+     * The m10.
+     */
+    double m10;
+
+    /**
+     * The m01.
+     */
+    double m01;
+
+    /**
+     * The m11.
+     */
+    double m11;
+
+    /**
+     * The m02.
+     */
+    double m02;
+
+    /**
+     * The m12.
+     */
+    double m12;
+
+    /**
+     * The transformation <code>type</code>.
+     */
+    transient int type;
+
+    /**
+     * Instantiates a new affine transform of type <code>TYPE_IDENTITY</code>
+     * (which leaves coordinates unchanged).
+     */
+    public AffineTransform() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Instantiates a new affine transform that has the same data as the given
+     * AffineTransform.
+     * 
+     * @param t
+     *            the transform to copy.
+     */
+    public AffineTransform(AffineTransform t) {
+        this.type = t.type;
+        this.m00 = t.m00;
+        this.m10 = t.m10;
+        this.m01 = t.m01;
+        this.m11 = t.m11;
+        this.m02 = t.m02;
+        this.m12 = t.m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as floats. The type is set to the default type:
+     * <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00
+     *            the m00 entry in the transformation matrix.
+     * @param m10
+     *            the m10 entry in the transformation matrix.
+     * @param m01
+     *            the m01 entry in the transformation matrix.
+     * @param m11
+     *            the m11 entry in the transformation matrix.
+     * @param m02
+     *            the m02 entry in the transformation matrix.
+     * @param m12
+     *            the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as doubles. The type is set to the default type:
+     * <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00
+     *            the m00 entry in the transformation matrix.
+     * @param m10
+     *            the m10 entry in the transformation matrix.
+     * @param m01
+     *            the m01 entry in the transformation matrix.
+     * @param m11
+     *            the m11 entry in the transformation matrix.
+     * @param m02
+     *            the m02 entry in the transformation matrix.
+     * @param m12
+     *            the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the
+     * transformation matrix from an array of floats. The mapping from the array
+     * to the matrix starts with <code>matrix[0]</code> giving the top-left
+     * entry of the matrix and proceeds with the usual left-to-right and
+     * top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the last row
+     * of the transformation matrix default to zero.
+     * 
+     * @param matrix
+     *            the array of four or six floats giving the values of the
+     *            matrix.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of the array is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(float[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the
+     * transformation matrix from an array of doubles. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the
+     * top-left entry of the matrix and proceeds with the usual left-to-right
+     * and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the last row
+     * of the transformation matrix default to zero.
+     * 
+     * @param matrix
+     *            the array of four or six doubles giving the values of the
+     *            matrix.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of the array is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(double[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+    /**
+     * Returns type of the affine transformation.
+     * <p>
+     * The type is computed as follows: Label the entries of the transformation
+     * matrix as three rows (m00, m01), (m10, m11), and (m02, m12). Then if the
+     * original basis vectors are (1, 0) and (0, 1), the new basis vectors after
+     * transformation are given by (m00, m01) and (m10, m11), and the
+     * translation vector is (m02, m12).
+     * <p>
+     * The types are classified as follows: <br/> TYPE_IDENTITY - no change<br/>
+     * TYPE_TRANSLATION - The translation vector isn't zero<br/>
+     * TYPE_UNIFORM_SCALE - The new basis vectors have equal length<br/>
+     * TYPE_GENERAL_SCALE - The new basis vectors dont' have equal length<br/>
+     * TYPE_FLIP - The new basis vector orientation differs from the original
+     * one<br/> TYPE_QUADRANT_ROTATION - The new basis is a rotation of the
+     * original by 90, 180, 270, or 360 degrees<br/> TYPE_GENERAL_ROTATION - The
+     * new basis is a rotation of the original by an arbitrary angle<br/>
+     * TYPE_GENERAL_TRANSFORM - The transformation can't be inverted.<br/>
+     * <p>
+     * Note that multiple types are possible, thus the types can be combined
+     * using bitwise combinations.
+     * 
+     * @return the type of the Affine Transform.
+     */
+    public int getType() {
+        if (type != TYPE_UNKNOWN) {
+            return type;
+        }
+
+        int type = 0;
+
+        if (m00 * m01 + m10 * m11 != 0.0) {
+            type |= TYPE_GENERAL_TRANSFORM;
+            return type;
+        }
+
+        if (m02 != 0.0 || m12 != 0.0) {
+            type |= TYPE_TRANSLATION;
+        } else if (m00 == 1.0 && m11 == 1.0 && m01 == 0.0 && m10 == 0.0) {
+            type = TYPE_IDENTITY;
+            return type;
+        }
+
+        if (m00 * m11 - m01 * m10 < 0.0) {
+            type |= TYPE_FLIP;
+        }
+
+        double dx = m00 * m00 + m10 * m10;
+        double dy = m01 * m01 + m11 * m11;
+        if (dx != dy) {
+            type |= TYPE_GENERAL_SCALE;
+        } else if (dx != 1.0) {
+            type |= TYPE_UNIFORM_SCALE;
+        }
+
+        if ((m00 == 0.0 && m11 == 0.0) || (m10 == 0.0 && m01 == 0.0 && (m00 < 0.0 || m11 < 0.0))) {
+            type |= TYPE_QUADRANT_ROTATION;
+        } else if (m01 != 0.0 || m10 != 0.0) {
+            type |= TYPE_GENERAL_ROTATION;
+        }
+
+        return type;
+    }
+
+    /**
+     * Gets the scale x entry of the transformation matrix (the upper left
+     * matrix entry).
+     * 
+     * @return the scale x value.
+     */
+    public double getScaleX() {
+        return m00;
+    }
+
+    /**
+     * Gets the scale y entry of the transformation matrix (the lower right
+     * entry of the linear transformation).
+     * 
+     * @return the scale y value.
+     */
+    public double getScaleY() {
+        return m11;
+    }
+
+    /**
+     * Gets the shear x entry of the transformation matrix (the upper right
+     * entry of the linear transformation).
+     * 
+     * @return the shear x value.
+     */
+    public double getShearX() {
+        return m01;
+    }
+
+    /**
+     * Gets the shear y entry of the transformation matrix (the lower left entry
+     * of the linear transformation).
+     * 
+     * @return the shear y value.
+     */
+    public double getShearY() {
+        return m10;
+    }
+
+    /**
+     * Gets the x coordinate of the translation vector.
+     * 
+     * @return the x coordinate of the translation vector.
+     */
+    public double getTranslateX() {
+        return m02;
+    }
+
+    /**
+     * Gets the y coordinate of the translation vector.
+     * 
+     * @return the y coordinate of the translation vector.
+     */
+    public double getTranslateY() {
+        return m12;
+    }
+
+    /**
+     * Checks if the AffineTransformation is the identity.
+     * 
+     * @return true, if the AffineTransformation is the identity.
+     */
+    public boolean isIdentity() {
+        return getType() == TYPE_IDENTITY;
+    }
+
+    /**
+     * Writes the values of the transformation matrix into the given array of
+     * doubles. If the array has length 4, only the linear transformation part
+     * will be written into it. If it has length greater than 4, the translation
+     * vector will be included as well.
+     * 
+     * @param matrix
+     *            the array to fill with the values of the matrix.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of the array is 0, 1, 2, 3, or 5.
+     */
+    public void getMatrix(double[] matrix) {
+        matrix[0] = m00;
+        matrix[1] = m10;
+        matrix[2] = m01;
+        matrix[3] = m11;
+        if (matrix.length > 4) {
+            matrix[4] = m02;
+            matrix[5] = m12;
+        }
+    }
+
+    /**
+     * Gets the determinant of the linear transformation matrix.
+     * 
+     * @return the determinant of the linear transformation matrix.
+     */
+    public double getDeterminant() {
+        return m00 * m11 - m01 * m10;
+    }
+
+    /**
+     * Sets the transform in terms of a list of double values.
+     * 
+     * @param m00
+     *            the m00 coordinate of the transformation matrix.
+     * @param m10
+     *            the m10 coordinate of the transformation matrix.
+     * @param m01
+     *            the m01 coordinate of the transformation matrix.
+     * @param m11
+     *            the m11 coordinate of the transformation matrix.
+     * @param m02
+     *            the m02 coordinate of the transformation matrix.
+     * @param m12
+     *            the m12 coordinate of the transformation matrix.
+     */
+    public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Sets the transform's data to match the data of the transform sent as a
+     * parameter.
+     * 
+     * @param t
+     *            the transform that gives the new values.
+     */
+    public void setTransform(AffineTransform t) {
+        type = t.type;
+        setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12);
+    }
+
+    /**
+     * Sets the transform to the identity transform.
+     */
+    public void setToIdentity() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Sets the transformation to a translation alone. Sets the linear part of
+     * the transformation to identity and the translation vector to the values
+     * sent as parameters. Sets the type to <code>TYPE_IDENTITY</code> if the
+     * resulting AffineTransformation is the identity transformation, otherwise
+     * sets it to <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx
+     *            the distance to translate in the x direction.
+     * @param my
+     *            the distance to translate in the y direction.
+     */
+    public void setToTranslation(double mx, double my) {
+        m00 = m11 = 1.0;
+        m01 = m10 = 0.0;
+        m02 = mx;
+        m12 = my;
+        if (mx == 0.0 && my == 0.0) {
+            type = TYPE_IDENTITY;
+        } else {
+            type = TYPE_TRANSLATION;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a scale alone, eliminating rotation,
+     * shear, and translation elements. Sets the type to
+     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
+     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx
+     *            the scaling factor in the x direction.
+     * @param scy
+     *            the scaling factor in the y direction.
+     */
+    public void setToScale(double scx, double scy) {
+        m00 = scx;
+        m11 = scy;
+        m10 = m01 = m02 = m12 = 0.0;
+        if (scx != 1.0 || scy != 1.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a shear alone, eliminating rotation,
+     * scaling, and translation elements. Sets the type to
+     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
+     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx
+     *            the shearing factor in the x direction.
+     * @param shy
+     *            the shearing factor in the y direction.
+     */
+    public void setToShear(double shx, double shy) {
+        m00 = m11 = 1.0;
+        m02 = m12 = 0.0;
+        m01 = shx;
+        m10 = shy;
+        if (shx != 0.0 || shy != 0.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a rotation alone, eliminating shearing,
+     * scaling, and translation elements. Sets the type to
+     * <code>TYPE_IDENTITY</code> if the resulting AffineTransformation is the
+     * identity transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     */
+    public void setToRotation(double angle) {
+        double sin = Math.sin(angle);
+        double cos = Math.cos(angle);
+        if (Math.abs(cos) < ZERO) {
+            cos = 0.0;
+            sin = sin > 0.0 ? 1.0 : -1.0;
+        } else if (Math.abs(sin) < ZERO) {
+            sin = 0.0;
+            cos = cos > 0.0 ? 1.0 : -1.0;
+        }
+        m00 = m11 = cos;
+        m01 = -sin;
+        m10 = sin;
+        m02 = m12 = 0.0;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Sets the transformation to being a rotation followed by a translation.
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     * @param px
+     *            the distance to translate in the x direction.
+     * @param py
+     *            the distance to translate in the y direction.
+     */
+    public void setToRotation(double angle, double px, double py) {
+        setToRotation(angle);
+        m02 = px * (1.0 - m00) + py * m10;
+        m12 = py * (1.0 - m00) - px * m10;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a translation alone with the
+     * translation vector given by the values sent as parameters. The new
+     * transformation's type is <code>TYPE_IDENTITY</code> if the
+     * AffineTransformation is the identity transformation, otherwise it's
+     * <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx
+     *            the distance to translate in the x direction.
+     * @param my
+     *            the distance to translate in the y direction.
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getTranslateInstance(double mx, double my) {
+        AffineTransform t = new AffineTransform();
+        t.setToTranslation(mx, my);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a scale alone. The new
+     * transformation's type is <code>TYPE_IDENTITY</code> if the
+     * AffineTransformation is the identity transformation, otherwise it's
+     * <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx
+     *            the scaling factor in the x direction.
+     * @param scY
+     *            the scaling factor in the y direction.
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getScaleInstance(double scx, double scY) {
+        AffineTransform t = new AffineTransform();
+        t.setToScale(scx, scY);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a shear alone. The new
+     * transformation's type is <code>TYPE_IDENTITY</code> if the
+     * AffineTransformation is the identity transformation, otherwise it's
+     * <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx
+     *            the shearing factor in the x direction.
+     * @param shy
+     *            the shearing factor in the y direction.
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getShearInstance(double shx, double shy) {
+        AffineTransform m = new AffineTransform();
+        m.setToShear(shx, shy);
+        return m;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation alone. The new
+     * transformation's type is <code>TYPE_IDENTITY</code> if the
+     * AffineTransformation is the identity transformation, otherwise it's
+     * <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation followed by a
+     * translation. Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     * @param x
+     *            the distance to translate in the x direction.
+     * @param y
+     *            the distance to translate in the y direction.
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle, double x, double y) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle, x, y);
+        return t;
+    }
+
+    /**
+     * Applies a translation to this AffineTransformation.
+     * 
+     * @param mx
+     *            the distance to translate in the x direction.
+     * @param my
+     *            the distance to translate in the y direction.
+     */
+    public void translate(double mx, double my) {
+        concatenate(AffineTransform.getTranslateInstance(mx, my));
+    }
+
+    /**
+     * Applies a scaling transformation to this AffineTransformation.
+     * 
+     * @param scx
+     *            the scaling factor in the x direction.
+     * @param scy
+     *            the scaling factor in the y direction.
+     */
+    public void scale(double scx, double scy) {
+        concatenate(AffineTransform.getScaleInstance(scx, scy));
+    }
+
+    /**
+     * Applies a shearing transformation to this AffineTransformation.
+     * 
+     * @param shx
+     *            the shearing factor in the x direction.
+     * @param shy
+     *            the shearing factor in the y direction.
+     */
+    public void shear(double shx, double shy) {
+        concatenate(AffineTransform.getShearInstance(shx, shy));
+    }
+
+    /**
+     * Applies a rotation transformation to this AffineTransformation.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     */
+    public void rotate(double angle) {
+        concatenate(AffineTransform.getRotateInstance(angle));
+    }
+
+    /**
+     * Applies a rotation and translation transformation to this
+     * AffineTransformation.
+     * 
+     * @param angle
+     *            the angle of rotation in radians.
+     * @param px
+     *            the distance to translate in the x direction.
+     * @param py
+     *            the distance to translate in the y direction.
+     */
+    public void rotate(double angle, double px, double py) {
+        concatenate(AffineTransform.getRotateInstance(angle, px, py));
+    }
+
+    /**
+     * Multiplies the matrix representations of two AffineTransform objects.
+     * 
+     * @param t1
+     *            - the AffineTransform object is a multiplicand
+     * @param t2
+     *            - the AffineTransform object is a multiplier
+     * @return an AffineTransform object that is the result of t1 multiplied by
+     *         the matrix t2.
+     */
+    AffineTransform multiply(AffineTransform t1, AffineTransform t2) {
+        return new AffineTransform(t1.m00 * t2.m00 + t1.m10 * t2.m01, // m00
+                t1.m00 * t2.m10 + t1.m10 * t2.m11, // m01
+                t1.m01 * t2.m00 + t1.m11 * t2.m01, // m10
+                t1.m01 * t2.m10 + t1.m11 * t2.m11, // m11
+                t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02
+                t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12
+    }
+
+    /**
+     * Applies the given AffineTransform to this AffineTransform via matrix
+     * multiplication.
+     * 
+     * @param t
+     *            the AffineTransform to apply to this AffineTransform.
+     */
+    public void concatenate(AffineTransform t) {
+        setTransform(multiply(t, this));
+    }
+
+    /**
+     * Changes the current AffineTransform the one obtained by taking the
+     * transform t and applying this AffineTransform to it.
+     * 
+     * @param t
+     *            the AffineTransform that this AffineTransform is multiplied
+     *            by.
+     */
+    public void preConcatenate(AffineTransform t) {
+        setTransform(multiply(this, t));
+    }
+
+    /**
+     * Creates an AffineTransform that is the inverse of this transform.
+     * 
+     * @return the affine transform that is the inverse of this AffineTransform.
+     * @throws NoninvertibleTransformException
+     *             if this AffineTransform cannot be inverted (the determinant
+     *             of the linear transformation part is zero).
+     */
+    public AffineTransform createInverse() throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+        return new AffineTransform(m11 / det, // m00
+                -m10 / det, // m10
+                -m01 / det, // m01
+                m00 / det, // m11
+                (m01 * m12 - m11 * m02) / det, // m02
+                (m10 * m02 - m00 * m12) / det // m12
+        );
+    }
+
+    /**
+     * Apply the current AffineTransform to the point.
+     * 
+     * @param src
+     *            the original point.
+     * @param dst
+     *            Point2D object to be filled with the destination coordinates
+     *            (where the original point is sent by this AffineTransform).
+     *            May be null.
+     * @return the point in the AffineTransform's image space where the original
+     *         point is sent.
+     */
+    public Point2D transform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+        return dst;
+    }
+
+    /**
+     * Applies this AffineTransform to an array of points.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length > src.length</code> or
+     *             <code>dstOff + length > dst.length</code>.
+     */
+    public void transform(Point2D[] src, int srcOff, Point2D[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            Point2D srcPoint = src[srcOff++];
+            double x = srcPoint.getX();
+            double y = srcPoint.getY();
+            Point2D dstPoint = dst[dstOff];
+            if (dstPoint == null) {
+                if (srcPoint instanceof Point2D.Double) {
+                    dstPoint = new Point2D.Double();
+                } else {
+                    dstPoint = new Point2D.Float();
+                }
+            }
+            dstPoint.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+            dst[dstOff++] = dstPoint;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given as an array of
+     * double values where every two values in the array give the coordinates of
+     * a point; the even-indexed values giving the x coordinates and the
+     * odd-indexed values giving the y coordinates.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            double x = src[srcOff + 0];
+            double y = src[srcOff + 1];
+            dst[dstOff + 0] = x * m00 + y * m01 + m02;
+            dst[dstOff + 1] = x * m10 + y * m11 + m12;
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given as an array of
+     * float values where every two values in the array give the coordinates of
+     * a point; the even-indexed values giving the x coordinates and the
+     * odd-indexed values giving the y coordinates.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            float x = src[srcOff + 0];
+            float y = src[srcOff + 1];
+            dst[dstOff + 0] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff + 1] = (float)(x * m10 + y * m11 + m12);
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given as an array of
+     * float values where every two values in the array give the coordinates of
+     * a point; the even-indexed values giving the x coordinates and the
+     * odd-indexed values giving the y coordinates. The destination coordinates
+     * are given as values of type <code>double</code>.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            float x = src[srcOff++];
+            float y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01 + m02;
+            dst[dstOff++] = x * m10 + y * m11 + m12;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given as an array of
+     * double values where every two values in the array give the coordinates of
+     * a point; the even-indexed values giving the x coordinates and the
+     * odd-indexed values giving the y coordinates. The destination coordinates
+     * are given as values of type <code>float</code>.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(double[] src, int srcOff, float[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff++] = (float)(x * m10 + y * m11 + m12);
+        }
+    }
+
+    /**
+     * Transforms the point according to the linear transformation part of this
+     * AffineTransformation (without applying the translation).
+     * 
+     * @param src
+     *            the original point.
+     * @param dst
+     *            the point object where the result of the delta transform is
+     *            written.
+     * @return the result of applying the delta transform (linear part only) to
+     *         the original point.
+     */
+    // TODO: is this right? if dst is null, we check what it's an
+    // instance of? Shouldn't it be src instanceof Point2D.Double?
+    public Point2D deltaTransform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (dst instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
+        return dst;
+    }
+
+    /**
+     * Applies the linear transformation part of this AffineTransform (ignoring
+     * the translation part) to a set of points given as an array of double
+     * values where every two values in the array give the coordinates of a
+     * point; the even-indexed values giving the x coordinates and the
+     * odd-indexed values giving the y coordinates.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the delta transformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void deltaTransform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01;
+            dst[dstOff++] = x * m10 + y * m11;
+        }
+    }
+
+    /**
+     * Transforms the point according to the inverse of this
+     * AffineTransformation.
+     * 
+     * @param src
+     *            the original point.
+     * @param dst
+     *            the point object where the result of the inverse transform is
+     *            written (may be null).
+     * @return the result of applying the inverse transform. Inverse transform.
+     * @throws NoninvertibleTransformException
+     *             if this AffineTransform cannot be inverted (the determinant
+     *             of the linear transformation part is zero).
+     */
+    public Point2D inverseTransform(Point2D src, Point2D dst)
+            throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX() - m02;
+        double y = src.getY() - m12;
+
+        dst.setLocation((x * m11 - y * m01) / det, (y * m00 - x * m10) / det);
+        return dst;
+    }
+
+    /**
+     * Applies the inverse of this AffineTransform to a set of points given as
+     * an array of double values where every two values in the array give the
+     * coordinates of a point; the even-indexed values giving the x coordinates
+     * and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src
+     *            the array of points to be transformed.
+     * @param srcOff
+     *            the offset in the source point array of the first point to be
+     *            transformed.
+     * @param dst
+     *            the point array where the images of the points (after applying
+     *            the inverse of the AffineTransformation) should be placed.
+     * @param dstOff
+     *            the offset in the destination array where the new values
+     *            should be written.
+     * @param length
+     *            the number of points to transform.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if <code>srcOff + length*2 > src.length</code> or
+     *             <code>dstOff + length*2 > dst.length</code>.
+     * @throws NoninvertibleTransformException
+     *             if this AffineTransform cannot be inverted (the determinant
+     *             of the linear transformation part is zero).
+     */
+    public void inverseTransform(double[] src, int srcOff, double[] dst, int dstOff, int length)
+            throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        while (--length >= 0) {
+            double x = src[srcOff++] - m02;
+            double y = src[srcOff++] - m12;
+            dst[dstOff++] = (x * m11 - y * m01) / det;
+            dst[dstOff++] = (y * m00 - x * m10) / det;
+        }
+    }
+
+    /**
+     * Creates a new shape whose data is given by applying this AffineTransform
+     * to the specified shape.
+     * 
+     * @param src
+     *            the original shape whose data is to be transformed.
+     * @return the new shape found by applying this AffineTransform to the
+     *         original shape.
+     */
+    public Shape createTransformedShape(Shape src) {
+        if (src == null) {
+            return null;
+        }
+        if (src instanceof GeneralPath) {
+            return ((GeneralPath)src).createTransformedShape(this);
+        }
+        PathIterator path = src.getPathIterator(this);
+        GeneralPath dst = new GeneralPath(path.getWindingRule());
+        dst.append(path, false);
+        return dst;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName() + "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                + m10 + ", " + m11 + ", " + m12 + "]]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(m00);
+        hash.append(m01);
+        hash.append(m02);
+        hash.append(m10);
+        hash.append(m11);
+        hash.append(m12);
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof AffineTransform) {
+            AffineTransform t = (AffineTransform)obj;
+            return m00 == t.m00 && m01 == t.m01 && m02 == t.m02 && m10 == t.m10 && m11 == t.m11
+                    && m12 == t.m12;
+        }
+        return false;
+    }
+
+    /**
+     * Writes the AffineTrassform object to the output steam.
+     * 
+     * @param stream
+     *            - the output stream.
+     * @throws IOException
+     *             - if there are I/O errors while writing to the output stream.
+     */
+    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+    }
+
+    /**
+     * Read the AffineTransform object from the input stream.
+     * 
+     * @param stream
+     *            - the input stream.
+     * @throws IOException
+     *             - if there are I/O errors while reading from the input
+     *             stream.
+     * @throws ClassNotFoundException
+     *             - if class could not be found.
+     */
+    private void readObject(java.io.ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+        stream.defaultReadObject();
+        type = TYPE_UNKNOWN;
+    }
+
+}
diff --git a/awt/java/awt/geom/Arc2D.java b/awt/java/awt/geom/Arc2D.java
new file mode 100644
index 0000000..56f5cd3
--- /dev/null
+++ b/awt/java/awt/geom/Arc2D.java
@@ -0,0 +1,1157 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Arc2D represents a segment of a curve inscribed in a rectangle. The
+ * curve is defined by a start angle and an extent angle (the end angle minus
+ * the start angle) as a pie wedge whose point is in the center of the
+ * rectangle. The Arc2D as a shape may be either OPEN (including nothing but the
+ * curved arc segment itself), CHORD (the curved arc segment closed by a
+ * connecting segment from the end to the beginning of the arc, or PIE (the
+ * segments from the end of the arc to the center of the rectangle and from the
+ * center of the rectangle back to the arc's start point are included).
+ * 
+ * @since Android 1.0
+ */
+public abstract class Arc2D extends RectangularShape {
+
+    /**
+     * The arc type OPEN indicates that the shape includes only the curved arc
+     * segment.
+     */
+    public final static int OPEN = 0;
+
+    /**
+     * The arc type CHORD indicates that as a shape the connecting segment from
+     * the end point of the curved arc to the beginning point is included.
+     */
+    public final static int CHORD = 1;
+
+    /**
+     * The arc type PIE indicates that as a shape the two segments from the
+     * arc's endpoint to the center of the rectangle and from the center of the
+     * rectangle to the arc's endpoint are included.
+     */
+    public final static int PIE = 2;
+
+    /**
+     * The Class Float is a subclass of Arc2D in which all of the data values
+     * are given as floats.
+     * 
+     * @see Arc2D.Double
+     * @since Android 1.0
+     */
+    public static class Float extends Arc2D {
+
+        /**
+         * The x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         */
+        public float x;
+
+        /**
+         * The y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         */
+        public float y;
+
+        /**
+         * The width of the rectangle that contains the arc.
+         */
+        public float width;
+
+        /**
+         * The height of the rectangle that contains the arc.
+         */
+        public float height;
+
+        /**
+         * The start angle of the arc in degrees.
+         */
+        public float start;
+
+        /**
+         * The width angle of the arc in degrees.
+         */
+        public float extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with float values.
+         */
+        public Float() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with float values.
+         * 
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified float-valued data.
+         * 
+         * @param x
+         *            the x coordinate of the upper left corner of the rectangle
+         *            that contains the arc.
+         * @param y
+         *            the y coordinate of the upper left corner of the rectangle
+         *            that contains the arc.
+         * @param width
+         *            the width of the rectangle that contains the arc.
+         * @param height
+         *            the height of the rectangle that contains the arc.
+         * @param start
+         *            the start angle of the arc in degrees.
+         * @param extent
+         *            the width angle of the arc in degrees.
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(float x, float y, float width, float height, float start, float extent,
+                int type) {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data and
+         * the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds
+         *            the bounding rectangle of the Angle2D.
+         * @param start
+         *            the start angle of the arc in degrees.
+         * @param extent
+         *            the width angle of the arc in degrees.
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(Rectangle2D bounds, float start, float extent, int type) {
+            super(type);
+            this.x = (float)bounds.getX();
+            this.y = (float)bounds.getY();
+            this.width = (float)bounds.getWidth();
+            this.height = (float)bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height, double start,
+                double extent, int type) {
+            this.setArcType(type);
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.start = (float)start;
+            this.extent = (float)extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = (float)start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = (float)extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Float((float)x, (float)y, (float)width, (float)height);
+        }
+
+    }
+
+    /**
+     * The Class Double is a subclass of Arc2D in which all of the data values
+     * are given as doubles.
+     * 
+     * @see Arc2D.Float
+     * @since Android 1.0
+     */
+    public static class Double extends Arc2D {
+
+        /**
+         * The x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         */
+        public double x;
+
+        /**
+         * The y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         */
+        public double y;
+
+        /**
+         * The width of the rectangle that contains the arc.
+         */
+        public double width;
+
+        /**
+         * The height of the rectangle that contains the arc.
+         */
+        public double height;
+
+        /**
+         * The start angle of the arc in degrees.
+         */
+        public double start;
+
+        /**
+         * The width angle of the arc in degrees.
+         */
+        public double extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with double values.
+         */
+        public Double() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with double values.
+         * 
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified double-valued data.
+         * 
+         * @param x
+         *            the x coordinate of the upper left corner of the rectangle
+         *            that contains the arc.
+         * @param y
+         *            the y coordinate of the upper left corner of the rectangle
+         *            that contains the arc.
+         * @param width
+         *            the width of the rectangle that contains the arc.
+         * @param height
+         *            the height of the rectangle that contains the arc.
+         * @param start
+         *            the start angle of the arc in degrees.
+         * @param extent
+         *            the width angle of the arc in degrees.
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(double x, double y, double width, double height, double start, double extent,
+                int type) {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data and
+         * the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds
+         *            the bounding rectangle of the Angle2D.
+         * @param start
+         *            the start angle of the arc in degrees.
+         * @param extent
+         *            the width angle of the arc in degrees.
+         * @param type
+         *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+         *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(Rectangle2D bounds, double start, double extent, int type) {
+            super(type);
+            this.x = bounds.getX();
+            this.y = bounds.getY();
+            this.width = bounds.getWidth();
+            this.height = bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height, double start,
+                double extent, int type) {
+            this.setArcType(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * The Class Iterator is the subclass of PathIterator that is used to
+     * traverse the boundary of a shape of type Arc2D.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The x coordinate of the center of the arc's bounding rectangle.
+         */
+        double x;
+
+        /**
+         * The y coordinate of the center of the arc's bounding rectangle.
+         */
+        double y;
+
+        /**
+         * Half of the width of the arc's bounding rectangle (the radius in the
+         * case of a circular arc).
+         */
+        double width;
+
+        /**
+         * Half of the height of the arc's bounding rectangle (the radius in the
+         * case of a circular arc).
+         */
+        double height;
+
+        /**
+         * The start angle of the arc in degrees.
+         */
+        double angle;
+
+        /**
+         * The angle extent in degrees.
+         */
+        double extent;
+
+        /**
+         * The closure type of the arc.
+         */
+        int type;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * The number of arc segments the source arc subdivided to be
+         * approximated by Bezier curves. Depends on extent value.
+         */
+        int arcCount;
+
+        /**
+         * The number of line segments. Depends on closure type.
+         */
+        int lineCount;
+
+        /**
+         * The step to calculate next arc subdivision point.
+         */
+        double step;
+
+        /**
+         * The temporary value of cosinus of the current angle.
+         */
+        double cos;
+
+        /**
+         * The temporary value of sinus of the current angle.
+         */
+        double sin;
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        double k;
+
+        /**
+         * The temporary value of x coordinate of the Bezier curve control
+         * vector.
+         */
+        double kx;
+
+        /**
+         * The temporary value of y coordinate of the Bezier curve control
+         * vector.
+         */
+        double ky;
+
+        /**
+         * The x coordinate of the first path point (MOVE_TO).
+         */
+        double mx;
+
+        /**
+         * The y coordinate of the first path point (MOVE_TO).
+         */
+        double my;
+
+        /**
+         * Constructs a new Arc2D.Iterator for given line and transformation
+         * 
+         * @param a
+         *            the source Arc2D object.
+         * @param t
+         *            the AffineTransformation.
+         */
+        Iterator(Arc2D a, AffineTransform t) {
+            if (width < 0 || height < 0) {
+                arcCount = 0;
+                lineCount = 0;
+                index = 1;
+                return;
+            }
+
+            this.width = a.getWidth() / 2.0;
+            this.height = a.getHeight() / 2.0;
+            this.x = a.getX() + width;
+            this.y = a.getY() + height;
+            this.angle = -Math.toRadians(a.getAngleStart());
+            this.extent = -a.getAngleExtent();
+            this.type = a.getArcType();
+            this.t = t;
+
+            if (Math.abs(extent) >= 360.0) {
+                arcCount = 4;
+                k = 4.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+                step = Math.PI / 2.0;
+                if (extent < 0.0) {
+                    step = -step;
+                    k = -k;
+                }
+            } else {
+                arcCount = (int)Math.rint(Math.abs(extent) / 90.0);
+                step = Math.toRadians(extent / arcCount);
+                k = 4.0 / 3.0 * (1.0 - Math.cos(step / 2.0)) / Math.sin(step / 2.0);
+            }
+
+            lineCount = 0;
+            if (type == Arc2D.CHORD) {
+                lineCount++;
+            } else if (type == Arc2D.PIE) {
+                lineCount += 2;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > arcCount + lineCount;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = mx = x + cos * width;
+                coords[1] = my = y + sin * height;
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = mx - kx;
+                coords[1] = my + ky;
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = mx = x + cos * width;
+                coords[5] = my = y + sin * height;
+                coords[2] = mx + kx;
+                coords[3] = my - ky;
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = x;
+                coords[1] = y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = (float)(mx = x + cos * width);
+                coords[1] = (float)(my = y + sin * height);
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = (float)(mx - kx);
+                coords[1] = (float)(my + ky);
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = (float)(mx = x + cos * width);
+                coords[5] = (float)(my = y + sin * height);
+                coords[2] = (float)(mx + kx);
+                coords[3] = (float)(my - ky);
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * The closure type of the arc.
+     */
+    private int type;
+
+    /**
+     * Instantiates a new arc2D.
+     * 
+     * @param type
+     *            the closure type.
+     */
+    protected Arc2D(int type) {
+        setArcType(type);
+    }
+
+    /**
+     * Takes the double-valued data and creates the corresponding Rectangle2D
+     * object with values either of type float or of type double depending on
+     * whether this Arc2D instance is of type Float or Double.
+     * 
+     * @param x
+     *            the x coordinate of the upper left corner of the bounding
+     *            rectangle.
+     * @param y
+     *            the y coordinate of the upper left corner of the bounding
+     *            rectangle.
+     * @param width
+     *            the width of the bounding rectangle.
+     * @param height
+     *            the height of the bounding rectangle.
+     * @return the corresponding Rectangle2D object.
+     */
+    protected abstract Rectangle2D makeBounds(double x, double y, double width, double height);
+
+    /**
+     * Gets the start angle.
+     * 
+     * @return the start angle.
+     */
+    public abstract double getAngleStart();
+
+    /**
+     * Gets the width angle.
+     * 
+     * @return the width angle.
+     */
+    public abstract double getAngleExtent();
+
+    /**
+     * Sets the start angle.
+     * 
+     * @param start
+     *            the new start angle.
+     */
+    public abstract void setAngleStart(double start);
+
+    /**
+     * Sets the width angle.
+     * 
+     * @param extent
+     *            the new width angle.
+     */
+    public abstract void setAngleExtent(double extent);
+
+    /**
+     * Sets the data values that define the arc.
+     * 
+     * @param x
+     *            the x coordinate of the upper left corner of the rectangle
+     *            that contains the arc.
+     * @param y
+     *            the y coordinate of the upper left corner of the rectangle
+     *            that contains the arc.
+     * @param width
+     *            the width of the rectangle that contains the arc.
+     * @param height
+     *            the height of the rectangle that contains the arc.
+     * @param start
+     *            the start angle of the arc in degrees.
+     * @param extent
+     *            the width angle of the arc in degrees.
+     * @param type
+     *            the type of the new Arc2D, either {@link Arc2D#OPEN},
+     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public abstract void setArc(double x, double y, double width, double height, double start,
+            double extent, int type);
+
+    /**
+     * Gets the arc type, either {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, or
+     * {@link Arc2D#PIE}.
+     * 
+     * @return the arc type.
+     */
+    public int getArcType() {
+        return type;
+    }
+
+    /**
+     * Sets the arc type, either {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, or
+     * {@link Arc2D#PIE}.
+     * 
+     * @param type
+     *            the new arc type.
+     */
+    public void setArcType(int type) {
+        if (type != OPEN && type != CHORD && type != PIE) {
+            // awt.205=Invalid type of Arc: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.205", type)); //$NON-NLS-1$
+        }
+        this.type = type;
+    }
+
+    /**
+     * Gets the start point of the arc as a Point2D.
+     * 
+     * @return the start point of the curved arc segment.
+     */
+    public Point2D getStartPoint() {
+        double a = Math.toRadians(getAngleStart());
+        return new Point2D.Double(getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0, getY()
+                + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    /**
+     * Gets the end point of the arc as a Point2D.
+     * 
+     * @return the end point of the curved arc segment.
+     */
+    public Point2D getEndPoint() {
+        double a = Math.toRadians(getAngleStart() + getAngleExtent());
+        return new Point2D.Double(getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0, getY()
+                + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    public Rectangle2D getBounds2D() {
+        if (isEmpty()) {
+            return makeBounds(getX(), getY(), getWidth(), getHeight());
+        }
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        double bx1 = containsAngle(180.0) ? rx1 : Math.min(p1.getX(), p2.getX());
+        double by1 = containsAngle(90.0) ? ry1 : Math.min(p1.getY(), p2.getY());
+        double bx2 = containsAngle(0.0) ? rx2 : Math.max(p1.getX(), p2.getX());
+        double by2 = containsAngle(270.0) ? ry2 : Math.max(p1.getY(), p2.getY());
+
+        if (type == PIE) {
+            double cx = getCenterX();
+            double cy = getCenterY();
+            bx1 = Math.min(bx1, cx);
+            by1 = Math.min(by1, cy);
+            bx2 = Math.max(bx2, cx);
+            by2 = Math.max(by2, cy);
+        }
+        return makeBounds(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param point
+     *            the upper left corner of the bounding rectangle.
+     * @param size
+     *            the size of the bounding rectangle.
+     * @param start
+     *            the start angle of the arc in degrees.
+     * @param extent
+     *            the angle width of the arc in degrees.
+     * @param type
+     *            the closure type, either {@link Arc2D#OPEN},
+     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Point2D point, Dimension2D size, double start, double extent, int type) {
+        setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param rect
+     *            the arc's bounding rectangle.
+     * @param start
+     *            the start angle of the arc in degrees.
+     * @param extent
+     *            the angle width of the arc in degrees.
+     * @param type
+     *            the closure type, either {@link Arc2D#OPEN},
+     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Rectangle2D rect, double start, double extent, int type) {
+        setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc by copying it from another Arc2D.
+     * 
+     * @param arc
+     *            the arc whose data is copied into this arc.
+     */
+    public void setArc(Arc2D arc) {
+        setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc.getAngleStart(), arc
+                .getAngleExtent(), arc.getArcType());
+    }
+
+    /**
+     * Sets the data for a circular arc by giving its center and radius.
+     * 
+     * @param x
+     *            the x coordinate of the center of the circle.
+     * @param y
+     *            the y coordinate of the center of the circle.
+     * @param radius
+     *            the radius of the circle.
+     * @param start
+     *            the start angle of the arc in degrees.
+     * @param extent
+     *            the angle width of the arc in degrees.
+     * @param type
+     *            the closure type, either {@link Arc2D#OPEN},
+     *            {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArcByCenter(double x, double y, double radius, double start, double extent,
+            int type) {
+        setArc(x - radius, y - radius, radius * 2.0, radius * 2.0, start, extent, type);
+    }
+
+    /**
+     * Sets the arc data for a circular arc based on two tangent lines and the
+     * radius. The two tangent lines are the lines from p1 to p2 and from p2 to
+     * p3, which determine a unique circle with the given radius. The start and
+     * end points of the arc are the points where the circle touches the two
+     * lines, and the arc itself is the shorter of the two circle segments
+     * determined by the two points (in other words, it is the piece of the
+     * circle that is closer to the lines' intersection point p2 and forms a
+     * concave shape with the segments from p1 to p2 and from p2 to p3).
+     * 
+     * @param p1
+     *            a point which determines one of the two tangent lines (with
+     *            p2).
+     * @param p2
+     *            the point of intersection of the two tangent lines.
+     * @param p3
+     *            a point which determines one of the two tangent lines (with
+     *            p2).
+     * @param radius
+     *            the radius of the circular arc.
+     */
+    public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double radius) {
+        // Used simple geometric calculations of arc center, radius and angles
+        // by tangents
+        double a1 = -Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
+        double a2 = -Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
+        double am = (a1 + a2) / 2.0;
+        double ah = a1 - am;
+        double d = radius / Math.abs(Math.sin(ah));
+        double x = p2.getX() + d * Math.cos(am);
+        double y = p2.getY() - d * Math.sin(am);
+        ah = ah >= 0.0 ? Math.PI * 1.5 - ah : Math.PI * 0.5 - ah;
+        a1 = getNormAngle(Math.toDegrees(am - ah));
+        a2 = getNormAngle(Math.toDegrees(am + ah));
+        double delta = a2 - a1;
+        if (delta <= 0.0) {
+            delta += 360.0;
+        }
+        setArcByCenter(x, y, radius, a1, delta, type);
+    }
+
+    /**
+     * Sets a new start angle to be the angle given by the the vector from the
+     * current center point to the specified point.
+     * 
+     * @param point
+     *            the point that determines the new start angle.
+     */
+    public void setAngleStart(Point2D point) {
+        double angle = Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
+        setAngleStart(getNormAngle(-Math.toDegrees(angle)));
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center to the
+     * points (x1, y1) and (x2, y2). The start angle is given by the vector from
+     * the current center to the point (x1, y1) and the end angle is given by
+     * the vector from the center to the point (x2, y2).
+     * 
+     * @param x1
+     *            the x coordinate of the point whose vector from the center
+     *            point determines the new start angle of the arc.
+     * @param y1
+     *            the y coordinate of the point whose vector from the center
+     *            point determines the new start angle of the arc.
+     * @param x2
+     *            the x coordinate of the point whose vector from the center
+     *            point determines the new end angle of the arc.
+     * @param y2
+     *            the y coordinate of the point whose vector from the center
+     *            point determines the new end angle of the arc.
+     */
+    public void setAngles(double x1, double y1, double x2, double y2) {
+        double cx = getCenterX();
+        double cy = getCenterY();
+        double a1 = getNormAngle(-Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
+        double a2 = getNormAngle(-Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
+        a2 -= a1;
+        if (a2 <= 0.0) {
+            a2 += 360.0;
+        }
+        setAngleStart(a1);
+        setAngleExtent(a2);
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center to the
+     * points p1 and p2. The start angle is given by the vector from the current
+     * center to the point p1 and the end angle is given by the vector from the
+     * center to the point p2.
+     * 
+     * @param p1
+     *            the point whose vector from the center point determines the
+     *            new start angle of the arc.
+     * @param p2
+     *            the point whose vector from the center point determines the
+     *            new end angle of the arc.
+     */
+    public void setAngles(Point2D p1, Point2D p2) {
+        setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Normalizes the angle by removing extra winding (past 360 degrees) and
+     * placing it in the positive degree range.
+     * 
+     * @param angle
+     *            the source angle in degrees.
+     * @return an angle between 0 and 360 degrees which corresponds to the same
+     *         direction vector as the source angle.
+     */
+    double getNormAngle(double angle) {
+        double n = Math.floor(angle / 360.0);
+        return angle - n * 360.0;
+    }
+
+    /**
+     * Determines whether the given angle is contained in the span of the arc.
+     * 
+     * @param angle
+     *            the angle to test in degrees.
+     * @return true, if the given angle is between the start angle and the end
+     *         angle of the arc.
+     */
+    public boolean containsAngle(double angle) {
+        double extent = getAngleExtent();
+        if (extent >= 360.0) {
+            return true;
+        }
+        angle = getNormAngle(angle);
+        double a1 = getNormAngle(getAngleStart());
+        double a2 = a1 + extent;
+        if (a2 > 360.0) {
+            return angle >= a1 || angle <= a2 - 360.0;
+        }
+        if (a2 < 0.0) {
+            return angle >= a2 + 360.0 || angle <= a1;
+        }
+        return extent > 0.0 ? a1 <= angle && angle <= a2 : a2 <= angle && angle <= a1;
+    }
+
+    public boolean contains(double px, double py) {
+        // Normalize point
+        double nx = (px - getX()) / getWidth() - 0.5;
+        double ny = (py - getY()) / getHeight() - 0.5;
+
+        if ((nx * nx + ny * ny) > 0.25) {
+            return false;
+        }
+
+        double extent = getAngleExtent();
+        double absExtent = Math.abs(extent);
+        if (absExtent >= 360.0) {
+            return true;
+        }
+
+        boolean containsAngle = containsAngle(Math.toDegrees(-Math.atan2(ny, nx)));
+        if (type == PIE) {
+            return containsAngle;
+        }
+        if (absExtent <= 180.0 && !containsAngle) {
+            return false;
+        }
+
+        Line2D l = new Line2D.Double(getStartPoint(), getEndPoint());
+        int ccw1 = l.relativeCCW(px, py);
+        int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
+        return ccw1 == 0 || ccw2 == 0 || ((ccw1 + ccw2) == 0 ^ absExtent > 180.0);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+
+        if (!(contains(rx, ry) && contains(rx + rw, ry) && contains(rx + rw, ry + rh) && contains(
+                rx, ry + rh))) {
+            return false;
+        }
+
+        double absExtent = Math.abs(getAngleExtent());
+        if (type != PIE || absExtent <= 180.0 || absExtent >= 360.0) {
+            return true;
+        }
+
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        if (r.contains(cx, cy)) {
+            return false;
+        }
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        return !r.intersectsLine(cx, cy, p1.getX(), p1.getY())
+                && !r.intersectsLine(cx, cy, p2.getX(), p2.getY());
+    }
+
+    @Override
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        // Check: Does arc contain rectangle's points
+        if (contains(rx, ry) || contains(rx + rw, ry) || contains(rx, ry + rh)
+                || contains(rx + rw, ry + rh)) {
+            return true;
+        }
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        // Check: Does rectangle contain arc's points
+        if (r.contains(p1) || r.contains(p2) || (type == PIE && r.contains(cx, cy))) {
+            return true;
+        }
+
+        if (type == PIE) {
+            if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy)
+                    || r.intersectsLine(p2.getX(), p2.getY(), cx, cy)) {
+                return true;
+            }
+        } else {
+            if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
+                return true;
+            }
+        }
+
+        // Nearest rectangle point
+        double nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
+        double ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
+        return contains(nx, ny);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
diff --git a/awt/java/awt/geom/Area.java b/awt/java/awt/geom/Area.java
new file mode 100644
index 0000000..e6619e3
--- /dev/null
+++ b/awt/java/awt/geom/Area.java
@@ -0,0 +1,330 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ * The Class Area provides a minimal implementation for a generic shape.
+ * 
+ * @since Android 1.0
+ */
+public class Area implements Shape, Cloneable {
+
+    /**
+     * The source Shape object.
+     */
+    Shape s;
+
+    /**
+     * The Class NullIterator.
+     */
+    private static class NullIterator implements PathIterator {
+
+        /**
+         * Instantiates a new null iterator.
+         */
+        NullIterator() {
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return true;
+        }
+
+        public void next() {
+            // nothing
+        }
+
+        public int currentSegment(double[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+        public int currentSegment(float[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+    }
+
+    /**
+     * Instantiates a new area with no data.
+     */
+    public Area() {
+    }
+
+    /**
+     * Instantiates a new area with data given by the specified shape.
+     * 
+     * @param s
+     *            the shape that gives the data for this Area.
+     */
+    public Area(Shape s) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        this.s = s;
+    }
+
+    public boolean contains(double x, double y) {
+        return s == null ? false : s.contains(x, y);
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        return s == null ? false : s.contains(x, y, width, height);
+    }
+
+    public boolean contains(Point2D p) {
+        if (p == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(p);
+    }
+
+    public boolean contains(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(r);
+    }
+
+    /**
+     * Tests whether the object is equal to this Area.
+     * 
+     * @param obj
+     *            the object to compare.
+     * @return true, if successful.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        return s == null ? false : s.intersects(x, y, width, height);
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.intersects(r);
+    }
+
+    public Rectangle getBounds() {
+        return s == null ? new Rectangle() : s.getBounds();
+    }
+
+    public Rectangle2D getBounds2D() {
+        return s == null ? new Rectangle2D.Double() : s.getBounds2D();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return s == null ? new NullIterator() : s.getPathIterator(t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
+    }
+
+    /**
+     * Adds the specified area to this area.
+     * 
+     * @param area
+     *            the area to add to this area.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Performs an exclusive or operation between this shape and the specified
+     * shape.
+     * 
+     * @param area
+     *            the area to XOR against this area.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Extracts a Rectangle2D from the source shape if the underlying shape data
+     * describes a rectangle.
+     * 
+     * @return a Rectangle2D object if the source shape is rectangle, or null if
+     *         shape is empty or not rectangle.
+     */
+    Rectangle2D extractRectangle() {
+        if (s == null) {
+            return null;
+        }
+        float[] points = new float[12];
+        int count = 0;
+        PathIterator p = s.getPathIterator(null);
+        float[] coords = new float[6];
+        while (!p.isDone()) {
+            int type = p.currentSegment(coords);
+            if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
+                return null;
+            }
+            points[count++] = coords[0];
+            points[count++] = coords[1];
+            p.next();
+        }
+        if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4]
+                && points[1] == points[3] && points[3] == points[9] && points[5] == points[7]) {
+            return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7]
+                    - points[1]);
+        }
+        return null;
+    }
+
+    /**
+     * Reduces the size of this Area by intersecting it with the specified Area
+     * if they are both rectangles.
+     * 
+     * @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D,
+     *      Rectangle2D)
+     * @param area
+     *            the area.
+     */
+    public void intersect(Area area) {
+        Rectangle2D src1 = extractRectangle();
+        Rectangle2D src2 = area.extractRectangle();
+        if (src1 != null && src2 != null) {
+            Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
+        }
+    }
+
+    /**
+     * Subtract the specified area from this area.
+     * 
+     * @param area
+     *            the area to subtract.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is empty.
+     * 
+     * @return true, if this Area is empty.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is polygonal.
+     * 
+     * @return true, if this Area is polygonal.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is rectangular.
+     * 
+     * @return true, if this Area is rectangular.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is singular.
+     * 
+     * @return true, if this Area is singular.
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Resets the data of this Area.
+     * 
+     * @throws NotImplementedException
+     *             if this method is not implemented.
+     */
+    public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Transforms the data of this Area according to the specified
+     * AffineTransform.
+     * 
+     * @param t
+     *            the transform to use to transform the data.
+     */
+    public void transform(AffineTransform t) {
+        s = t.createTransformedShape(s);
+    }
+
+    /**
+     * Creates a new Area that is the result of transforming the data of this
+     * Area according to the specified AffineTransform.
+     * 
+     * @param t
+     *            the transform to use to transform the data.
+     * @return the new Area that is the result of transforming the data of this
+     *         Area according to the specified AffineTransform.
+     */
+    public Area createTransformedArea(AffineTransform t) {
+        return s == null ? new Area() : new Area(t.createTransformedShape(s));
+    }
+
+    @Override
+    public Object clone() {
+        return new Area(this);
+    }
+
+}
diff --git a/awt/java/awt/geom/CubicCurve2D.java b/awt/java/awt/geom/CubicCurve2D.java
new file mode 100644
index 0000000..1ddedf3
--- /dev/null
+++ b/awt/java/awt/geom/CubicCurve2D.java
@@ -0,0 +1,1047 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class CubicCurve2D is a Shape that represents a segment of a quadratic
+ * (Bezier) curve. The curved segment is determined by four points: a start
+ * point, an end point, and two control points. The control points give
+ * information about the tangent and next derivative at the endpoints according
+ * to the standard theory of Bezier curves. For more information on Bezier
+ * curves, see <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">this
+ * article</a>.
+ * 
+ * @since Android 1.0
+ */
+public abstract class CubicCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of CubicCurve2D that has all of its data
+     * values stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends CubicCurve2D {
+
+        /**
+         * The x coordinate of the starting point.
+         */
+        public float x1;
+
+        /**
+         * The y coordinate of the starting point.
+         */
+        public float y1;
+
+        /**
+         * The x coordinate of the first control point.
+         */
+        public float ctrlx1;
+
+        /**
+         * The y coordinate of the first control point.
+         */
+        public float ctrly1;
+
+        /**
+         * The x coordinate of the second control point.
+         */
+        public float ctrlx2;
+
+        /**
+         * The y coordinate of the second control point.
+         */
+        public float ctrly2;
+
+        /**
+         * The x coordinate of the end point.
+         */
+        public float x2;
+
+        /**
+         * The y coordinate of the end point.
+         */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with all coordinate
+         * values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param ctrlx1
+         *            the x coordinate of the first control point.
+         * @param ctrly1
+         *            the y coordinate of the first control point.
+         * @param ctrlx2
+         *            the x coordinate of the second control point.
+         * @param ctrly2
+         *            the y coordinate of the second control point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public Float(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2,
+                float x2, float y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Float(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Float(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
+                double ctrly2, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx1 = (float)ctrlx1;
+            this.ctrly1 = (float)ctrly1;
+            this.ctrlx2 = (float)ctrlx2;
+            this.ctrly2 = (float)ctrly2;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param ctrlx1
+         *            the x coordinate of the first control point.
+         * @param ctrly1
+         *            the y coordinate of the first control point.
+         * @param ctrlx2
+         *            the x coordinate of the second control point.
+         * @param ctrly2
+         *            the y coordinate of the second control point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public void setCurve(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2,
+                float ctrly2, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            float ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            float rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            float ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of CubicCurve2D that has all of its data
+     * values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends CubicCurve2D {
+
+        /**
+         * The x coordinate of the starting point.
+         */
+        public double x1;
+
+        /**
+         * The y coordinate of the starting point.
+         */
+        public double y1;
+
+        /**
+         * The x coordinate of the first control point.
+         */
+        public double ctrlx1;
+
+        /**
+         * The y coordinate of the first control point.
+         */
+        public double ctrly1;
+
+        /**
+         * The x coordinate of the second control point.
+         */
+        public double ctrlx2;
+
+        /**
+         * The y coordinate of the second control point.
+         */
+        public double ctrly2;
+
+        /**
+         * The x coordinate of the end point.
+         */
+        public double x2;
+
+        /**
+         * The y coordinate of the end point.
+         */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with all coordinate
+         * values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param ctrlx1
+         *            the x coordinate of the first control point.
+         * @param ctrly1
+         *            the y coordinate of the first control point.
+         * @param ctrlx2
+         *            the x coordinate of the second control point.
+         * @param ctrly2
+         *            the y coordinate of the second control point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public Double(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
+                double ctrly2, double x2, double y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Double(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Double(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2,
+                double ctrly2, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            double ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            double rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            double ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Double(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /*
+     * CubicCurve2D path iterator
+     */
+    /**
+     * The Iterator class for the Shape CubicCurve2D.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The source CubicCurve2D object.
+         */
+        CubicCurve2D c;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new CubicCurve2D.Iterator for given line and
+         * transformation
+         * 
+         * @param c
+         *            the source CubicCurve2D object.
+         * @param t
+         *            the affine transformation object.
+         */
+        Iterator(CubicCurve2D c, AffineTransform t) {
+            this.c = c;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = c.getCtrlX1();
+                coords[1] = c.getCtrlY1();
+                coords[2] = c.getCtrlX2();
+                coords[3] = c.getCtrlY2();
+                coords[4] = c.getX2();
+                coords[5] = c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = (float)c.getCtrlX1();
+                coords[1] = (float)c.getCtrlY1();
+                coords[2] = (float)c.getCtrlX2();
+                coords[3] = (float)c.getCtrlY2();
+                coords[4] = (float)c.getX2();
+                coords[5] = (float)c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new 2-D cubic curve.
+     */
+    protected CubicCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point.
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point.
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point.
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the first control point.
+     * 
+     * @return the x coordinate of the first control point.
+     */
+    public abstract double getCtrlX1();
+
+    /**
+     * Gets the y coordinate of the first control point.
+     * 
+     * @return the y coordinate of the first control point.
+     */
+    public abstract double getCtrlY1();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point.
+     */
+    public abstract Point2D getCtrlP1();
+
+    /**
+     * Gets the x coordinate of the second control point.
+     * 
+     * @return the x coordinate of the second control point
+     */
+    public abstract double getCtrlX2();
+
+    /**
+     * Gets the y coordinate of the second control point.
+     * 
+     * @return the y coordinate of the second control point
+     */
+    public abstract double getCtrlY2();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point.
+     */
+    public abstract Point2D getCtrlP2();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point.
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point.
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point.
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point.
+     * @param y1
+     *            the y coordinate of the starting point.
+     * @param ctrlx1
+     *            the x coordinate of the first control point.
+     * @param ctrly1
+     *            the y coordinate of the first control point.
+     * @param ctrlx2
+     *            the x coordinate of the second control point.
+     * @param ctrly2
+     *            the y coordinate of the second control point.
+     * @param x2
+     *            the x coordinate of the end point.
+     * @param y2
+     *            the y coordinate of the end point.
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2);
+
+    /**
+     * Sets the data of the curve as point objects.
+     * 
+     * @param p1
+     *            the starting point.
+     * @param cp1
+     *            the first control point.
+     * @param cp2
+     *            the second control point.
+     * @param p2
+     *            the end point.
+     * @throws NullPointerException
+     *             if any of the points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
+        setCurve(p1.getX(), p1.getY(), cp1.getX(), cp1.getY(), cp2.getX(), cp2.getY(), p2.getX(),
+                p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array of values.
+     * The values are read in the same order as the arguments of the method
+     * {@link CubicCurve2D#setCurve(double, double, double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of values containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code coords.length} < offset + 8.
+     * @throws NullPointerException
+     *             if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5], coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array of points.
+     * The values are read in the same order as the arguments of the method
+     * {@link CubicCurve2D#setCurve(Point2D, Point2D, Point2D, Point2D)}
+     * 
+     * @param points
+     *            the array of points containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code points.length} < offset + .
+     * @throws NullPointerException
+     *             if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(),
+                points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY(),
+                points[offset + 3].getX(), points[offset + 3].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another CubicCurve2D.
+     * 
+     * @param curve
+     *            the curve to copy the data points from.
+     * @throws NullPointerException
+     *             if the curve is null.
+     */
+    public void setCurve(CubicCurve2D curve) {
+        setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX1(), curve.getCtrlY1(), curve
+                .getCtrlX2(), curve.getCtrlY2(), curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of this curve, where the flatness is the
+     * maximum distance from the curves control points to the line segment
+     * connecting the two points.
+     * 
+     * @return the square of the flatness.
+     */
+    public double getFlatnessSq() {
+        return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment defined by the
+     * specified values.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point.
+     * @param y1
+     *            the y coordinate of the starting point.
+     * @param ctrlx1
+     *            the x coordinate of the first control point.
+     * @param ctrly1
+     *            the y coordinate of the first control point.
+     * @param ctrlx2
+     *            the x coordinate of the second control point.
+     * @param ctrly2
+     *            the y coordinate of the second control point.
+     * @param x2
+     *            the x coordinate of the end point.
+     * @param y2
+     *            the y coordinate of the end point.
+     * @return the square of the flatness.
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2) {
+        return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1), Line2D.ptSegDistSq(x1,
+                y1, x2, y2, ctrlx2, ctrly2));
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment defined by the
+     * specified values. The values are read in the same order as the arguments
+     * of the method
+     * {@link CubicCurve2D#getFlatnessSq(double, double, double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of points containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @return the square of the flatness.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if points.length < offset + .
+     * @throws NullPointerException
+     *             if the point array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return getFlatnessSq(coords[offset + 0], coords[offset + 1], coords[offset + 2],
+                coords[offset + 3], coords[offset + 4], coords[offset + 5], coords[offset + 6],
+                coords[offset + 7]);
+    }
+
+    /**
+     * Gets the flatness of this curve, where the flatness is the maximum
+     * distance from the curves control points to the line segment connecting
+     * the two points.
+     * 
+     * @return the flatness of this curve.
+     */
+    public double getFlatness() {
+        return getFlatness(getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment defined by the specified
+     * values.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point.
+     * @param y1
+     *            the y coordinate of the starting point.
+     * @param ctrlx1
+     *            the x coordinate of the first control point.
+     * @param ctrly1
+     *            the y coordinate of the first control point.
+     * @param ctrlx2
+     *            the x coordinate of the second control point.
+     * @param ctrly2
+     *            the y coordinate of the second control point.
+     * @param x2
+     *            the x coordinate of the end point.
+     * @param y2
+     *            the y coordinate of the end point.
+     * @return the flatness.
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2) {
+        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment defined by the specified
+     * values. The values are read in the same order as the arguments of the
+     * method
+     * {@link CubicCurve2D#getFlatness(double, double, double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of points containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @return the flatness.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if points.length < offset + .
+     * @throws NullPointerException
+     *             if the point array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return getFlatness(coords[offset + 0], coords[offset + 1], coords[offset + 2],
+                coords[offset + 3], coords[offset + 4], coords[offset + 5], coords[offset + 6],
+                coords[offset + 7]);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing this curve in two. The
+     * division point is the point on the curve that is closest to the average
+     * of curve's two control points. The two new control points (nearest the
+     * new endpoint) are computed by averaging the original control points with
+     * the new endpoint. The data of this curve is left unchanged.
+     * 
+     * @param left
+     *            the CubicCurve2D where the left (start) segment's data is
+     *            written.
+     * @param right
+     *            the CubicCurve2D where the right (end) segment's data is
+     *            written.
+     * @throws NullPointerException
+     *             if either curve is null.
+     */
+    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified curve in
+     * two. The division point is the point on the curve that is closest to the
+     * average of curve's two control points. The two new control points
+     * (nearest the new endpoint) are computed by averaging the original control
+     * points with the new endpoint. The data of the source curve is left
+     * unchanged.
+     * 
+     * @param src
+     *            the original curve to be divided in two.
+     * @param left
+     *            the CubicCurve2D where the left (start) segment's data is
+     *            written.
+     * @param right
+     *            the CubicCurve2D where the right (end) segment's data is
+     *            written.
+     * @throws NullPointerException
+     *             if either curve is null.
+     */
+    public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx1 = src.getCtrlX1();
+        double cy1 = src.getCtrlY1();
+        double cx2 = src.getCtrlX2();
+        double cy2 = src.getCtrlY2();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified curve in
+     * two. The division point is the point on the curve that is closest to the
+     * average of curve's two control points. The two new control points
+     * (nearest the new endpoint) are computed by averaging the original control
+     * points with the new endpoint. The data of the source curve is left
+     * unchanged. The data for the three curves is read/written in the usual
+     * order: { x1, y1, ctrlx1, ctrly1, ctrlx2, crtry2, x2, y3 }
+     * 
+     * @param src
+     *            the array that gives the data values for the source curve.
+     * @param srcOff
+     *            the offset in the src array to read the values from.
+     * @param left
+     *            the array where the coordinates of the start curve should be
+     *            written.
+     * @param leftOff
+     *            the offset in the left array to start writing the values.
+     * @param right
+     *            the array where the coordinates of the end curve should be
+     *            written.
+     * @param rightOff
+     *            the offset in the right array to start writing the values.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if src.length < srcoff + 8 or if left.length < leftOff + 8 or
+     *             if right.length < rightOff + 8.
+     * @throws NullPointerException
+     *             if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcOff, double left[], int leftOff,
+            double right[], int rightOff) {
+        double x1 = src[srcOff + 0];
+        double y1 = src[srcOff + 1];
+        double cx1 = src[srcOff + 2];
+        double cy1 = src[srcOff + 3];
+        double cx2 = src[srcOff + 4];
+        double cy2 = src[srcOff + 5];
+        double x2 = src[srcOff + 6];
+        double y2 = src[srcOff + 7];
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = ax;
+            left[leftOff + 5] = ay;
+            left[leftOff + 6] = cx;
+            left[leftOff + 7] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = bx;
+            right[rightOff + 3] = by;
+            right[rightOff + 4] = cx2;
+            right[rightOff + 5] = cy2;
+            right[rightOff + 6] = x2;
+            right[rightOff + 7] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is accomplished by finding
+     * the (real) values of x that solve the following equation: eqn[3]*x*x*x +
+     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into
+     * the array eqn starting from the index 0 in the array. The return value
+     * tells how many array elements have been changed by this method call.
+     * 
+     * @param eqn
+     *            an array containing the coefficients of the cubic polynomial
+     *            to solve.
+     * @return the number of roots of the cubic polynomial.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if eqn.length < 4.
+     * @throws NullPointerException
+     *             if the array is null.
+     */
+    public static int solveCubic(double eqn[]) {
+        return solveCubic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is accomplished by finding
+     * the (real) values of x that solve the following equation: eqn[3]*x*x*x +
+     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the
+     * array res starting from the index 0 in the array. The return value tells
+     * how many array elements have been changed by this method call.
+     * 
+     * @param eqn
+     *            an array containing the coefficients of the cubic polynomial
+     *            to solve.
+     * @param res
+     *            the array that this method writes the results into.
+     * @return the number of roots of the cubic polynomial.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if eqn.length < 4 or if res.length is less than the number of
+     *             roots.
+     * @throws NullPointerException
+     *             if either array is null.
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        return Crossing.solveCubic(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(at), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/geom/Dimension2D.java b/awt/java/awt/geom/Dimension2D.java
new file mode 100644
index 0000000..ea081c5
--- /dev/null
+++ b/awt/java/awt/geom/Dimension2D.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 Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+/**
+ * The Class Dimension2D represents a size (width and height) of a geometric
+ * object. It stores double-valued data in order to be compatible with
+ * high-precision geometric operations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Dimension2D implements Cloneable {
+
+    /**
+     * Instantiates a new dimension 2d with no data.
+     */
+    protected Dimension2D() {
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width.
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height.
+     */
+    public abstract double getHeight();
+
+    /**
+     * Sets the width and height.
+     * 
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     */
+    public abstract void setSize(double width, double height);
+
+    /**
+     * Sets the width and height based on the data of another Dimension2D
+     * object.
+     * 
+     * @param d
+     *            the Dimension2D object providing the data to copy into this
+     *            Dimension2D object.
+     */
+    public void setSize(Dimension2D d) {
+        setSize(d.getWidth(), d.getHeight());
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
diff --git a/awt/java/awt/geom/Ellipse2D.java b/awt/java/awt/geom/Ellipse2D.java
new file mode 100644
index 0000000..89fd0d0
--- /dev/null
+++ b/awt/java/awt/geom/Ellipse2D.java
@@ -0,0 +1,458 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Ellipse2D describes an ellipse defined by a rectangular area in
+ * which it is inscribed.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Ellipse2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of Ellipse2D that has all of its data
+     * values stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends Ellipse2D {
+
+        /**
+         * The x coordinate of the upper left corner of the ellipse's bounding
+         * rectangle.
+         */
+        public float x;
+
+        /**
+         * The y coordinate of the upper left corner of the ellipse's bounding
+         * rectangle.
+         */
+        public float y;
+
+        /**
+         * The width of the ellipse's bounding rectangle.
+         */
+        public float width;
+
+        /**
+         * The height of the ellipse's bounding rectangle.
+         */
+        public float height;
+
+        /**
+         * Instantiates a new float-valued Ellipse2D.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Ellipse2D with the specified data.
+         * 
+         * @param x
+         *            the x coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param y
+         *            the y coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param width
+         *            the width of the ellipse's bounding rectangle.
+         * @param height
+         *            the height of the ellipse's bounding rectangle.
+         */
+        public Float(float x, float y, float width, float height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        /**
+         * Sets the data of the ellipse's bounding rectangle.
+         * 
+         * @param x
+         *            the x coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param y
+         *            the y coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param width
+         *            the width of the ellipse's bounding rectangle.
+         * @param height
+         *            the height of the ellipse's bounding rectangle.
+         */
+        public void setFrame(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Ellipse2D that has all of its data
+     * values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends Ellipse2D {
+
+        /**
+         * The x coordinate of the upper left corner of the ellipse's bounding
+         * rectangle.
+         */
+        public double x;
+
+        /**
+         * The y coordinate of the upper left corner of the ellipse's bounding
+         * rectangle.
+         */
+        public double y;
+
+        /**
+         * The width of the ellipse's bounding rectangle.
+         */
+        public double width;
+
+        /**
+         * The height of the ellipse's bounding rectangle.
+         */
+        public double height;
+
+        /**
+         * Instantiates a new double-valued Ellipse2D.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Ellipse2D with the specified data.
+         * 
+         * @param x
+         *            the x coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param y
+         *            the y coordinate of the upper left corner of the ellipse's
+         *            bounding rectangle.
+         * @param width
+         *            the width of the ellipse's bounding rectangle.
+         * @param height
+         *            the height of the ellipse's bounding rectangle.
+         */
+        public Double(double x, double y, double width, double height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * Ellipse2D path iterator
+     */
+    /**
+     * The subclass of PathIterator to traverse an Ellipse2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Ellipse is subdivided into four quarters by x and y axis. Each part
+         * approximated by cubic Bezier curve. Arc in first quarter is started
+         * in (a, 0) and finished in (0, b) points. Control points for cubic
+         * curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
+         * calculated based on requirement Bezier curve in point 0.5 should lay
+         * on the arc.
+         */
+
+        /**
+         * The coefficient to calculate control points of Bezier curves.
+         */
+        final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /**
+         * The points coordinates calculation table.
+         */
+        final double points[][] = {
+                {
+                        1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0
+                }, {
+                        0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5
+                }, {
+                        0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0
+                }, {
+                        0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5
+                }
+        };
+
+        /**
+         * The x coordinate of left-upper corner of the ellipse bounds.
+         */
+        double x;
+
+        /**
+         * The y coordinate of left-upper corner of the ellipse bounds.
+         */
+        double y;
+
+        /**
+         * The width of the ellipse bounds.
+         */
+        double width;
+
+        /**
+         * The height of the ellipse bounds.
+         */
+        double height;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new Ellipse2D.Iterator for given ellipse and
+         * transformation
+         * 
+         * @param e
+         *            the source Ellipse2D object.
+         * @param t
+         *            the affine transformation object.
+         */
+        Iterator(Ellipse2D e, AffineTransform t) {
+            this.x = e.getX();
+            this.y = e.getY();
+            this.width = e.getWidth();
+            this.height = e.getHeight();
+            this.t = t;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = x + p[4] * width;
+                coords[1] = y + p[5] * height;
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                double p[] = points[index - 1];
+                int j = 0;
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = x + p[j++] * width;
+                    coords[j] = y + p[j++] * height;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = (float)(x + p[4] * width);
+                coords[1] = (float)(y + p[5] * height);
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                int j = 0;
+                double p[] = points[index - 1];
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = (float)(x + p[j++] * width);
+                    coords[j] = (float)(y + p[j++] * height);
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Ellipse2D.
+     */
+    protected Ellipse2D() {
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double a = (px - getX()) / getWidth() - 0.5;
+        double b = (py - getY()) / getHeight() - 0.5;
+
+        return a * a + b * b < 0.25;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double cx = getX() + getWidth() / 2.0;
+        double cy = getY() + getHeight() / 2.0;
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+}
diff --git a/awt/java/awt/geom/FlatteningPathIterator.java b/awt/java/awt/geom/FlatteningPathIterator.java
new file mode 100644
index 0000000..8208f39
--- /dev/null
+++ b/awt/java/awt/geom/FlatteningPathIterator.java
@@ -0,0 +1,358 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class FlatteningPathIterator takes a PathIterator for traversing a curved
+ * shape and flattens it by estimating the curve as a series of line segments.
+ * The flattening factor indicates how far the estimating line segments are
+ * allowed to be from the actual curve: the FlatteningPathIterator will keep
+ * dividing each curved segment into smaller and smaller flat segments until
+ * either the segments are within the flattening factor of the curve or until
+ * the buffer limit is reached.
+ * 
+ * @since Android 1.0
+ */
+public class FlatteningPathIterator implements PathIterator {
+
+    /**
+     * The default points buffer size.
+     */
+    private static final int BUFFER_SIZE = 16;
+
+    /**
+     * The default curve subdivision limit.
+     */
+    private static final int BUFFER_LIMIT = 16;
+
+    /**
+     * The points buffer capacity.
+     */
+    private static final int BUFFER_CAPACITY = 16;
+
+    /**
+     * The type of current segment to be flat.
+     */
+    int bufType;
+
+    /**
+     * The curve subdivision limit.
+     */
+    int bufLimit;
+
+    /**
+     * The current points buffer size.
+     */
+    int bufSize;
+
+    /**
+     * The inner cursor position in points buffer.
+     */
+    int bufIndex;
+
+    /**
+     * The current subdivision count.
+     */
+    int bufSubdiv;
+
+    /**
+     * The points buffer.
+     */
+    double buf[];
+
+    /**
+     * The indicator of empty points buffer.
+     */
+    boolean bufEmpty = true;
+
+    /**
+     * The source PathIterator.
+     */
+    PathIterator p;
+
+    /**
+     * The flatness of new path.
+     */
+    double flatness;
+
+    /**
+     * The square of flatness.
+     */
+    double flatness2;
+
+    /**
+     * The x coordinate of previous path segment.
+     */
+    double px;
+
+    /**
+     * The y coordinate of previous path segment.
+     */
+    double py;
+
+    /**
+     * The temporary buffer for getting points from PathIterator.
+     */
+    double coords[] = new double[6];
+
+    /**
+     * Instantiates a new flattening path iterator given the path iterator for a
+     * (possibly) curved path and a flattening factor which indicates how close
+     * together the points on the curve should be chosen. The buffer limit
+     * defaults to 16 which means that each curve will be divided into no more
+     * than 16 segments regardless of the flattening factor.
+     * 
+     * @param path
+     *            the path iterator of the original curve.
+     * @param flatness
+     *            the flattening factor that indicates how far the flat path is
+     *            allowed to be from the actual curve in order to decide when to
+     *            stop dividing the path into smaller and smaller segments.
+     * @throws IllegalArgumentException
+     *             if the flatness is less than zero.
+     * @throws NullPointerException
+     *             if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness) {
+        this(path, flatness, BUFFER_LIMIT);
+    }
+
+    /**
+     * Instantiates a new flattening path iterator given the path iterator for a
+     * (possibly) curved path and a flattening factor and a buffer limit. The
+     * FlatteningPathIterator will keep dividing each curved segment into
+     * smaller and smaller flat segments until either the segments are within
+     * the flattening factor of the curve or until the buffer limit is reached.
+     * 
+     * @param path
+     *            the path iterator of the original curve.
+     * @param flatness
+     *            the flattening factor that indicates how far the flat path is
+     *            allowed to be from the actual curve in order to decide when to
+     *            stop dividing the path into smaller and smaller segments.
+     * @param limit
+     *            the maximum number of flat segments to divide each curve into.
+     * @throws IllegalArgumentException
+     *             if the flatness or limit is less than zero.
+     * @throws NullPointerException
+     *             if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
+        if (flatness < 0.0) {
+            // awt.206=Flatness is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
+        }
+        if (limit < 0) {
+            // awt.207=Limit is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
+        }
+        if (path == null) {
+            // awt.208=Path is null
+            throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
+        }
+        this.p = path;
+        this.flatness = flatness;
+        this.flatness2 = flatness * flatness;
+        this.bufLimit = limit;
+        this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
+        this.buf = new double[bufSize];
+        this.bufIndex = bufSize;
+    }
+
+    /**
+     * Gets the flattening factor.
+     * 
+     * @return the flattening factor.
+     */
+    public double getFlatness() {
+        return flatness;
+    }
+
+    /**
+     * Gets the maximum number of subdivisions per curved segment.
+     * 
+     * @return the maximum number of subdivisions per curved segment.
+     */
+    public int getRecursionLimit() {
+        return bufLimit;
+    }
+
+    public int getWindingRule() {
+        return p.getWindingRule();
+    }
+
+    public boolean isDone() {
+        return bufEmpty && p.isDone();
+    }
+
+    /**
+     * Calculates flat path points for current segment of the source shape. Line
+     * segment is flat by itself. Flatness of quad and cubic curves evaluated by
+     * getFlatnessSq() method. Curves subdivided until current flatness is
+     * bigger than user defined and subdivision limit isn't exhausted. Single
+     * source segment translated to series of buffer points. The less flatness
+     * the bigger series. Every currentSegment() call extract one point from the
+     * buffer. When series completed evaluate() takes next source shape segment.
+     */
+    void evaluate() {
+        if (bufEmpty) {
+            bufType = p.currentSegment(coords);
+        }
+
+        switch (bufType) {
+            case SEG_MOVETO:
+            case SEG_LINETO:
+                px = coords[0];
+                py = coords[1];
+                break;
+            case SEG_QUADTO:
+                if (bufEmpty) {
+                    bufIndex -= 6;
+                    buf[bufIndex + 0] = px;
+                    buf[bufIndex + 1] = py;
+                    System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
+                    bufSubdiv = 0;
+                }
+
+                while (bufSubdiv < bufLimit) {
+                    if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                        break;
+                    }
+
+                    // Realloc buffer
+                    if (bufIndex <= 4) {
+                        double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                        System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
+                                - bufIndex);
+                        buf = tmp;
+                        bufSize += BUFFER_CAPACITY;
+                        bufIndex += BUFFER_CAPACITY;
+                    }
+
+                    QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
+
+                    bufIndex -= 4;
+                    bufSubdiv++;
+                }
+
+                bufIndex += 4;
+                px = buf[bufIndex];
+                py = buf[bufIndex + 1];
+
+                bufEmpty = (bufIndex == bufSize - 2);
+                if (bufEmpty) {
+                    bufIndex = bufSize;
+                    bufType = SEG_LINETO;
+                } else {
+                    bufSubdiv--;
+                }
+                break;
+            case SEG_CUBICTO:
+                if (bufEmpty) {
+                    bufIndex -= 8;
+                    buf[bufIndex + 0] = px;
+                    buf[bufIndex + 1] = py;
+                    System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
+                    bufSubdiv = 0;
+                }
+
+                while (bufSubdiv < bufLimit) {
+                    if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                        break;
+                    }
+
+                    // Realloc buffer
+                    if (bufIndex <= 6) {
+                        double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                        System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
+                                - bufIndex);
+                        buf = tmp;
+                        bufSize += BUFFER_CAPACITY;
+                        bufIndex += BUFFER_CAPACITY;
+                    }
+
+                    CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
+
+                    bufIndex -= 6;
+                    bufSubdiv++;
+                }
+
+                bufIndex += 6;
+                px = buf[bufIndex];
+                py = buf[bufIndex + 1];
+
+                bufEmpty = (bufIndex == bufSize - 2);
+                if (bufEmpty) {
+                    bufIndex = bufSize;
+                    bufType = SEG_LINETO;
+                } else {
+                    bufSubdiv--;
+                }
+                break;
+        }
+
+    }
+
+    public void next() {
+        if (bufEmpty) {
+            p.next();
+        }
+    }
+
+    public int currentSegment(float[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = (float)px;
+            coords[1] = (float)py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+
+    public int currentSegment(double[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = px;
+            coords[1] = py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+}
diff --git a/awt/java/awt/geom/GeneralPath.java b/awt/java/awt/geom/GeneralPath.java
new file mode 100644
index 0000000..0669bc7
--- /dev/null
+++ b/awt/java/awt/geom/GeneralPath.java
@@ -0,0 +1,624 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class GeneralPath represents a shape whose outline is given by different
+ * types of curved and straight segments.
+ * 
+ * @since Android 1.0
+ */
+public final class GeneralPath implements Shape, Cloneable {
+
+    /**
+     * The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}.
+     */
+    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+
+    /**
+     * The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+    /**
+     * The buffers size.
+     */
+    private static final int BUFFER_SIZE = 10;
+
+    /**
+     * The buffers capacity.
+     */
+    private static final int BUFFER_CAPACITY = 10;
+
+    /**
+     * The point's types buffer.
+     */
+    byte[] types;
+
+    /**
+     * The points buffer.
+     */
+    float[] points;
+
+    /**
+     * The point's type buffer size.
+     */
+    int typeSize;
+
+    /**
+     * The points buffer size.
+     */
+    int pointSize;
+
+    /**
+     * The path rule.
+     */
+    int rule;
+
+    /**
+     * The space amount in points buffer for different segmenet's types.
+     */
+    static int pointShift[] = {
+            2, // MOVETO
+            2, // LINETO
+            4, // QUADTO
+            6, // CUBICTO
+            0
+    }; // CLOSE
+
+    /*
+     * GeneralPath path iterator
+     */
+    /**
+     * The Class Iterator is the subclass of Iterator for traversing the outline
+     * of a GeneralPath.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The current cursor position in types buffer.
+         */
+        int typeIndex;
+
+        /**
+         * The current cursor position in points buffer.
+         */
+        int pointIndex;
+
+        /**
+         * The source GeneralPath object.
+         */
+        GeneralPath p;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path.
+         * 
+         * @param path
+         *            the source GeneralPath object.
+         */
+        Iterator(GeneralPath path) {
+            this(path, null);
+        }
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path and
+         * transformation.
+         * 
+         * @param path
+         *            the source GeneralPath object.
+         * @param at
+         *            the AffineTransform object to apply rectangle path.
+         */
+        Iterator(GeneralPath path, AffineTransform at) {
+            this.p = path;
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return p.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return typeIndex >= p.typeSize;
+        }
+
+        public void next() {
+            typeIndex++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            for (int i = 0; i < count; i++) {
+                coords[i] = p.points[pointIndex + i];
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            System.arraycopy(p.points, pointIndex, coords, 0, count);
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new general path with the winding rule set to
+     * {@link PathIterator#WIND_NON_ZERO} and the initial capacity (number of
+     * segments) set to the default value 10.
+     */
+    public GeneralPath() {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule and the
+     * initial capacity (number of segments) set to the default value 10.
+     * 
+     * @param rule
+     *            the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     *            {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public GeneralPath(int rule) {
+        this(rule, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule and initial
+     * capacity (number of segments).
+     * 
+     * @param rule
+     *            the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     *            {@link PathIterator#WIND_NON_ZERO}.
+     * @param initialCapacity
+     *            the number of segments the path is set to hold.
+     */
+    public GeneralPath(int rule, int initialCapacity) {
+        setWindingRule(rule);
+        types = new byte[initialCapacity];
+        points = new float[initialCapacity * 2];
+    }
+
+    /**
+     * Creates a new GeneralPath from the outline of the given shape.
+     * 
+     * @param shape
+     *            the shape.
+     */
+    public GeneralPath(Shape shape) {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+        PathIterator p = shape.getPathIterator(null);
+        setWindingRule(p.getWindingRule());
+        append(p, false);
+    }
+
+    /**
+     * Sets the winding rule, which determines how to decide whether a point
+     * that isn't on the path itself is inside or outside of the shape.
+     * 
+     * @param rule
+     *            the new winding rule.
+     * @throws IllegalArgumentException
+     *             if the winding rule is neither
+     *             {@link PathIterator#WIND_EVEN_ODD} nor
+     *             {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public void setWindingRule(int rule) {
+        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
+            // awt.209=Invalid winding rule value
+            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
+        }
+        this.rule = rule;
+    }
+
+    /**
+     * Gets the winding rule.
+     * 
+     * @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     *         {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public int getWindingRule() {
+        return rule;
+    }
+
+    /**
+     * Checks the point data buffer sizes to see whether pointCount additional
+     * point-data elements can fit. (Note that the number of point data elements
+     * to add is more than one per point -- it depends on the type of point
+     * being added.) Reallocates the buffers to enlarge the size if necessary.
+     * 
+     * @param pointCount
+     *            the number of point data elements to be added.
+     * @param checkMove
+     *            whether to check for existing points.
+     * @throws IllegalPathStateException
+     *             checkMove is true and the path is currently empty.
+     */
+    void checkBuf(int pointCount, boolean checkMove) {
+        if (checkMove && typeSize == 0) {
+            // awt.20A=First segment should be SEG_MOVETO type
+            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
+        }
+        if (typeSize == types.length) {
+            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
+            System.arraycopy(types, 0, tmp, 0, typeSize);
+            types = tmp;
+        }
+        if (pointSize + pointCount > points.length) {
+            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
+            System.arraycopy(points, 0, tmp, 0, pointSize);
+            points = tmp;
+        }
+    }
+
+    /**
+     * Appends a new point to the end of this general path, disconnected from
+     * the existing path.
+     * 
+     * @param x
+     *            the x coordinate of the next point to append.
+     * @param y
+     *            the y coordinate of the next point to append.
+     */
+    public void moveTo(float x, float y) {
+        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
+            points[pointSize - 2] = x;
+            points[pointSize - 1] = y;
+        } else {
+            checkBuf(2, false);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = x;
+            points[pointSize++] = y;
+        }
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making a
+     * straight line segment from the current endpoint to the given new point.
+     * 
+     * @param x
+     *            the x coordinate of the next point to append.
+     * @param y
+     *            the y coordinate of the next point to append.
+     */
+    public void lineTo(float x, float y) {
+        checkBuf(2, true);
+        types[typeSize++] = PathIterator.SEG_LINETO;
+        points[pointSize++] = x;
+        points[pointSize++] = y;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making a
+     * quadratic curve from the current endpoint to the point (x2, y2) using the
+     * point (x1, y1) as the quadratic curve's control point.
+     * 
+     * @param x1
+     *            the x coordinate of the quadratic curve's control point.
+     * @param y1
+     *            the y coordinate of the quadratic curve's control point.
+     * @param x2
+     *            the x coordinate of the quadratic curve's end point.
+     * @param y2
+     *            the y coordinate of the quadratic curve's end point.
+     */
+    public void quadTo(float x1, float y1, float x2, float y2) {
+        checkBuf(4, true);
+        types[typeSize++] = PathIterator.SEG_QUADTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making a cubic
+     * curve from the current endpoint to the point (x3, y3) using (x1, y1) and
+     * (x2, y2) as control points.
+     * 
+     * @see java.awt.geom.CubicCurve2D
+     * @param x1
+     *            the x coordinate of the new cubic segment's first control
+     *            point.
+     * @param y1
+     *            the y coordinate of the new cubic segment's first control
+     *            point.
+     * @param x2
+     *            the x coordinate of the new cubic segment's second control
+     *            point.
+     * @param y2
+     *            the y coordinate of the new cubic segment's second control
+     *            point.
+     * @param x3
+     *            the x coordinate of the new cubic segment's end point.
+     * @param y3
+     *            the y coordinate of the new cubic segment's end point.
+     */
+    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+        checkBuf(6, true);
+        types[typeSize++] = PathIterator.SEG_CUBICTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+        points[pointSize++] = x3;
+        points[pointSize++] = y3;
+    }
+
+    /**
+     * Appends the type information to declare that the current endpoint closes
+     * the curve.
+     */
+    public void closePath() {
+        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
+            checkBuf(0, true);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+    }
+
+    /**
+     * Appends the outline of the specified shape onto the end of this
+     * GeneralPath.
+     * 
+     * @param shape
+     *            the shape whose outline is to be appended.
+     * @param connect
+     *            true to connect this path's current endpoint to the first
+     *            point of the shape's outline or false to append the shape's
+     *            outline without connecting it.
+     * @throws NullPointerException
+     *             if the shape parameter is null.
+     */
+    public void append(Shape shape, boolean connect) {
+        PathIterator p = shape.getPathIterator(null);
+        append(p, connect);
+    }
+
+    /**
+     * Appends the path defined by the specified PathIterator onto the end of
+     * this GeneralPath.
+     * 
+     * @param path
+     *            the PathIterator that defines the new path to append.
+     * @param connect
+     *            true to connect this path's current endpoint to the first
+     *            point of the shape's outline or false to append the shape's
+     *            outline without connecting it.
+     */
+    public void append(PathIterator path, boolean connect) {
+        while (!path.isDone()) {
+            float coords[] = new float[6];
+            switch (path.currentSegment(coords)) {
+                case PathIterator.SEG_MOVETO:
+                    if (!connect || typeSize == 0) {
+                        moveTo(coords[0], coords[1]);
+                        break;
+                    }
+                    if (types[typeSize - 1] != PathIterator.SEG_CLOSE
+                            && points[pointSize - 2] == coords[0]
+                            && points[pointSize - 1] == coords[1]) {
+                        break;
+                    }
+                    // NO BREAK;
+                case PathIterator.SEG_LINETO:
+                    lineTo(coords[0], coords[1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    quadTo(coords[0], coords[1], coords[2], coords[3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    closePath();
+                    break;
+            }
+            path.next();
+            connect = false;
+        }
+    }
+
+    /**
+     * Gets the current end point of the path.
+     * 
+     * @return the current end point of the path.
+     */
+    public Point2D getCurrentPoint() {
+        if (typeSize == 0) {
+            return null;
+        }
+        int j = pointSize - 2;
+        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
+
+            for (int i = typeSize - 2; i > 0; i--) {
+                int type = types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    break;
+                }
+                j -= pointShift[type];
+            }
+        }
+        return new Point2D.Float(points[j], points[j + 1]);
+    }
+
+    /**
+     * Resets the GeneralPath to being an empty path. The underlying point and
+     * segment data is not deleted but rather the end indices of the data arrays
+     * are set to zero.
+     */
+    public void reset() {
+        typeSize = 0;
+        pointSize = 0;
+    }
+
+    /**
+     * Transform all of the coordinates of this path according to the specified
+     * AffineTransform.
+     * 
+     * @param t
+     *            the AffineTransform.
+     */
+    public void transform(AffineTransform t) {
+        t.transform(points, 0, points, 0, pointSize / 2);
+    }
+
+    /**
+     * Creates a new GeneralPath whose data is given by this path's data
+     * transformed according to the specified AffineTransform.
+     * 
+     * @param t
+     *            the AffineTransform.
+     * @return the new GeneralPath whose data is given by this path's data
+     *         transformed according to the specified AffineTransform.
+     */
+    public Shape createTransformedShape(AffineTransform t) {
+        GeneralPath p = (GeneralPath)clone();
+        if (t != null) {
+            p.transform(t);
+        }
+        return p;
+    }
+
+    public Rectangle2D getBounds2D() {
+        float rx1, ry1, rx2, ry2;
+        if (pointSize == 0) {
+            rx1 = ry1 = rx2 = ry2 = 0.0f;
+        } else {
+            int i = pointSize - 1;
+            ry1 = ry2 = points[i--];
+            rx1 = rx2 = points[i--];
+            while (i > 0) {
+                float y = points[i--];
+                float x = points[i--];
+                if (x < rx1) {
+                    rx1 = x;
+                } else if (x > rx2) {
+                    rx2 = x;
+                }
+                if (y < ry1) {
+                    ry1 = y;
+                } else if (y > ry2) {
+                    ry2 = y;
+                }
+            }
+        }
+        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    /**
+     * Checks the cross count (number of times a ray from the point crosses the
+     * shape's boundary) to determine whether the number of crossings
+     * corresponds to a point inside the shape or not (according to the shape's
+     * path rule).
+     * 
+     * @param cross
+     *            the point's cross count.
+     * @return true if the point is inside the path, or false otherwise.
+     */
+    boolean isInside(int cross) {
+        if (rule == WIND_NON_ZERO) {
+            return Crossing.isInsideNonZero(cross);
+        }
+        return Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(double px, double py) {
+        return isInside(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && isInside(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || isInside(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            GeneralPath p = (GeneralPath)super.clone();
+            p.types = types.clone();
+            p.points = points.clone();
+            return p;
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/IllegalPathStateException.java b/awt/java/awt/geom/IllegalPathStateException.java
new file mode 100644
index 0000000..750ba29
--- /dev/null
+++ b/awt/java/awt/geom/IllegalPathStateException.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 Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+/**
+ * The Class IllegalPathStateException indicates errors where the current state
+ * of a path object is incompatible with the desired action, such as performing
+ * non-trivial actions on an empty path.
+ * 
+ * @since Android 1.0
+ */
+public class IllegalPathStateException extends RuntimeException {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -5158084205220481094L;
+
+    /**
+     * Instantiates a new illegal path state exception.
+     */
+    public IllegalPathStateException() {
+    }
+
+    /**
+     * Instantiates a new illegal path state exception with the specified detail
+     * message.
+     * 
+     * @param s
+     *            the details of the error.
+     */
+    public IllegalPathStateException(String s) {
+        super(s);
+    }
+
+}
diff --git a/awt/java/awt/geom/Line2D.java b/awt/java/awt/geom/Line2D.java
new file mode 100644
index 0000000..fcd51b6
--- /dev/null
+++ b/awt/java/awt/geom/Line2D.java
@@ -0,0 +1,948 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Line2D represents a line whose data is given in high-precision
+ * values appropriate for graphical operations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Line2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of Line2D that has all of its data values
+     * stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends Line2D {
+
+        /**
+         * The x coordinate of the starting point.
+         */
+        public float x1;
+
+        /**
+         * The y coordinate of the starting point.
+         */
+        public float y1;
+
+        /**
+         * The x coordinate of the end point.
+         */
+        public float x2;
+
+        /**
+         * The y coordinate of the end point.
+         */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued Line2D with its data values set to
+         * zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with the specified endpoints.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public Float(float x1, float y1, float x2, float y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with the specified endpoints.
+         * 
+         * @param p1
+         *            the starting point.
+         * @param p2
+         *            the end point.
+         */
+        public Float(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values that define the line.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public void setLine(float x1, float y1, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Float(rx, ry, rw, rh);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Line2D that has all of its data
+     * values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends Line2D {
+
+        /**
+         * The x coordinate of the starting point.
+         */
+        public double x1;
+
+        /**
+         * The y coordinate of the starting point.
+         */
+        public double y1;
+
+        /**
+         * The x coordinate of the end point.
+         */
+        public double x2;
+
+        /**
+         * The y coordinate of the end point.
+         */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued Line2D with its data values set to
+         * zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with the specified endpoints.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point.
+         * @param y1
+         *            the y coordinate of the starting point.
+         * @param x2
+         *            the x coordinate of the end point.
+         * @param y2
+         *            the y coordinate of the end point.
+         */
+        public Double(double x1, double y1, double x2, double y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with the specified endpoints.
+         * 
+         * @param p1
+         *            the starting point.
+         * @param p2
+         *            the end point.
+         */
+        public Double(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Double(rx, ry, rw, rh);
+        }
+    }
+
+    /*
+     * Line2D path iterator
+     */
+    /**
+     * The subclass of PathIterator to traverse a Line2D.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The x coordinate of the start line point.
+         */
+        double x1;
+
+        /**
+         * The y coordinate of the start line point.
+         */
+        double y1;
+
+        /**
+         * The x coordinate of the end line point.
+         */
+        double x2;
+
+        /**
+         * The y coordinate of the end line point.
+         */
+        double y2;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new Line2D.Iterator for given line and transformation.
+         * 
+         * @param l
+         *            the source Line2D object.
+         * @param at
+         *            the AffineTransform object to apply rectangle path.
+         */
+        Iterator(Line2D l, AffineTransform at) {
+            this.x1 = l.getX1();
+            this.y1 = l.getY1();
+            this.x2 = l.getX2();
+            this.y2 = l.getY2();
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x1;
+                coords[1] = y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = x2;
+                coords[1] = y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)x1;
+                coords[1] = (float)y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = (float)x2;
+                coords[1] = (float)y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Line2D.
+     */
+    protected Line2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point.
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point.
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x2.
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point.
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the p the starting point.
+     * 
+     * @return the p the starting point.
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the p end point.
+     * 
+     * @return the p end point.
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point.
+     * @param y1
+     *            the y coordinate of the starting point.
+     * @param x2
+     *            the x coordinate of the end point.
+     * @param y2
+     *            the y coordinate of the end point.
+     */
+    public abstract void setLine(double x1, double y1, double x2, double y2);
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param p1
+     *            the starting point.
+     * @param p2
+     *            the end point.
+     */
+    public void setLine(Point2D p1, Point2D p2) {
+        setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the line's endpoints by copying the data from another Line2D.
+     * 
+     * @param line
+     *            the Line2D to copy the endpoint data from.
+     */
+    public void setLine(Line2D line) {
+        setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    /**
+     * Tells where the point is with respect to the line segment, given the
+     * orientation of the line segment. If the ray found by extending the line
+     * segment from its starting point is rotated, this method tells whether the
+     * ray should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the point is
+     * on the line segment, it's 1 if the point is on the ray or if the ray
+     * should rotate in a counter-clockwise direction to get to the point, and
+     * it's -1 if the ray should rotate in a clockwise direction to get to the
+     * point or if the point is on the line determined by the line segment but
+     * not on the ray from the segment's starting point and through its end
+     * point.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the line segment.
+     * @param y1
+     *            the y coordinate of the starting point of the line segment.
+     * @param x2
+     *            the x coordinate of the end point of the line segment.
+     * @param y2
+     *            the y coordinate of the end point of the line segment.
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the p coordinate of the test point.
+     * @return the value that describes where the point is with respect to the
+     *         line segment, given the orientation of the line segment.
+     */
+    public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2-x1, y2-y1) P = (px-x1, py-y1)
+         */
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double t = px * y2 - py * x2; // PxA
+        if (t == 0.0) {
+            t = px * x2 + py * y2; // P*A
+            if (t > 0.0) {
+                px -= x2; // B-A
+                py -= y2;
+                t = px * x2 + py * y2; // (P-A)*A
+                if (t < 0.0) {
+                    t = 0.0;
+                }
+            }
+        }
+
+        return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, given the
+     * orientation of this line segment. If the ray found by extending the line
+     * segment from its starting point is rotated, this method tells whether the
+     * ray should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the point is
+     * on the line segment, it's 1 if the point is on the ray or if the ray
+     * should rotate in a counter-clockwise direction to get to the point, and
+     * it's -1 if the ray should rotate in a clockwise direction to get to the
+     * point or if the point is on the line determined by the line segment but
+     * not on the ray from the segment's starting point and through its end
+     * point.
+     * 
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the p coordinate of the test point.
+     * @return the value that describes where the point is with respect to this
+     *         line segment, given the orientation of this line segment.
+     */
+    public int relativeCCW(double px, double py) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, given the
+     * orientation of this line segment. If the ray found by extending the line
+     * segment from its starting point is rotated, this method tells whether the
+     * ray should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the point is
+     * on the line segment, it's 1 if the point is on the ray or if the ray
+     * should rotate in a counter-clockwise direction to get to the point, and
+     * it's -1 if the ray should rotate in a clockwise direction to get to the
+     * point or if the point is on the line determined by the line segment but
+     * not on the ray from the segment's starting point and through its end
+     * point.
+     * 
+     * @param p
+     *            the test point.
+     * @return the value that describes where the point is with respect to this
+     *         line segment, given the orientation of this line segment.
+     */
+    public int relativeCCW(Point2D p) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Tells whether the two line segments cross.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the first segment.
+     * @param y1
+     *            the y coordinate of the starting point of the first segment.
+     * @param x2
+     *            the x coordinate of the end point of the first segment.
+     * @param y2
+     *            the y coordinate of the end point of the first segment.
+     * @param x3
+     *            the x coordinate of the starting point of the second segment.
+     * @param y3
+     *            the y coordinate of the starting point of the second segment.
+     * @param x4
+     *            the x coordinate of the end point of the second segment.
+     * @param y4
+     *            the y coordinate of the end point of the second segment.
+     * @return true, if the two line segments cross.
+     */
+    public static boolean linesIntersect(double x1, double y1, double x2, double y2, double x3,
+            double y3, double x4, double y4) {
+        /*
+         * A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
+         * y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B Result
+         * is ((AxB) (AxC) <=0) and ((DxE) (DxF) <= 0) DxE = (C-B)x(-B) =
+         * BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB = AxB+BxC-AxC
+         */
+
+        x2 -= x1; // A
+        y2 -= y1;
+        x3 -= x1; // B
+        y3 -= y1;
+        x4 -= x1; // C
+        y4 -= y1;
+
+        double AvB = x2 * y3 - x3 * y2;
+        double AvC = x2 * y4 - x4 * y2;
+
+        // Online
+        if (AvB == 0.0 && AvC == 0.0) {
+            if (x2 != 0.0) {
+                return (x4 * x3 <= 0.0)
+                        || ((x3 * x2 >= 0.0) && (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2
+                                || x4 >= x2));
+            }
+            if (y2 != 0.0) {
+                return (y4 * y3 <= 0.0)
+                        || ((y3 * y2 >= 0.0) && (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2
+                                || y4 >= y2));
+            }
+            return false;
+        }
+
+        double BvC = x3 * y4 - x4 * y3;
+
+        return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the test segment.
+     * @param y1
+     *            the y coordinate of the starting point of the test segment.
+     * @param x2
+     *            the x coordinate of the end point of the test segment.
+     * @param y2
+     *            the y coordinate of the end point of the test segment.
+     * @return true, if the specified line segments crosses this line segment.
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param l
+     *            the test segment.
+     * @return true, if the specified line segments crosses this line segment.
+     * @throws NullPointerException
+     *             if l is null.
+     */
+    public boolean intersectsLine(Line2D l) {
+        return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the line segment.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the line segment.
+     * @param y1
+     *            the y coordinate of the starting point of the line segment.
+     * @param x2
+     *            the x coordinate of the end point of the line segment.
+     * @param y2
+     *            the y coordinate of the end point of the line segment.
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the the square of the distance between the point and the line
+     *         segment.
+     */
+    public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px,
+            double py) {
+        /*
+         * A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
+         */
+        x2 -= x1; // A = (x2, y2)
+        y2 -= y1;
+        px -= x1; // P = (px, py)
+        py -= y1;
+        double dist;
+        if (px * x2 + py * y2 <= 0.0) { // P*A
+            dist = px * px + py * py;
+        } else {
+            px = x2 - px; // P = A - P = (x2 - px, y2 - py)
+            py = y2 - py;
+            if (px * x2 + py * y2 <= 0.0) { // P*A
+                dist = px * px + py * py;
+            } else {
+                dist = px * y2 - py * x2;
+                dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
+            }
+        }
+        if (dist < 0) {
+            dist = 0;
+        }
+        return dist;
+    }
+
+    /**
+     * Gives the distance between the point and the line segment.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the line segment.
+     * @param y1
+     *            the y coordinate of the starting point of the line segment.
+     * @param x2
+     *            the x coordinate of the end point of the line segment.
+     * @param y2
+     *            the y coordinate of the end point of the line segment.
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the the distance between the point and the line segment.
+     */
+    public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and this line segment.
+     * 
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the the square of the distance between the point and this line
+     *         segment.
+     */
+    public double ptSegDistSq(double px, double py) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and this line segment.
+     * 
+     * @param p
+     *            the test point.
+     * @return the square of the distance between the point and this line
+     *         segment.
+     */
+    public double ptSegDistSq(Point2D p) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and this line segment.
+     * 
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the distance between the point and this line segment.
+     */
+    public double ptSegDist(double px, double py) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and this line segment.
+     * 
+     * @param p
+     *            the test point.
+     * @return the distance between the point and this line segment.
+     */
+    public double ptSegDist(Point2D p) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the line.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the line segment.
+     * @param y1
+     *            the y coordinate of the starting point of the line segment.
+     * @param x2
+     *            the x coordinate of the end point of the line segment.
+     * @param y2
+     *            the y coordinate of the end point of the line segment.
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the square of the distance between the point and the line.
+     */
+    public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px,
+            double py) {
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double s = px * y2 - py * x2;
+        return s * s / (x2 * x2 + y2 * y2);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the line.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the line segment.
+     * @param y1
+     *            the y coordinate of the starting point of the line segment.
+     * @param x2
+     *            the x coordinate of the end point of the line segment.
+     * @param y2
+     *            the y coordinate of the end point of the line segment.
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the square of the distance between the point and the line.
+     */
+    public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and the line
+     * determined by this Line2D.
+     * 
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the square of the distance between the point and the line
+     *         determined by this Line2D.
+     */
+    public double ptLineDistSq(double px, double py) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the line
+     * determined by this Line2D.
+     * 
+     * @param p
+     *            the test point.
+     * @return the square of the distance between the point and the line
+     *         determined by this Line2D.
+     */
+    public double ptLineDistSq(Point2D p) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and the line determined by this
+     * Line2D.
+     * 
+     * @param px
+     *            the x coordinate of the test point.
+     * @param py
+     *            the y coordinate of the test point.
+     * @return the distance between the point and the line determined by this
+     *         Line2D.
+     */
+    public double ptLineDist(double px, double py) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and the line determined by this
+     * Line2D.
+     * 
+     * @param p
+     *            the test point.
+     * @return the distance between the point and the line determined by this
+     *         Line2D.
+     */
+    public double ptLineDist(Point2D p) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    public boolean contains(double px, double py) {
+        return false;
+    }
+
+    public boolean contains(Point2D p) {
+        return false;
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return false;
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        return false;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new Iterator(this, at);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/NoninvertibleTransformException.java b/awt/java/awt/geom/NoninvertibleTransformException.java
new file mode 100644
index 0000000..a4e6f0f
--- /dev/null
+++ b/awt/java/awt/geom/NoninvertibleTransformException.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 Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+/**
+ * The Class NoninvertibleTransformException is the exception that is thrown
+ * when an action requires inverting an {@link AffineTransform} that is not
+ * invertible (has determinant 0).
+ * 
+ * @since Android 1.0
+ */
+public class NoninvertibleTransformException extends java.lang.Exception {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 6137225240503990466L;
+
+    /**
+     * Instantiates a new non-invertible transform exception.
+     * 
+     * @param s
+     *            the error message.
+     */
+    public NoninvertibleTransformException(String s) {
+        super(s);
+    }
+
+}
diff --git a/awt/java/awt/geom/PathIterator.java b/awt/java/awt/geom/PathIterator.java
new file mode 100644
index 0000000..2d1c0ff
--- /dev/null
+++ b/awt/java/awt/geom/PathIterator.java
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+/**
+ * The Interface PathIterator represents an iterator object that can be used to
+ * traverse the outline of a {@link java.awt.Shape}. It returns points along the
+ * boundary of the Shape which may be actual vertices (in the case of a shape
+ * made of line segments) or may be points on a curved segment with the distance
+ * between the points determined by a chosen flattening factor.
+ * <p>
+ * If the shape is closed, the outline is traversed in the counter-clockwise
+ * direction. That means that moving forward along the boundary is to travel in
+ * such a way that the interior of the shape is to the left of the outline path
+ * and the exterior of the shape is to the right of the outline path. The
+ * interior and exterior of the shape are determined by a winding rule.
+ * </p>
+ * 
+ * @since Android 1.0
+ */
+public interface PathIterator {
+
+    /**
+     * The Constant WIND_EVEN_ODD indicates the winding rule that says that a
+     * point is outside the shape if any infinite ray from the point crosses the
+     * outline of the shape an even number of times, otherwise it is inside.
+     */
+    public static final int WIND_EVEN_ODD = 0;
+
+    /**
+     * The Constant WIND_NON_ZERO indicates the winding rule that says that a
+     * point is inside the shape if every infinite ray starting from that point
+     * crosses the outline of the shape a non-zero number of times.
+     */
+    public static final int WIND_NON_ZERO = 1;
+
+    /**
+     * The Constant SEG_MOVETO indicates that to follow the shape's outline from
+     * the previous point to the current point, the cursor (traversal point)
+     * should be placed directly on the current point.
+     */
+    public static final int SEG_MOVETO = 0;
+
+    /**
+     * The Constant SEG_LINETO indicates that to follow the shape's outline from
+     * the previous point to the current point, the cursor (traversal point)
+     * should follow a straight line.
+     */
+    public static final int SEG_LINETO = 1;
+
+    /**
+     * The Constant SEG_QUADTO indicates that to follow the shape's outline from
+     * the previous point to the current point, the cursor (traversal point)
+     * should follow a quadratic curve.
+     */
+    public static final int SEG_QUADTO = 2;
+
+    /**
+     * The Constant SEG_CUBICTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal
+     * point) should follow a cubic curve.
+     */
+    public static final int SEG_CUBICTO = 3;
+
+    /**
+     * The Constant SEG_CLOSE indicates that the previous point was the end of
+     * the shape's outline.
+     */
+    public static final int SEG_CLOSE = 4;
+
+    /**
+     * Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     * {@link PathIterator#WIND_NON_ZERO}.
+     * 
+     * @return the winding rule.
+     */
+    public int getWindingRule();
+
+    /**
+     * Checks if this PathIterator has been completely traversed.
+     * 
+     * @return true, if this PathIterator has been completely traversed.
+     */
+    public boolean isDone();
+
+    /**
+     * Tells this PathIterator to skip to the next segment.
+     */
+    public void next();
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline
+     * and a flag that indicates what kind of segment to use in order to connect
+     * the previous vertex point to the current vertex point to form the current
+     * segment.
+     * 
+     * @param coords
+     *            the array that the coordinates of the end point of the current
+     *            segment are written into.
+     * @return the flag that indicates how to follow the shape's outline from
+     *         the previous point to the current one, chosen from the following
+     *         constants: {@link PathIterator#SEG_MOVETO},
+     *         {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
+     *         {@link PathIterator#SEG_CUBICTO}, or
+     *         {@link PathIterator#SEG_CLOSE}.
+     */
+    public int currentSegment(float[] coords);
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline
+     * and a flag that indicates what kind of segment to use in order to connect
+     * the previous vertex point to the current vertex point to form the current
+     * segment.
+     * 
+     * @param coords
+     *            the array that the coordinates of the end point of the current
+     *            segment are written into.
+     * @return the flag that indicates how to follow the shape's outline from
+     *         the previous point to the current one, chosen from the following
+     *         constants: {@link PathIterator#SEG_MOVETO},
+     *         {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
+     *         {@link PathIterator#SEG_CUBICTO}, or
+     *         {@link PathIterator#SEG_CLOSE}.
+     */
+    public int currentSegment(double[] coords);
+
+}
diff --git a/awt/java/awt/geom/Point2D.java b/awt/java/awt/geom/Point2D.java
new file mode 100644
index 0000000..f7026c8
--- /dev/null
+++ b/awt/java/awt/geom/Point2D.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 Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Point2D represents a point whose data is given in high-precision
+ * values appropriate for graphical operations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Point2D implements Cloneable {
+
+    /**
+     * The Class Float is the subclass of Point2D that has all of its data
+     * values stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends Point2D {
+
+        /**
+         * The x coordinate.
+         */
+        public float x;
+
+        /**
+         * The y coordinate.
+         */
+        public float y;
+
+        /**
+         * Instantiates a new float-valued Point2D with its data set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Point2D with the specified
+         * coordinates.
+         * 
+         * @param x
+         *            the x coordinate.
+         * @param y
+         *            the y coordinate.
+         */
+        public Float(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        /**
+         * Sets the point's coordinates.
+         * 
+         * @param x
+         *            the x coordinate.
+         * @param y
+         *            the y coordinate.
+         */
+        public void setLocation(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = (float)x;
+            this.y = (float)y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Point2D that has all of its data
+     * values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends Point2D {
+
+        /**
+         * The x coordinate.
+         */
+        public double x;
+
+        /**
+         * The y coordinate.
+         */
+        public double y;
+
+        /**
+         * Instantiates a new double-valued Point2D with its data set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Point2D with the specified
+         * coordinates.
+         * 
+         * @param x
+         *            the x coordinate.
+         * @param y
+         *            the y coordinate.
+         */
+        public Double(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * Instantiates a new Point2D.
+     */
+    protected Point2D() {
+    }
+
+    /**
+     * Gets the x coordinate.
+     * 
+     * @return the x coordinate.
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate.
+     * 
+     * @return the y coordinate.
+     */
+    public abstract double getY();
+
+    /**
+     * Sets the point's coordinates.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     */
+    public abstract void setLocation(double x, double y);
+
+    /**
+     * Sets the point's coordinates by copying them from another point.
+     * 
+     * @param p
+     *            the point to copy the data from.
+     */
+    public void setLocation(Point2D p) {
+        setLocation(p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the square of the distance between the two specified points.
+     * 
+     * @param x1
+     *            the x coordinate of the first point.
+     * @param y1
+     *            the y coordinate of the first point.
+     * @param x2
+     *            the x coordinate of the second point.
+     * @param y2
+     *            the y coordinate of the second point.
+     * @return the square of the distance between the two specified points.
+     */
+    public static double distanceSq(double x1, double y1, double x2, double y2) {
+        x2 -= x1;
+        y2 -= y1;
+        return x2 * x2 + y2 * y2;
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified
+     * point.
+     * 
+     * @param px
+     *            the x coordinate of the point.
+     * @param py
+     *            the y coordinate of the point.
+     * @return the square of the distance between this point and the specified
+     *         point.
+     */
+    public double distanceSq(double px, double py) {
+        return Point2D.distanceSq(getX(), getY(), px, py);
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified
+     * point.
+     * 
+     * @param p
+     *            the other point.
+     * @return the square of the distance between this point and the specified
+     *         point.
+     */
+    public double distanceSq(Point2D p) {
+        return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the distance between the two specified points.
+     * 
+     * @param x1
+     *            the x coordinate of the first point.
+     * @param y1
+     *            the y coordinate of the first point.
+     * @param x2
+     *            the x coordinate of the second point.
+     * @param y2
+     *            the y coordinate of the second point.
+     * @return the distance between the two specified points.
+     */
+    public static double distance(double x1, double y1, double x2, double y2) {
+        return Math.sqrt(distanceSq(x1, y1, x2, y2));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param px
+     *            the x coordinate of the point.
+     * @param py
+     *            the y coordinate of the point.
+     * @return the distance between this point and the specified point.
+     */
+    public double distance(double px, double py) {
+        return Math.sqrt(distanceSq(px, py));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param p
+     *            the other point.
+     * @return the distance between this point and the specified point.
+     */
+    public double distance(Point2D p) {
+        return Math.sqrt(distanceSq(p));
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point2D) {
+            Point2D p = (Point2D)obj;
+            return getX() == p.getX() && getY() == p.getY();
+        }
+        return false;
+    }
+}
diff --git a/awt/java/awt/geom/QuadCurve2D.java b/awt/java/awt/geom/QuadCurve2D.java
new file mode 100644
index 0000000..7a86a48
--- /dev/null
+++ b/awt/java/awt/geom/QuadCurve2D.java
@@ -0,0 +1,918 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class QuadCurve2D is a Shape that represents a segment of a quadratic
+ * (Bezier) curve. The curved segment is determined by three points: a start
+ * point, an end point, and a control point. The line from the control point to
+ * the starting point gives the tangent to the curve at the starting point, and
+ * the line from the control point to the end point gives the tangent to the
+ * curve at the end point.
+ * 
+ * @since Android 1.0
+ */
+public abstract class QuadCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of QuadCurve2D that has all of its data
+     * values stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends QuadCurve2D {
+
+        /**
+         * The x coordinate of the starting point of the curved segment.
+         */
+        public float x1;
+
+        /**
+         * The y coordinate of the starting point of the curved segment.
+         */
+        public float y1;
+
+        /**
+         * The x coordinate of the control point.
+         */
+        public float ctrlx;
+
+        /**
+         * The y coordinate of the control point.
+         */
+        public float ctrly;
+
+        /**
+         * The x coordinate of the end point of the curved segment.
+         */
+        public float x2;
+
+        /**
+         * The y coordinate of the end point of the curved segment.
+         */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with all coordinate
+         * values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point of the curved
+         *            segment.
+         * @param y1
+         *            the y coordinate of the starting point of the curved
+         *            segment.
+         * @param ctrlx
+         *            the x coordinate of the control point.
+         * @param ctrly
+         *            the y coordinate of the control point.
+         * @param x2
+         *            the x coordinate of the end point of the curved segment.
+         * @param y2
+         *            the y coordinate of the end point of the curved segment.
+         */
+        public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Float(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx = (float)ctrlx;
+            this.ctrly = (float)ctrly;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point of the curved
+         *            segment.
+         * @param y1
+         *            the y coordinate of the starting point of the curved
+         *            segment.
+         * @param ctrlx
+         *            the x coordinate of the control point.
+         * @param ctrly
+         *            the y coordinate of the control point.
+         * @param x2
+         *            the x coordinate of the end point of the curved segment.
+         * @param y2
+         *            the y coordinate of the end point of the curved segment.
+         */
+        public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            float ry0 = Math.min(Math.min(y1, y2), ctrly);
+            float rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            float ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of QuadCurve2D that has all of its data
+     * values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends QuadCurve2D {
+
+        /**
+         * The x coordinate of the starting point of the curved segment.
+         */
+        public double x1;
+
+        /**
+         * The y coordinate of the starting point of the curved segment.
+         */
+        public double y1;
+
+        /**
+         * The x coordinate of the control point.
+         */
+        public double ctrlx;
+
+        /**
+         * The y coordinate of the control point.
+         */
+        public double ctrly;
+
+        /**
+         * The x coordinate of the end point of the curved segment.
+         */
+        public double x2;
+
+        /**
+         * The y coordinate of the end point of the curved segment.
+         */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with all coordinate
+         * values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1
+         *            the x coordinate of the starting point of the curved
+         *            segment.
+         * @param y1
+         *            the y coordinate of the starting point of the curved
+         *            segment.
+         * @param ctrlx
+         *            the x coordinate of the control point.
+         * @param ctrly
+         *            the y coordinate of the control point.
+         * @param x2
+         *            the x coordinate of the end point of the curved segment.
+         * @param y2
+         *            the y coordinate of the end point of the curved segment.
+         */
+        public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Double(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            double ry0 = Math.min(Math.min(y1, y2), ctrly);
+            double rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            double ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /*
+     * QuadCurve2D path iterator
+     */
+    /**
+     * The PathIterator for a Quad2D curve.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The source QuadCurve2D object.
+         */
+        QuadCurve2D c;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new QuadCurve2D.Iterator for given curve and
+         * transformation
+         * 
+         * @param q
+         *            the source QuadCurve2D object.
+         * @param t
+         *            the AffineTransform that acts on the coordinates before
+         *            returning them (or null).
+         */
+        Iterator(QuadCurve2D q, AffineTransform t) {
+            this.c = q;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return (index > 1);
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = c.getCtrlX();
+                coords[1] = c.getCtrlY();
+                coords[2] = c.getX2();
+                coords[3] = c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = (float)c.getCtrlX();
+                coords[1] = (float)c.getCtrlY();
+                coords[2] = (float)c.getX2();
+                coords[3] = (float)c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new quadratic curve.
+     */
+    protected QuadCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point.
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point.
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point.
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the control point.
+     * 
+     * @return the x coordinate of the control point.
+     */
+    public abstract double getCtrlX();
+
+    /**
+     * Gets the y coordinate of the control point.
+     * 
+     * @return y coordinate of the control point.
+     */
+    public abstract double getCtrlY();
+
+    /**
+     * Gets the control point.
+     * 
+     * @return the control point.
+     */
+    public abstract Point2D getCtrlPt();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point.
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point.
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point.
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the curved segment.
+     * @param y1
+     *            the y coordinate of the starting point of the curved segment.
+     * @param ctrlx
+     *            the x coordinate of the control point.
+     * @param ctrly
+     *            the y coordinate of the control point.
+     * @param x2
+     *            the x coordinate of the end point of the curved segment.
+     * @param y2
+     *            the y coordinate of the end point of the curved segment.
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2,
+            double y2);
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param p1
+     *            the starting point of the curved segment.
+     * @param cp
+     *            the control point.
+     * @param p2
+     *            the end point of the curved segment.
+     * @throws NullPointerException
+     *             if any of the three points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
+        setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array of values.
+     * The values are read in the same order as the arguments of the method
+     * {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of values containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code coords.length} < offset + 6.
+     * @throws NullPointerException
+     *             if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array of points.
+     * The values are read in the same order as the arguments of the method
+     * {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}.
+     * 
+     * @param points
+     *            the array of points containing the new coordinates.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if points.length < offset + 3.
+     * @throws NullPointerException
+     *             if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(),
+                points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another QuadCurve2D.
+     * 
+     * @param curve
+     *            the curve to copy the data points from.
+     * @throws NullPointerException
+     *             if the curve is null.
+     */
+    public void setCurve(QuadCurve2D curve) {
+        setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX(), curve.getCtrlY(), curve.getX2(),
+                curve.getY2());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the straight
+     * line segment connecting the start point and the end point for this curve.
+     * 
+     * @return the square of the distance from the control point to the straight
+     *         line segment connecting the start point and the end point.
+     */
+    public double getFlatnessSq() {
+        return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the straight
+     * line segment connecting the start point and the end point.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the curved segment.
+     * @param y1
+     *            the y coordinate of the starting point of the curved segment.
+     * @param ctrlx
+     *            the x coordinate of the control point.
+     * @param ctrly
+     *            the y coordinate of the control point.
+     * @param x2
+     *            the x coordinate of the end point of the curved segment.
+     * @param y2
+     *            the y coordinate of the end point of the curved segment.
+     * @return the square of the distance from the control point to the straight
+     *         line segment connecting the start point and the end point.
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2,
+            double y2) {
+        return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the straight
+     * line segment connecting the start point and the end point by reading the
+     * coordinates of the points from an array of values. The values are read in
+     * the same order as the arguments of the method
+     * {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of points containing the coordinates to use for the
+     *            calculation
+     * @param offset
+     *            the offset of the data to read within the array
+     * @return the square of the distance from the control point to the straight
+     *         line segment connecting the start point and the end point.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code coords.length} < offset + 6.
+     * @throws NullPointerException
+     *             if the coordinate array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], coords[offset + 4],
+                coords[offset + 5], coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Gets the distance from the control point to the straight line segment
+     * connecting the start point and the end point of this QuadCurve2D.
+     * 
+     * @return the the distance from the control point to the straight line
+     *         segment connecting the start point and the end point of this
+     *         QuadCurve2D.
+     */
+    public double getFlatness() {
+        return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the distance from the control point to the straight line segment
+     * connecting the start point and the end point.
+     * 
+     * @param x1
+     *            the x coordinate of the starting point of the curved segment.
+     * @param y1
+     *            the y coordinate of the starting point of the curved segment.
+     * @param ctrlx
+     *            the x coordinate of the control point.
+     * @param ctrly
+     *            the y coordinate of the control point.
+     * @param x2
+     *            the x coordinate of the end point of the curved segment.
+     * @param y2
+     *            the y coordinate of the end point of the curved segment.
+     * @return the the distance from the control point to the straight line
+     *         segment connecting the start point and the end point.
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx, double ctrly, double x2,
+            double y2) {
+        return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the the distance from the control point to the straight line segment
+     * connecting the start point and the end point. The values are read in the
+     * same order as the arguments of the method
+     * {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}
+     * .
+     * 
+     * @param coords
+     *            the array of points containing the coordinates to use for the
+     *            calculation.
+     * @param offset
+     *            the offset of the data to read within the array.
+     * @return the the distance from the control point to the straight line
+     *         segment connecting the start point and the end point.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {code coords.length} < offset + 6.
+     * @throws NullPointerException
+     *             if the coordinate array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1], coords[offset + 4],
+                coords[offset + 5], coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing this curve in two.
+     * The division point is the point on the curve that is closest to this
+     * curve's control point. The data of this curve is left unchanged.
+     * 
+     * @param left
+     *            the QuadCurve2D where the left (start) segment's data is
+     *            written.
+     * @param right
+     *            the QuadCurve2D where the right (end) segment's data is
+     *            written.
+     * @throws NullPointerException
+     *             if either curve is null.
+     */
+    public void subdivide(QuadCurve2D left, QuadCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source curve in
+     * two. The division point is the point on the curve that is closest to the
+     * source curve's control point. The data of the source curve is left
+     * unchanged.
+     * 
+     * @param src
+     *            the curve that provides the initial data.
+     * @param left
+     *            the QuadCurve2D where the left (start) segment's data is
+     *            written.
+     * @param right
+     *            the QuadCurve2D where the right (end) segment's data is
+     *            written.
+     * @throws NullPointerException
+     *             if one of the curves is null.
+     */
+    public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx = src.getCtrlX();
+        double cy = src.getCtrlY();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source curve in
+     * two. The division point is the point on the curve that is closest to the
+     * source curve's control point. The data for the three curves is read and
+     * written from arrays of values in the usual order: x1, y1, cx, cy, x2, y2.
+     * 
+     * @param src
+     *            the array that gives the data values for the source curve.
+     * @param srcoff
+     *            the offset in the src array to read the values from.
+     * @param left
+     *            the array where the coordinates of the start curve should be
+     *            written.
+     * @param leftOff
+     *            the offset in the left array to start writing the values.
+     * @param right
+     *            the array where the coordinates of the end curve should be
+     *            written.
+     * @param rightOff
+     *            the offset in the right array to start writing the values.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code src.length} < srcoff + 6 or if {@code left.length}
+     *             < leftOff + 6 or if {@code right.length} < rightOff + 6.
+     * @throws NullPointerException
+     *             if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcoff, double left[], int leftOff,
+            double right[], int rightOff) {
+        double x1 = src[srcoff + 0];
+        double y1 = src[srcoff + 1];
+        double cx = src[srcoff + 2];
+        double cy = src[srcoff + 3];
+        double x2 = src[srcoff + 4];
+        double y2 = src[srcoff + 5];
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = cx;
+            left[leftOff + 5] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = cx2;
+            right[rightOff + 3] = cy2;
+            right[rightOff + 4] = x2;
+            right[rightOff + 5] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is accomplished by
+     * finding the (real) values of x that solve the following equation:
+     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into
+     * the array eqn starting from the index 0 in the array. The return value
+     * tells how many array elements have been changed by this method call.
+     * 
+     * @param eqn
+     *            an array containing the coefficients of the quadratic
+     *            polynomial to solve.
+     * @return the number of roots of the quadratic polynomial.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code eqn.length} < 3.
+     * @throws NullPointerException
+     *             if the array is null.
+     */
+    public static int solveQuadratic(double eqn[]) {
+        return solveQuadratic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is accomplished by
+     * finding the (real) values of x that solve the following equation:
+     * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the
+     * array res starting from the index 0 in the array. The return value tells
+     * how many array elements have been written by this method call.
+     * 
+     * @param eqn
+     *            an array containing the coefficients of the quadratic
+     *            polynomial to solve.
+     * @param res
+     *            the array that this method writes the results into.
+     * @return the number of roots of the quadratic polynomial.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if {@code eqn.length} < 3 or if {@code res.length} is less
+     *             than the number of roots.
+     * @throws NullPointerException
+     *             if either array is null.
+     */
+    public static int solveQuadratic(double eqn[], double res[]) {
+        return Crossing.solveQuad(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/Rectangle2D.java b/awt/java/awt/geom/Rectangle2D.java
new file mode 100644
index 0000000..8166134
--- /dev/null
+++ b/awt/java/awt/geom/Rectangle2D.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.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Rectangle2D represents a rectangle whose coordinates are given with
+ * the correct precision to be used with the Graphics2D classes.
+ * 
+ * @since Android 1.0
+ */
+public abstract class Rectangle2D extends RectangularShape {
+
+    /**
+     * The Constant OUT_LEFT is a mask that is used to indicate that a given
+     * point is outside the rectangle and to its left.
+     */
+    public static final int OUT_LEFT = 1;
+
+    /**
+     * The Constant OUT_TOP is a mask that is used to indicate that a given
+     * point is outside the rectangle and above it.
+     */
+    public static final int OUT_TOP = 2;
+
+    /**
+     * The Constant OUT_RIGHT is a mask that is used to indicate that a given
+     * point is outside the rectangle and to its right.
+     */
+    public static final int OUT_RIGHT = 4;
+
+    /**
+     * The Constant OUT_BOTTOM is a mask that is used to indicate that a given
+     * point is outside the rectangle and above it.
+     */
+    public static final int OUT_BOTTOM = 8;
+
+    /**
+     * The Class Float is the subclass of Rectangle2D that represents a
+     * rectangle whose data values are given as floats (with float-level
+     * precision).
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends Rectangle2D {
+
+        /**
+         * The x coordinate of the rectangle's upper left corner.
+         */
+        public float x;
+
+        /**
+         * The y coordinate of the rectangle's upper left corner.
+         */
+        public float y;
+
+        /**
+         * The width of the rectangle.
+         */
+        public float width;
+
+        /**
+         * The height of the rectangle.
+         */
+        public float height;
+
+        /**
+         * Instantiates a new empty rectangle with float-precision data fields.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the specified float-precision data.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         */
+        public Float(float x, float y, float width, float height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the rectangle's data to the given values.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         */
+        public void setRect(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = (float)r.getX();
+            this.y = (float)r.getY();
+            this.width = (float)r.getWidth();
+            this.height = (float)r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0f) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else if (px < x) {
+                code |= OUT_LEFT;
+            } else if (px > x + width) {
+                code |= OUT_RIGHT;
+            }
+
+            if (height <= 0.0f) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else if (py < y) {
+                code |= OUT_TOP;
+            } else if (py > y + height) {
+                code |= OUT_BOTTOM;
+            }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Float(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.union(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be
+            // obtained in the following way
+            // System.out.println(new Rectangle2D.Float().toString())
+            return getClass().getName()
+                    + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Rectangle2D that represents a
+     * rectangle whose data values are given as doubles (with
+     * double-precision-level precision).
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends Rectangle2D {
+
+        /**
+         * The x coordinate of the rectangle's upper left corner.
+         */
+        public double x;
+
+        /**
+         * The y coordinate of the rectangle's upper left corner.
+         */
+        public double y;
+
+        /**
+         * The width of the rectangle.
+         */
+        public double width;
+
+        /**
+         * The height of the rectangle.
+         */
+        public double height;
+
+        /**
+         * Instantiates a new empty rectangle with double-precision data fields.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the given double values.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         */
+        public Double(double x, double y, double width, double height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else if (px < x) {
+                code |= OUT_LEFT;
+            } else if (px > x + width) {
+                code |= OUT_RIGHT;
+            }
+
+            if (height <= 0.0) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else if (py < y) {
+                code |= OUT_TOP;
+            } else if (py > y + height) {
+                code |= OUT_BOTTOM;
+            }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Double(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst = new Rectangle2D.Double();
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dest = new Rectangle2D.Double();
+            Rectangle2D.union(this, r, dest);
+            return dest;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be
+            // obtained in the following way
+            // System.out.println(new Rectangle2D.Double().toString())
+            return getClass().getName()
+                    + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Iterator provides access to the coordinates of the
+     * Rectangle2D's boundary modified by an AffineTransform.
+     */
+    class Iterator implements PathIterator {
+
+        /**
+         * The x coordinate of the rectangle's upper left corner.
+         */
+        double x;
+
+        /**
+         * The y coordinate of the rectangle's upper left corner.
+         */
+        double y;
+
+        /**
+         * The width of the rectangle.
+         */
+        double width;
+
+        /**
+         * The height of the rectangle.
+         */
+        double height;
+
+        /**
+         * The AffineTransform that is used to modify the coordinates that are
+         * returned by the path iterator.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new Rectangle2D.Iterator for given rectangle and
+         * transformation.
+         * 
+         * @param r
+         *            the source Rectangle2D object.
+         * @param at
+         *            the AffineTransform object to apply to the coordinates
+         *            before returning them.
+         */
+        Iterator(Rectangle2D r, AffineTransform at) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+            this.t = at;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x;
+                coords[1] = y;
+            } else {
+                type = SEG_LINETO;
+                switch (index) {
+                    case 1:
+                        coords[0] = x + width;
+                        coords[1] = y;
+                        break;
+                    case 2:
+                        coords[0] = x + width;
+                        coords[1] = y + height;
+                        break;
+                    case 3:
+                        coords[0] = x;
+                        coords[1] = y + height;
+                        break;
+                    case 4:
+                        coords[0] = x;
+                        coords[1] = y;
+                        break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+                type = SEG_MOVETO;
+            } else {
+                type = SEG_LINETO;
+                switch (index) {
+                    case 1:
+                        coords[0] = (float)(x + width);
+                        coords[1] = (float)y;
+                        break;
+                    case 2:
+                        coords[0] = (float)(x + width);
+                        coords[1] = (float)(y + height);
+                        break;
+                    case 3:
+                        coords[0] = (float)x;
+                        coords[1] = (float)(y + height);
+                        break;
+                    case 4:
+                        coords[0] = (float)x;
+                        coords[1] = (float)y;
+                        break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Rectangle2D.
+     */
+    protected Rectangle2D() {
+    }
+
+    /**
+     * Sets the rectangle's location and dimension.
+     * 
+     * @param x
+     *            the x coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the y coordinate of the rectangle's upper left corner.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     */
+    public abstract void setRect(double x, double y, double width, double height);
+
+    /**
+     * Gets the location of the point with respect to the rectangle and packs
+     * the information into a single integer using the bitmasks
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
+     * rectangle has zero or negative width, then every point is regarded as
+     * being both to the left and to the right of the rectangle. Similarly, if
+     * the height is zero or negative then all points are considered to be both
+     * both above and below it.
+     * 
+     * @param x
+     *            the x coordinate of the point to check.
+     * @param y
+     *            the y coordinate of the point to check.
+     * @return the point's location with respect to the rectangle.
+     */
+    public abstract int outcode(double x, double y);
+
+    /**
+     * Creates an new rectangle that is the intersection of this rectangle with
+     * the given rectangle. The resulting rectangle may be empty. The data of
+     * this rectangle is left unchanged.
+     * 
+     * @param r
+     *            the rectangle to intersect with this rectangle.
+     * @return the new rectangle given by intersection.
+     */
+    public abstract Rectangle2D createIntersection(Rectangle2D r);
+
+    /**
+     * Creates an new rectangle that is the union of this rectangle with the
+     * given rectangle. The new rectangle is the smallest rectangle which
+     * contains both this rectangle and the rectangle specified as a parameter.
+     * The data of this rectangle is left unchanged.
+     * 
+     * @param r
+     *            the rectangle to combine with this rectangle.
+     * @return the new rectangle given by union.
+     */
+    public abstract Rectangle2D createUnion(Rectangle2D r);
+
+    /**
+     * Sets the data of this rectangle to match the data of the given rectangle.
+     * 
+     * @param r
+     *            the rectangle whose data is to be copied into this rectangle's
+     *            fields.
+     */
+    public void setRect(Rectangle2D r) {
+        setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRect(x, y, width, height);
+    }
+
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D)clone();
+    }
+
+    /**
+     * Determines whether any part of the line segment between (and including)
+     * the two given points touches any part of the rectangle, including its
+     * boundary.
+     * 
+     * @param x1
+     *            the x coordinate of one of the points that determines the line
+     *            segment to test.
+     * @param y1
+     *            the y coordinate of one of the points that determines the line
+     *            segment to test.
+     * @param x2
+     *            the x coordinate of one of the points that determines the line
+     *            segment to test.
+     * @param y2
+     *            the y coordinate of one of the points that determines the line
+     *            segment to test.
+     * @return true, if at least one point of the line segment between the two
+     *         points matches any point of the interior of the rectangle or the
+     *         rectangle's boundary.
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+        return (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2)
+                || (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2)
+                || Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2)
+                || Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
+    }
+
+    /**
+     * Determines whether any part of the specified line segment touches any
+     * part of the rectangle, including its boundary.
+     * 
+     * @param l
+     *            the line segment to test.
+     * @return true, if at least one point of the given line segment matches any
+     *         point of the interior of the rectangle or the rectangle's
+     *         boundary.
+     */
+    public boolean intersectsLine(Line2D l) {
+        return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+    }
+
+    /**
+     * Gets the location of the point with respect to the rectangle and packs
+     * the information into a single integer using the bitmasks
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
+     * rectangle has zero or negative width, then every point is regarded as
+     * being both to the left and to the right of the rectangle. Similarly, if
+     * the height is zero or negative then all points are considered to be both
+     * both above and below it.
+     * 
+     * @param p
+     *            the point to check.
+     * @return the point's location with respect to the rectangle.
+     */
+    public int outcode(Point2D p) {
+        return outcode(p.getX(), p.getY());
+    }
+
+    public boolean contains(double x, double y) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return x1 <= x && x < x2 && y1 <= y && y < y2;
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return x + width > x1 && x < x2 && y + height > y1 && y < y2;
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return x1 <= x && x + width <= x2 && y1 <= y && y + height <= y2;
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match the
+     * intersection of the two source rectangles, leaving the two source
+     * rectangles unchanged. The resulting rectangle may be empty.
+     * 
+     * @param src1
+     *            one of the two source rectangles giving the data to intersect.
+     * @param src2
+     *            one of the two source rectangles giving the data to intersect.
+     * @param dst
+     *            the destination object where the data of the intersection is
+     *            written.
+     */
+    public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.max(src1.getMinX(), src2.getMinX());
+        double y1 = Math.max(src1.getMinY(), src2.getMinY());
+        double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match the union
+     * of the two source rectangles, leaving the two source rectangles
+     * unchanged. The union is the smallest rectangle that completely covers the
+     * two source rectangles.
+     * 
+     * @param src1
+     *            one of the two source rectangles giving the data.
+     * @param src2
+     *            one of the two source rectangles giving the data.
+     * @param dst
+     *            the destination object where the data of the union is written.
+     */
+    public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.min(src1.getMinX(), src2.getMinX());
+        double y1 = Math.min(src1.getMinY(), src2.getMinY());
+        double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param x
+     *            the x coordinate of the new point to be covered by the
+     *            rectangle.
+     * @param y
+     *            the y coordinate of the new point to be covered by the
+     *            rectangle.
+     */
+    public void add(double x, double y) {
+        double x1 = Math.min(getMinX(), x);
+        double y1 = Math.min(getMinY(), y);
+        double x2 = Math.max(getMaxX(), x);
+        double y2 = Math.max(getMaxY(), y);
+        setRect(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param p
+     *            the new point to be covered by the rectangle.
+     */
+    public void add(Point2D p) {
+        add(p.getX(), p.getY());
+    }
+
+    /**
+     * Enlarges the rectangle so that it covers the given rectangle.
+     * 
+     * @param r
+     *            the new rectangle to be covered by this rectangle.
+     */
+    public void add(Rectangle2D r) {
+        union(this, r, this);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        hash.append(getWidth());
+        hash.append(getHeight());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle2D) {
+            Rectangle2D r = (Rectangle2D)obj;
+            return getX() == r.getX() && getY() == r.getY() && getWidth() == r.getWidth()
+                    && getHeight() == r.getHeight();
+        }
+        return false;
+    }
+
+}
diff --git a/awt/java/awt/geom/RectangularShape.java b/awt/java/awt/geom/RectangularShape.java
new file mode 100644
index 0000000..0b0d05c
--- /dev/null
+++ b/awt/java/awt/geom/RectangularShape.java
@@ -0,0 +1,297 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+/**
+ * The Class RectangularShape represents a Shape whose data is (at least
+ * partially) described by a rectangular frame. This includes shapes which are
+ * obviously rectangular (such as Rectangle2D) as well as shapes like Arc2D
+ * which are largely determined by the rectangle they fit inside.
+ * 
+ * @since Android 1.0
+ */
+public abstract class RectangularShape implements Shape, Cloneable {
+
+    /**
+     * Instantiates a new rectangular shape.
+     */
+    protected RectangularShape() {
+    }
+
+    /**
+     * Gets the x coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the x coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the y coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getY();
+
+    /**
+     * Gets the width of the rectangle.
+     * 
+     * @return the width of the rectangle.
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height of the rectangle.
+     * 
+     * @return the height of the rectangle.
+     */
+    public abstract double getHeight();
+
+    /**
+     * Checks if this is an empty rectangle: one with zero as its width or
+     * height.
+     * 
+     * @return true, if the width or height is empty.
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * Sets the data for the bounding rectangle in terms of double values.
+     * 
+     * @param x
+     *            the x coordinate of the upper left corner of the rectangle.
+     * @param y
+     *            the y coordinate of the upper left corner of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     */
+    public abstract void setFrame(double x, double y, double w, double h);
+
+    /**
+     * Gets the minimum x value of the bounding rectangle (the x coordinate of
+     * the upper left corner of the rectangle).
+     * 
+     * @return the minimum x value of the bounding rectangle.
+     */
+    public double getMinX() {
+        return getX();
+    }
+
+    /**
+     * Gets the minimum y value of the bounding rectangle (the y coordinate of
+     * the upper left corner of the rectangle).
+     * 
+     * @return the minimum y value of the bounding rectangle.
+     */
+    public double getMinY() {
+        return getY();
+    }
+
+    /**
+     * Gets the maximum x value of the bounding rectangle (the x coordinate of
+     * the upper left corner of the rectangle plus the rectangle's width).
+     * 
+     * @return the maximum x value of the bounding rectangle.
+     */
+    public double getMaxX() {
+        return getX() + getWidth();
+    }
+
+    /**
+     * Gets the maximum y value of the bounding rectangle (the y coordinate of
+     * the upper left corner of the rectangle plus the rectangle's height).
+     * 
+     * @return the maximum y value of the bounding rectangle.
+     */
+    public double getMaxY() {
+        return getY() + getHeight();
+    }
+
+    /**
+     * Gets the x coordinate of the center of the rectangle.
+     * 
+     * @return the x coordinate of the center of the rectangle.
+     */
+    public double getCenterX() {
+        return getX() + getWidth() / 2.0;
+    }
+
+    /**
+     * Gets the y coordinate of the center of the rectangle.
+     * 
+     * @return the y coordinate of the center of the rectangle.
+     */
+    public double getCenterY() {
+        return getY() + getHeight() / 2.0;
+    }
+
+    /**
+     * Places the rectangle's size and location data in a new Rectangle2D object
+     * and returns it.
+     * 
+     * @return the bounding rectangle as a new Rectangle2D object.
+     */
+    public Rectangle2D getFrame() {
+        return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle in terms of a Point2D which gives its upper
+     * left corner and a Dimension2D object giving its width and height.
+     * 
+     * @param loc
+     *            the new upper left corner coordinate.
+     * @param size
+     *            the new size dimensions.
+     */
+    public void setFrame(Point2D loc, Dimension2D size) {
+        setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle to match the data contained in the specified
+     * Rectangle2D.
+     * 
+     * @param r
+     *            the rectangle that gives the new frame data.
+     */
+    public void setFrame(Rectangle2D r) {
+        setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one
+     * another.
+     * 
+     * @param x1
+     *            the x coordinate of one of the corner points.
+     * @param y1
+     *            the y coordinate of one of the corner points.
+     * @param x2
+     *            the x coordinate of the other corner point.
+     * @param y2
+     *            the y coordinate of the other corner point.
+     */
+    public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
+        double rx, ry, rw, rh;
+        if (x1 < x2) {
+            rx = x1;
+            rw = x2 - x1;
+        } else {
+            rx = x2;
+            rw = x1 - x2;
+        }
+        if (y1 < y2) {
+            ry = y1;
+            rh = y2 - y1;
+        } else {
+            ry = y2;
+            rh = y1 - y2;
+        }
+        setFrame(rx, ry, rw, rh);
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one
+     * another.
+     * 
+     * @param p1
+     *            one of the corner points.
+     * @param p2
+     *            the other corner point.
+     */
+    public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
+        setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param centerX
+     *            the x coordinate of the center point.
+     * @param centerY
+     *            the y coordinate of the center point.
+     * @param cornerX
+     *            the x coordinate of one of the corner points.
+     * @param cornerY
+     *            the y coordinate of one of the corner points.
+     */
+    public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
+        double width = Math.abs(cornerX - centerX);
+        double height = Math.abs(cornerY - centerY);
+        setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param center
+     *            the center point.
+     * @param corner
+     *            a corner point.
+     */
+    public void setFrameFromCenter(Point2D center, Point2D corner) {
+        setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
+    }
+
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        int x1 = (int)Math.floor(getMinX());
+        int y1 = (int)Math.floor(getMinY());
+        int x2 = (int)Math.ceil(getMaxX());
+        int y2 = (int)Math.ceil(getMaxY());
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/RoundRectangle2D.java b/awt/java/awt/geom/RoundRectangle2D.java
new file mode 100644
index 0000000..8fbddd6
--- /dev/null
+++ b/awt/java/awt/geom/RoundRectangle2D.java
@@ -0,0 +1,635 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RoundRectangle2D describes a rectangle with rounded corners with
+ * high-precision data that is appropriate for geometric operations.
+ * 
+ * @since Android 1.0
+ */
+public abstract class RoundRectangle2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of RoundRectangle2D that has all of its
+     * data values stored with float-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Float extends RoundRectangle2D {
+
+        /**
+         * The x coordinate of the rectangle's upper left corner.
+         */
+        public float x;
+
+        /**
+         * The y coordinate of the rectangle's upper left corner.
+         */
+        public float y;
+
+        /**
+         * The width of the rectangle.
+         */
+        public float width;
+
+        /**
+         * The height of the rectangle.
+         */
+        public float height;
+
+        /**
+         * The arc width of the rounded corners.
+         */
+        public float arcwidth;
+
+        /**
+         * The arc height of the rounded corners.
+         */
+        public float archeight;
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with its data-values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with the specified
+         * data values.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         * @param arcwidth
+         *            the arc width of the rounded corners.
+         * @param archeight
+         *            the arc height of the rounded corners.
+         */
+        public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the data of the round rectangle.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         * @param arcwidth
+         *            the arc width of the rounded corners.
+         * @param archeight
+         *            the arc height of the rounded corners.
+         */
+        public void setRoundRect(float x, float y, float width, float height, float arcwidth,
+                float archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth,
+                double archeight) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.arcwidth = (float)arcwidth;
+            this.archeight = (float)archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = (float)rr.getX();
+            this.y = (float)rr.getY();
+            this.width = (float)rr.getWidth();
+            this.height = (float)rr.getHeight();
+            this.arcwidth = (float)rr.getArcWidth();
+            this.archeight = (float)rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of RoundRectangle2D that has all of its
+     * data values stored with double-level precision.
+     * 
+     * @since Android 1.0
+     */
+    public static class Double extends RoundRectangle2D {
+
+        /**
+         * The x coordinate of the rectangle's upper left corner.
+         */
+        public double x;
+
+        /**
+         * The y coordinate of the rectangle's upper left corner.
+         */
+        public double y;
+
+        /**
+         * The width of the rectangle.
+         */
+        public double width;
+
+        /**
+         * The height of the rectangle.
+         */
+        public double height;
+
+        /**
+         * The arc width of the rounded corners.
+         */
+        public double arcwidth;
+
+        /**
+         * The arc height of the rounded corners.
+         */
+        public double archeight;
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with its
+         * data-values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with the specified
+         * data values.
+         * 
+         * @param x
+         *            the x coordinate of the rectangle's upper left corner.
+         * @param y
+         *            the y coordinate of the rectangle's upper left corner.
+         * @param width
+         *            the width of the rectangle.
+         * @param height
+         *            the height of the rectangle.
+         * @param arcwidth
+         *            the arc width of the rounded corners.
+         * @param archeight
+         *            the arc height of the rounded corners.
+         */
+        public Double(double x, double y, double width, double height, double arcwidth,
+                double archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth,
+                double archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.arcwidth = rr.getArcWidth();
+            this.archeight = rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * RoundRectangle2D path iterator
+     */
+    /**
+     * The subclass of PathIterator to traverse a RoundRectangle2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Path for round corners generated the same way as Ellipse2D
+         */
+
+        /**
+         * The coefficient to calculate control points of Bezier curves.
+         */
+        double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /**
+         * The points coordinates calculation table.
+         */
+        double points[][] = {
+                {
+                        0.0, 0.5, 0.0, 0.0
+                }, // MOVETO
+                {
+                        1.0, -0.5, 0.0, 0.0
+                }, // LINETO
+                {
+                        1.0, -u, 0.0, 0.0, // CUBICTO
+                        1.0, 0.0, 0.0, u, 1.0, 0.0, 0.0, 0.5
+                }, {
+                        1.0, 0.0, 1.0, -0.5
+                }, // LINETO
+                {
+                        1.0, 0.0, 1.0, -u, // CUBICTO
+                        1.0, -u, 1.0, 0.0, 1.0, -0.5, 1.0, 0.0
+                }, {
+                        0.0, 0.5, 1.0, 0.0
+                }, // LINETO
+                {
+                        0.0, u, 1.0, 0.0, // CUBICTO
+                        0.0, 0.0, 1.0, -u, 0.0, 0.0, 1.0, -0.5
+                }, {
+                        0.0, 0.0, 0.0, 0.5
+                }, // LINETO
+                {
+                        0.0, 0.0, 0.0, u, // CUBICTO
+                        0.0, u, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0
+                }
+        };
+
+        /**
+         * The segment types correspond to points array.
+         */
+        int types[] = {
+                SEG_MOVETO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO,
+                SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO
+        };
+
+        /**
+         * The x coordinate of left-upper corner of the round rectangle bounds.
+         */
+        double x;
+
+        /**
+         * The y coordinate of left-upper corner of the round rectangle bounds.
+         */
+        double y;
+
+        /**
+         * The width of the round rectangle bounds.
+         */
+        double width;
+
+        /**
+         * The height of the round rectangle bounds.
+         */
+        double height;
+
+        /**
+         * The width of arc corners of the round rectangle.
+         */
+        double aw;
+
+        /**
+         * The height of arc corners of the round rectangle.
+         */
+        double ah;
+
+        /**
+         * The path iterator transformation.
+         */
+        AffineTransform t;
+
+        /**
+         * The current segment index.
+         */
+        int index;
+
+        /**
+         * Constructs a new RoundRectangle2D.Iterator for given round rectangle
+         * and transformation.
+         * 
+         * @param rr
+         *            - the source RoundRectangle2D object
+         * @param at
+         *            - the AffineTransform object to apply rectangle path
+         */
+        Iterator(RoundRectangle2D rr, AffineTransform at) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.aw = Math.min(width, rr.getArcWidth());
+            this.ah = Math.min(height, rr.getArcHeight());
+            this.t = at;
+            if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
+                index = points.length;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > points.length;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
+                coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
+                coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+    }
+
+    /**
+     * Instantiates a new RoundRectangle2D.
+     */
+    protected RoundRectangle2D() {
+    }
+
+    /**
+     * Gets the arc width.
+     * 
+     * @return the arc width.
+     */
+    public abstract double getArcWidth();
+
+    /**
+     * Gets the arc height.
+     * 
+     * @return the arc height.
+     */
+    public abstract double getArcHeight();
+
+    /**
+     * Sets the data of the RoundRectangle2D.
+     * 
+     * @param x
+     *            the x coordinate of the rectangle's upper left corner.
+     * @param y
+     *            the y coordinate of the rectangle's upper left corner.
+     * @param width
+     *            the width of the rectangle.
+     * @param height
+     *            the height of the rectangle.
+     * @param arcWidth
+     *            the arc width of the rounded corners.
+     * @param arcHeight
+     *            the arc height of the rounded corners.
+     */
+    public abstract void setRoundRect(double x, double y, double width, double height,
+            double arcWidth, double arcHeight);
+
+    /**
+     * Sets the data of the RoundRectangle2D by copying the values from an
+     * existing RoundRectangle2D.
+     * 
+     * @param rr
+     *            the round rectangle to copy the data from.
+     * @throws NullPointerException
+     *             if rr is null.
+     */
+    public void setRoundRect(RoundRectangle2D rr) {
+        setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr.getArcWidth(), rr
+                .getArcHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
+            return false;
+        }
+
+        double aw = getArcWidth() / 2.0;
+        double ah = getArcHeight() / 2.0;
+
+        double cx, cy;
+
+        if (px < rx1 + aw) {
+            cx = rx1 + aw;
+        } else if (px > rx2 - aw) {
+            cx = rx2 - aw;
+        } else {
+            return true;
+        }
+
+        if (py < ry1 + ah) {
+            cy = ry1 + ah;
+        } else if (py > ry2 - ah) {
+            cy = ry2 - ah;
+        } else {
+            return true;
+        }
+
+        px = (px - cx) / aw;
+        py = (py - cy) / ah;
+        return px * px + py * py <= 1.0;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
+            return false;
+        }
+
+        double cx = (x1 + x2) / 2.0;
+        double cy = (y1 + y2) / 2.0;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
diff --git a/awt/java/awt/geom/package.html b/awt/java/awt/geom/package.html
new file mode 100644
index 0000000..e3a236e
--- /dev/null
+++ b/awt/java/awt/geom/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes and interfaces related to Java2D shapes and geometry.
+    </p>
+    @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
new file mode 100644
index 0000000..cce5148
--- /dev/null
+++ b/awt/java/awt/im/InputContext.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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.AWTEvent;
+//???AWT: import java.awt.Component;
+import java.util.Locale;
+
+import org.apache.harmony.awt.im.InputMethodContext;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class InputContext {
+    protected InputContext() {
+    }
+
+    public static InputContext getInstance() {
+        return new InputMethodContext();
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+    }
+
+    public void dispose() {
+    }
+
+    public void endComposition() {
+    }
+
+    public Object getInputMethodControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void reconvert() {
+    }
+
+    //???AWT
+    /*
+    public void removeNotify(Component client) {
+    }
+    */
+
+    public boolean selectInputMethod(Locale locale) {
+        return false;
+    }
+
+    public void setCharacterSubsets(Character.Subset[] subsets) {
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodHighlight.java b/awt/java/awt/im/InputMethodHighlight.java
new file mode 100644
index 0000000..865d47c
--- /dev/null
+++ b/awt/java/awt/im/InputMethodHighlight.java
@@ -0,0 +1,95 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.util.Map;
+import java.awt.font.TextAttribute;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public class InputMethodHighlight {
+
+    public static final int RAW_TEXT = 0;
+
+    public static final int CONVERTED_TEXT = 1;
+
+    public static final InputMethodHighlight
+        UNSELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(false, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(true, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        UNSELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(false, CONVERTED_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(true, CONVERTED_TEXT);
+    
+    private boolean selected;
+    private int state;
+    private int variation;
+    private Map<TextAttribute,?> style;
+
+    public InputMethodHighlight(boolean selected, int state, int variation) {
+        this(selected, state, variation, null);
+    }
+
+    public InputMethodHighlight(boolean selected, int state,
+                                int variation, Map<java.awt.font.TextAttribute, ?> style) {
+        if ((state != RAW_TEXT) && (state != CONVERTED_TEXT)) {
+            // awt.20B=unknown input method highlight state
+            throw new IllegalArgumentException(Messages.getString("awt.20B")); //$NON-NLS-1$
+        }
+        this.selected = selected;
+        this.state = state;
+        this.variation = variation;
+        this.style = style;
+    }
+
+    public InputMethodHighlight(boolean selected, int state) {
+        this(selected, state, 0, null);
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public Map<java.awt.font.TextAttribute, ?> getStyle() {
+        return style;
+    }
+
+    public int getVariation() {
+        return variation;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodRequests.java b/awt/java/awt/im/InputMethodRequests.java
new file mode 100644
index 0000000..b12d397
--- /dev/null
+++ b/awt/java/awt/im/InputMethodRequests.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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.Rectangle;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface InputMethodRequests {
+
+    public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes);
+
+    public int getCommittedTextLength();
+
+    public int getInsertPositionOffset();
+
+    public TextHitInfo getLocationOffset(int x, int y);
+
+    public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public Rectangle getTextLocation(TextHitInfo offset);
+}
+
diff --git a/awt/java/awt/im/InputSubset.java b/awt/java/awt/im/InputSubset.java
new file mode 100644
index 0000000..708881e
--- /dev/null
+++ b/awt/java/awt/im/InputSubset.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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public final class InputSubset extends Character.Subset {
+
+    public static final InputSubset LATIN = new InputSubset("LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        LATIN_DIGITS = new InputSubset("LATIN_DIGITS"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        TRADITIONAL_HANZI = new InputSubset("TRADITIONAL_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        SIMPLIFIED_HANZI = new InputSubset("SIMPLIFIED_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset KANJI = new InputSubset("KANJI"); //$NON-NLS-1$
+
+    public static final InputSubset HANJA = new InputSubset("HANJA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        HALFWIDTH_KATAKANA = new InputSubset("HALFWIDTH_KATAKANA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_LATIN = new InputSubset("FULLWIDTH_LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_DIGITS = new InputSubset("FULLWIDTH_DIGITS"); //$NON-NLS-1$
+
+    private InputSubset(String name) {
+        super(name);
+    }
+}
+
diff --git a/awt/java/awt/im/spi/InputMethod.java b/awt/java/awt/im/spi/InputMethod.java
new file mode 100644
index 0000000..67a8834
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethod.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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTEvent;
+import java.awt.Rectangle;
+import java.util.Locale;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface InputMethod {
+
+    public void activate();
+
+    public void deactivate(boolean isTemporary);
+
+    public void dispatchEvent(AWTEvent event);
+
+    public void dispose();
+
+    public void endComposition();
+
+    public Object getControlObject();
+
+    public Locale getLocale();
+
+    public void hideWindows();
+
+    public boolean isCompositionEnabled();
+
+    public void notifyClientWindowChange(Rectangle bounds);
+
+    public void reconvert();
+
+    public void removeNotify();
+
+    public void setCharacterSubsets(Character.Subset[] subsets);
+
+    public void setCompositionEnabled(boolean enable);
+
+    public void setInputMethodContext(InputMethodContext context);
+
+    public boolean setLocale(Locale locale);
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodContext.java b/awt/java/awt/im/spi/InputMethodContext.java
new file mode 100644
index 0000000..bfc773c
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodContext.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 java.awt.im.spi;
+
+//???AWT: import java.awt.Window;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodRequests;
+import java.text.AttributedCharacterIterator;
+//???AWT: import javax.swing.JFrame;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface InputMethodContext extends InputMethodRequests {
+
+//    ???AWT: public JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
+
+//    ???AWT: public Window createInputMethodWindow(String title, boolean attachToInputContext);
+
+    public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition);
+
+    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
+
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodDescriptor.java b/awt/java/awt/im/spi/InputMethodDescriptor.java
new file mode 100644
index 0000000..c800bc1
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodDescriptor.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 java.awt.im.spi;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.util.Locale;
+
+/**
+ * This class is not supported in Android 1.0. It is merely provided to maintain
+ * interface compatibility with desktop Java implementations.
+ * 
+ * @since Android 1.0
+ */
+public interface InputMethodDescriptor {
+
+    public Locale[] getAvailableLocales() throws AWTException;
+
+    public InputMethod createInputMethod() throws Exception;
+
+    public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage);
+
+    public Image getInputMethodIcon(Locale inputLocale);
+
+    public boolean hasDynamicLocaleList();
+
+}
+
diff --git a/awt/java/awt/image/AffineTransformOp.java b/awt/java/awt/image/AffineTransformOp.java
new file mode 100644
index 0000000..db25e1a
--- /dev/null
+++ b/awt/java/awt/image/AffineTransformOp.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 Oleg V. Khaschansky, Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AffineTransform class translates coordinates from 2D coordinates in the
+ * source image or Raster to 2D coordinates in the destination image or Raster
+ * using affine transformation. The number of bands in the source Raster should
+ * equal to the number of bands in the destination Raster.
+ * 
+ * @since Android 1.0
+ */
+public class AffineTransformOp implements BufferedImageOp, RasterOp {
+
+    /**
+     * The Constant TYPE_NEAREST_NEIGHBOR indicates nearest-neighbor
+     * interpolation type.
+     */
+    public static final int TYPE_NEAREST_NEIGHBOR = 1;
+
+    /**
+     * The Constant TYPE_BILINEAR indicates bilinear interpolation type.
+     */
+    public static final int TYPE_BILINEAR = 2;
+
+    /**
+     * The Constant TYPE_BICUBIC indicates bi-cubic interpolation type.
+     */
+    public static final int TYPE_BICUBIC = 3;
+
+    /**
+     * The i type.
+     */
+    private int iType; // interpolation type
+
+    /**
+     * The at.
+     */
+    private AffineTransform at;
+
+    /**
+     * The hints.
+     */
+    private RenderingHints hints;
+
+    static {
+        // TODO - uncomment
+        // System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified AffineTransform
+     * and RenderingHints object which defines the interpolation type.
+     * 
+     * @param xform
+     *            the AffineTransform.
+     * @param hints
+     *            the RenderingHints object which defines the interpolation
+     *            type.
+     */
+    public AffineTransformOp(AffineTransform xform, RenderingHints hints) {
+        this(xform, TYPE_NEAREST_NEIGHBOR);
+        this.hints = hints;
+
+        if (hints != null) {
+            Object hint = hints.get(RenderingHints.KEY_INTERPOLATION);
+            if (hint != null) {
+                // Nearest neighbor is default
+                if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+                    this.iType = TYPE_BILINEAR;
+                } else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+                    this.iType = TYPE_BICUBIC;
+                }
+            } else {
+                hint = hints.get(RenderingHints.KEY_RENDERING);
+                // Determine from rendering quality
+                if (hint == RenderingHints.VALUE_RENDER_QUALITY) {
+                    this.iType = TYPE_BILINEAR;
+                    // For speed use nearest neighbor
+                }
+            }
+        }
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified AffineTransform
+     * and a specified interpolation type from the list of predefined
+     * interpolation types.
+     * 
+     * @param xform
+     *            the AffineTransform.
+     * @param interp
+     *            the one of predefined interpolation types:
+     *            TYPE_NEAREST_NEIGHBOR, TYPE_BILINEAR, or TYPE_BICUBIC.
+     */
+    public AffineTransformOp(AffineTransform xform, int interp) {
+        if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
+            // awt.24F=Unable to invert transform {0}
+            throw new ImagingOpException(Messages.getString("awt.24F", xform)); //$NON-NLS-1$
+        }
+
+        this.at = (AffineTransform)xform.clone();
+
+        if (interp != TYPE_NEAREST_NEIGHBOR && interp != TYPE_BILINEAR && interp != TYPE_BICUBIC) {
+            // awt.250=Unknown interpolation type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.250", interp)); //$NON-NLS-1$
+        }
+
+        this.iType = interp;
+    }
+
+    /**
+     * Gets the interpolation type.
+     * 
+     * @return the interpolation type.
+     */
+    public final int getInterpolationType() {
+        return iType;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        if (hints == null) {
+            Object value = null;
+
+            switch (iType) {
+                case TYPE_NEAREST_NEIGHBOR:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+                    break;
+                case TYPE_BILINEAR:
+                    value = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+                    break;
+                case TYPE_BICUBIC:
+                    value = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+                    break;
+                default:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+            }
+
+            hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, value);
+        }
+
+        return hints;
+    }
+
+    /**
+     * Gets the affine transform associated with this AffineTransformOp.
+     * 
+     * @return the AffineTransform.
+     */
+    public final AffineTransform getTransform() {
+        return (AffineTransform)at.clone();
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        return at.transform(srcPt, dstPt);
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        // We position source raster to (0,0) even if it is translated child
+        // raster.
+        // This means that we need only width and height of the src
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        float[] corners = {
+                0, 0, width, 0, width, height, 0, height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0, 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        Rectangle2D newBounds = getBounds2D(src);
+
+        // Destination image should include (0,0) + positive part
+        // of the area bounded by newBounds (in source coordinate system).
+        double dstWidth = newBounds.getX() + newBounds.getWidth();
+        double dstHeight = newBounds.getY() + newBounds.getHeight();
+
+        if (dstWidth <= 0 || dstHeight <= 0) {
+            // awt.251=Transformed width ({0}) and height ({1}) should be
+            // greater than 0
+            throw new RasterFormatException(Messages.getString("awt.251", dstWidth, dstHeight)); //$NON-NLS-1$
+        }
+
+        if (destCM != null) {
+            return new BufferedImage(destCM, destCM.createCompatibleWritableRaster((int)dstWidth,
+                    (int)dstHeight), destCM.isAlphaPremultiplied(), null);
+        }
+
+        ColorModel cm = src.getColorModel();
+
+        // Interpolation other than NN doesn't make any sense for index color
+        if (iType != TYPE_NEAREST_NEIGHBOR && cm instanceof IndexColorModel) {
+            return new BufferedImage((int)dstWidth, (int)dstHeight, BufferedImage.TYPE_INT_ARGB);
+        }
+
+        // OK, we can get source color model
+        return new BufferedImage(cm, src.getRaster().createCompatibleWritableRaster((int)dstWidth,
+                (int)dstHeight), cm.isAlphaPremultiplied(), null);
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        // Here approach is other then in createCompatibleDestImage -
+        // destination should include only
+        // transformed image, but not (0,0) in source coordinate system
+
+        Rectangle2D newBounds = getBounds2D(src);
+        return src.createCompatibleWritableRaster((int)newBounds.getX(), (int)newBounds.getY(),
+                (int)newBounds.getWidth(), (int)newBounds.getHeight());
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (srcCM instanceof IndexColorModel
+                && (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+            // TODO - uncomment
+            // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) !=
+            // 0)
+            // throw new ImagingOpException ("Unable to transform source");
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.253=Different number of bands in source and destination
+            throw new IllegalArgumentException(Messages.getString("awt.253")); //$NON-NLS-1$
+        }
+
+        if (slowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+            // TODO - uncomment
+            // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+            // throw new ImagingOpException("Unable to transform source");
+        }
+
+        return dst;
+    }
+
+    // TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param imageType
+     *            the image type.
+     * @return the int.
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth() * 3;
+                dstStride = dst.getWidth() * 3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
+                // native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (srcSM instanceof PixelInterleavedSampleModel
+                        && dstSM instanceof PixelInterleavedSampleModel) {
+                    // Check PixelInterleavedSampleModel
+                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
+                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
+                    // 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;
+
+                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride() * dataTypeSize;
+                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride() * dataTypeSize;
+                } else if (srcSM instanceof SinglePixelPackedSampleModel
+                        && dstSM instanceof SinglePixelPackedSampleModel) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
+
+                    // No IPP function for this type
+                    if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = sppsm1.getNumBands();
+                    // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (sppsm1.getDataType() != sppsm2.getDataType()
+                            || !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
+                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i = 0; i < channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) {
+                        channels = 4;
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;
+
+                    srcStride = sppsm1.getScanlineStride() * dataTypeSize;
+                    dstStride = sppsm2.getScanlineStride() * dataTypeSize;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                            || dst.getSampleModelTranslateX() != 0
+                            || dst.getSampleModelTranslateY() != 0) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        double m00 = at.getScaleX();
+        double m01 = at.getShearX();
+        double m02 = at.getTranslateX();
+        double m10 = at.getShearY();
+        double m11 = at.getScaleY();
+        double m12 = at.getTranslateY();
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippAffineTransform(m00, m01, m02, m10, m11, m12, srcData, src.getWidth(), src
+                .getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(), dstStride,
+                iType, channels, skipChannel, offsets);
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @return the int.
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        // TODO: make correct interpolation
+        // TODO: what if there are different data types?
+
+        Rectangle srcBounds = src.getBounds();
+        Rectangle dstBounds = dst.getBounds();
+        Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
+        Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);
+
+        AffineTransform inv = null;
+        try {
+            inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return -1;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int minSrcX = srcBounds.x;
+        int minSrcY = srcBounds.y;
+        int maxSrcX = srcBounds.x + srcBounds.width;
+        int maxSrcY = srcBounds.y + srcBounds.height;
+
+        int minX = bounds.x + dstBounds.x;
+        int minY = bounds.y + dstBounds.y;
+        int maxX = minX + bounds.width;
+        int maxY = minY + bounds.height;
+
+        int hx = (int)(m[0] * 256);
+        int hy = (int)(m[1] * 256);
+        int vx = (int)(m[2] * 256);
+        int vy = (int)(m[3] * 256);
+        int sx = (int)(m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
+        int sy = (int)(m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;
+
+        vx -= hx * bounds.width;
+        vy -= hy * bounds.width;
+
+        if (src.getTransferType() == dst.getTransferType()) {
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        Object val = src.getDataElements(px, py, null);
+                        dst.setDataElements(x, y, val);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        } else {
+            float pixel[] = null;
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        pixel = src.getPixel(px, py, pixel);
+                        dst.setPixel(x, y, pixel);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Ipp affine transform.
+     * 
+     * @param m00
+     *            the m00.
+     * @param m01
+     *            the m01.
+     * @param m02
+     *            the m02.
+     * @param m10
+     *            the m10.
+     * @param m11
+     *            the m11.
+     * @param m12
+     *            the m12.
+     * @param src
+     *            the src.
+     * @param srcWidth
+     *            the src width.
+     * @param srcHeight
+     *            the src height.
+     * @param srcStride
+     *            the src stride.
+     * @param dst
+     *            the dst.
+     * @param dstWidth
+     *            the dst width.
+     * @param dstHeight
+     *            the dst height.
+     * @param dstStride
+     *            the dst stride.
+     * @param iType
+     *            the i type.
+     * @param channels
+     *            the channels.
+     * @param skipChannel
+     *            the skip channel.
+     * @param offsets
+     *            the offsets.
+     * @return the int.
+     */
+    private native int ippAffineTransform(double m00, double m01, double m02, double m10,
+            double m11, double m12, Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride, int iType, int channels,
+            boolean skipChannel, int offsets[]);
+}
\ No newline at end of file
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..7fb138e
--- /dev/null
+++ b/awt/java/awt/image/AreaAveragingScaleFilter.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Arrays;
+
+/**
+ * The AreaAveragingScaleFilter class scales the source image using area
+ * averaging algorithm. This algorithm provides a source image with a new image
+ * containing the resampled image.
+ * 
+ * @since Android 1.0
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
+
+    /**
+     * The Constant rgbCM.
+     */
+    private static final ColorModel rgbCM = ColorModel.getRGBdefault();
+
+    /**
+     * The Constant averagingFlags.
+     */
+    private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES);
+
+    /**
+     * The reset.
+     */
+    private boolean reset = true; // Flag for used superclass filter
+
+    /**
+     * The inited.
+     */
+    private boolean inited = false; // All data inited
+
+    /**
+     * The sum_r.
+     */
+    private int sum_r[]; // Array for average Red samples
+
+    /**
+     * The sum_g.
+     */
+    private int sum_g[]; // Array for average Green samples
+
+    /**
+     * The sum_b.
+     */
+    private int sum_b[]; // Array for average Blue samples
+
+    /**
+     * The sum_a.
+     */
+    private int sum_a[]; // Array for average Alpha samples
+
+    /**
+     * The buff.
+     */
+    private int buff[]; // Stride buffer
+
+    /**
+     * The avg factor.
+     */
+    private int avgFactor; // Global averaging factor
+
+    /**
+     * The cached dy.
+     */
+    private int cachedDY; // Cached number of the destination scanline
+
+    /**
+     * The cached dv rest.
+     */
+    private int cachedDVRest; // Cached value of rest src scanlines for sum
+
+    // pixel samples
+    // Because data if transferring by whole scanlines
+    // we are caching only Y coordinate values
+
+    /**
+     * Instantiates a new AreaAveragingScaleFilter object which scales a source
+     * image with the specified width and height.
+     * 
+     * @param width
+     *            the scaled width of the image.
+     * @param height
+     *            the scaled height of the image.
+     */
+    public AreaAveragingScaleFilter(int width, int height) {
+        super(width, height);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        if (reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        if (reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setHints(int hints) {
+        super.setHints(hints);
+        reset = ((hints & averagingFlags) != averagingFlags);
+    }
+
+    /**
+     * This method implements the Area Averaging Scale filter. The description
+     * of algorithm is presented in Java API Specification. Arrays sum_r, sum_g,
+     * sum_b, sum_a have length equals width of destination image. In each
+     * array's element is accumulating pixel's component values, proportional to
+     * the area which source pixels will occupy in destination image. Then that
+     * values will divide by Global averaging factor (area of the destination
+     * image) for receiving average values of destination pixels.
+     * 
+     * @param x
+     *            the source pixels X coordinate.
+     * @param y
+     *            the source pixels Y coordinate.
+     * @param w
+     *            the width of the area of the source pixels.
+     * @param h
+     *            the height of the area of the source pixels.
+     * @param model
+     *            the color model of the source pixels.
+     * @param pixels
+     *            the array of source pixels.
+     * @param off
+     *            the offset into the source pixels array.
+     * @param scansize
+     *            the length of scanline in the pixels array.
+     */
+    private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels,
+            int off, int scansize) {
+        if (!inited) {
+            initialize();
+        }
+
+        int srcX, srcY, dx, dy;
+        int svRest, dvRest, shRest, dhRest, vDif, hDif;
+
+        if (y == 0) {
+            dy = 0;
+            dvRest = srcHeight;
+        } else {
+            dy = cachedDY;
+            dvRest = cachedDVRest;
+        }
+
+        srcY = y;
+        svRest = destHeight;
+
+        int srcOff = off;
+        while (srcY < y + h) {
+            if (svRest < dvRest) {
+                vDif = svRest;
+            } else {
+                vDif = dvRest;
+            }
+
+            srcX = 0;
+            dx = 0;
+            shRest = destWidth;
+            dhRest = srcWidth;
+            while (srcX < w) {
+                if (shRest < dhRest) {
+                    hDif = shRest;
+                } else {
+                    hDif = dhRest;
+                }
+                int avg = hDif * vDif; // calculation of contribution factor
+
+                int rgb, pix;
+                if (pixels instanceof int[]) {
+                    pix = ((int[])pixels)[srcOff + srcX];
+                } else {
+                    pix = ((byte[])pixels)[srcOff + srcX] & 0xff;
+                }
+
+                rgb = model.getRGB(pix);
+                int a = rgb >>> 24;
+                int r = (rgb >> 16) & 0xff;
+                int g = (rgb >> 8) & 0xff;
+                int b = rgb & 0xff;
+
+                // accumulating pixel's component values
+                sum_a[dx] += a * avg;
+                sum_r[dx] += r * avg;
+                sum_g[dx] += g * avg;
+                sum_b[dx] += b * avg;
+
+                shRest -= hDif;
+                dhRest -= hDif;
+
+                if (shRest == 0) {
+                    srcX++;
+                    shRest = destWidth;
+                }
+
+                if (dhRest == 0) {
+                    dx++;
+                    dhRest = srcWidth;
+                }
+            }
+
+            svRest -= vDif;
+            dvRest -= vDif;
+
+            if (svRest == 0) {
+                svRest = destHeight;
+                srcY++;
+                srcOff += scansize;
+            }
+
+            if (dvRest == 0) {
+                // averaging destination pixel's values
+                for (int i = 0; i < destWidth; i++) {
+                    int a = (sum_a[i] / avgFactor) & 0xff;
+                    int r = (sum_r[i] / avgFactor) & 0xff;
+                    int g = (sum_g[i] / avgFactor) & 0xff;
+                    int b = (sum_b[i] / avgFactor) & 0xff;
+                    int frgb = (a << 24) | (r << 16) | (g << 8) | b;
+                    buff[i] = frgb;
+                }
+                consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0, destWidth);
+                dy++;
+                dvRest = srcHeight;
+                Arrays.fill(sum_a, 0);
+                Arrays.fill(sum_r, 0);
+                Arrays.fill(sum_g, 0);
+                Arrays.fill(sum_b, 0);
+            }
+
+        }
+
+        cachedDY = dy;
+        cachedDVRest = dvRest;
+
+    }
+
+    /**
+     * Initialization of the auxiliary data.
+     */
+    private void initialize() {
+
+        sum_a = new int[destWidth];
+        sum_r = new int[destWidth];
+        sum_g = new int[destWidth];
+        sum_b = new int[destWidth];
+
+        buff = new int[destWidth];
+        outpixbuf = buff;
+        avgFactor = srcWidth * srcHeight;
+
+        inited = true;
+    }
+}
diff --git a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
new file mode 100644
index 0000000..6dffee8
--- /dev/null
+++ b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+
+package java.awt.image;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.gl.GLVolatileImage;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class not part of public API. It useful for receiving package private
+ * data from other packages.
+ * 
+ * @since Android 1.0
+ */
+class AwtImageBackdoorAccessorImpl extends AwtImageBackdoorAccessor {
+
+    static void init() {
+        inst = new AwtImageBackdoorAccessorImpl();
+    }
+
+    @Override
+    public Surface getImageSurface(Image image) {
+        if (image instanceof BufferedImage) {
+            return ((BufferedImage)image).getImageSurface();
+        } else if (image instanceof GLVolatileImage) {
+            return ((GLVolatileImage)image).getImageSurface();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isGrayPallete(IndexColorModel icm) {
+        return icm.isGrayPallete();
+    }
+
+    @Override
+    public Object getData(DataBuffer db) {
+        if (db instanceof DataBufferByte) {
+            return ((DataBufferByte)db).getData();
+        } else if (db instanceof DataBufferUShort) {
+            return ((DataBufferUShort)db).getData();
+        } else if (db instanceof DataBufferShort) {
+            return ((DataBufferShort)db).getData();
+        } else if (db instanceof DataBufferInt) {
+            return ((DataBufferInt)db).getData();
+        } else if (db instanceof DataBufferFloat) {
+            return ((DataBufferFloat)db).getData();
+        } else if (db instanceof DataBufferDouble) {
+            return ((DataBufferDouble)db).getData();
+        } else {
+            // awt.235=Wrong Data Buffer type : {0}
+            throw new IllegalArgumentException(Messages.getString("awt.235", //$NON-NLS-1$
+                    db.getClass()));
+        }
+    }
+
+    @Override
+    public int[] getDataInt(DataBuffer db) {
+        if (db instanceof DataBufferInt) {
+            return ((DataBufferInt)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public byte[] getDataByte(DataBuffer db) {
+        if (db instanceof DataBufferByte) {
+            return ((DataBufferByte)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataShort(DataBuffer db) {
+        if (db instanceof DataBufferShort) {
+            return ((DataBufferShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataUShort(DataBuffer db) {
+        if (db instanceof DataBufferUShort) {
+            return ((DataBufferUShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public double[] getDataDouble(DataBuffer db) {
+        if (db instanceof DataBufferDouble) {
+            return ((DataBufferDouble)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public float[] getDataFloat(DataBuffer db) {
+        if (db instanceof DataBufferFloat) {
+            return ((DataBufferFloat)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public void addDataBufferListener(DataBuffer db, DataBufferListener listener) {
+        db.addDataBufferListener(listener);
+    }
+
+    @Override
+    public void removeDataBufferListener(DataBuffer db) {
+        db.removeDataBufferListener();
+    }
+
+    @Override
+    public void validate(DataBuffer db) {
+        db.validate();
+    }
+
+    @Override
+    public void releaseData(DataBuffer db) {
+        db.releaseData();
+    }
+}
diff --git a/awt/java/awt/image/BandCombineOp.java b/awt/java/awt/image/BandCombineOp.java
new file mode 100644
index 0000000..da2cc89
--- /dev/null
+++ b/awt/java/awt/image/BandCombineOp.java
@@ -0,0 +1,658 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 20, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandCombineOp class translates coordinates from coordinates in the source
+ * Raster to coordinates in the destination Raster by an arbitrary linear
+ * combination of the bands in a source Raster, using a specified matrix. The
+ * number of bands in the matrix should equal to the number of bands in the
+ * source Raster plus 1.
+ * 
+ * @since Android 1.0
+ */
+public class BandCombineOp implements RasterOp {
+
+    /**
+     * The Constant offsets3c.
+     */
+    static final int offsets3c[] = {
+            16, 8, 0
+    };
+
+    /**
+     * The Constant offsets4ac.
+     */
+    static final int offsets4ac[] = {
+            16, 8, 0, 24
+    };
+
+    /**
+     * The Constant masks3c.
+     */
+    static final int masks3c[] = {
+            0xFF0000, 0xFF00, 0xFF
+    };
+
+    /**
+     * The Constant masks4ac.
+     */
+    static final int masks4ac[] = {
+            0xFF0000, 0xFF00, 0xFF, 0xFF000000
+    };
+
+    /**
+     * The Constant piOffsets.
+     */
+    private static final int piOffsets[] = {
+            0, 1, 2
+    };
+
+    /**
+     * The Constant piInvOffsets.
+     */
+    private static final int piInvOffsets[] = {
+            2, 1, 0
+    };
+
+    /**
+     * The Constant TYPE_BYTE3C.
+     */
+    private static final int TYPE_BYTE3C = 0;
+
+    /**
+     * The Constant TYPE_BYTE4AC.
+     */
+    private static final int TYPE_BYTE4AC = 1;
+
+    /**
+     * The Constant TYPE_USHORT3C.
+     */
+    private static final int TYPE_USHORT3C = 2;
+
+    /**
+     * The Constant TYPE_SHORT3C.
+     */
+    private static final int TYPE_SHORT3C = 3;
+
+    /**
+     * The mx width.
+     */
+    private int mxWidth;
+
+    /**
+     * The mx height.
+     */
+    private int mxHeight;
+
+    /**
+     * The matrix.
+     */
+    private float matrix[][];
+
+    /**
+     * The r hints.
+     */
+    private RenderingHints rHints;
+
+    static {
+        // XXX - todo
+        // System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new BandCombineOp object with the specified matrix.
+     * 
+     * @param matrix
+     *            the specified matrix for band combining.
+     * @param hints
+     *            the RenderingHints.
+     */
+    public BandCombineOp(float matrix[][], RenderingHints hints) {
+        this.mxHeight = matrix.length;
+        this.mxWidth = matrix[0].length;
+        this.matrix = new float[mxHeight][mxWidth];
+
+        for (int i = 0; i < mxHeight; i++) {
+            System.arraycopy(matrix[i], 0, this.matrix[i], 0, mxWidth);
+        }
+
+        this.rHints = hints;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return this.rHints;
+    }
+
+    /**
+     * Gets the matrix associated with this BandCombineOp object.
+     * 
+     * @return the matrix associated with this BandCombineOp object.
+     */
+    public final float[][] getMatrix() {
+        float res[][] = new float[mxHeight][mxWidth];
+
+        for (int i = 0; i < mxHeight; i++) {
+            System.arraycopy(matrix[i], 0, res[i], 0, mxWidth);
+        }
+
+        return res;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint) {
+        if (dstPoint == null) {
+            dstPoint = new Point2D.Float();
+        }
+
+        dstPoint.setLocation(srcPoint);
+        return dstPoint;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        int numBands = src.getNumBands();
+        if (mxWidth != numBands && mxWidth != (numBands + 1) || numBands != mxHeight) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            // incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[] {
+                            numBands, mxWidth, mxHeight
+                    }));
+        }
+
+        return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+    }
+
+    public WritableRaster filter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        if (mxWidth != numBands && mxWidth != (numBands + 1)) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            // incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[] {
+                            numBands, mxWidth, mxHeight
+                    }));
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (dst.getNumBands() != mxHeight) {
+            // awt.255=Number of bands in the destination raster ({0}) is
+            // incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.255", //$NON-NLS-1$
+                    new Object[] {
+                            dst.getNumBands(), mxWidth, mxHeight
+                    }));
+        }
+
+        // XXX - todo
+        // if (ippFilter(src, dst) != 0)
+        if (verySlowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * The Class SampleModelInfo.
+     */
+    private static final class SampleModelInfo {
+
+        /**
+         * The channels.
+         */
+        int channels;
+
+        /**
+         * The channels order.
+         */
+        int channelsOrder[];
+
+        /**
+         * The stride.
+         */
+        int stride;
+    }
+
+    /**
+     * Check sample model.
+     * 
+     * @param sm
+     *            the sm.
+     * @return the sample model info.
+     */
+    private final SampleModelInfo checkSampleModel(SampleModel sm) {
+        SampleModelInfo ret = new SampleModelInfo();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            // Check PixelInterleavedSampleModel
+            if (sm.getDataType() != DataBuffer.TYPE_BYTE) {
+                return null;
+            }
+
+            ret.channels = sm.getNumBands();
+            ret.stride = ((ComponentSampleModel)sm).getScanlineStride();
+            ret.channelsOrder = ((ComponentSampleModel)sm).getBandOffsets();
+
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)sm;
+
+            ret.channels = sppsm1.getNumBands();
+            if (sppsm1.getDataType() != DataBuffer.TYPE_INT) {
+                return null;
+            }
+
+            // Check sample models
+            for (int i = 0; i < ret.channels; i++) {
+                if (sppsm1.getSampleSize(i) != 8) {
+                    return null;
+                }
+            }
+
+            ret.channelsOrder = new int[ret.channels];
+            int bitOffsets[] = sppsm1.getBitOffsets();
+            for (int i = 0; i < ret.channels; i++) {
+                if (bitOffsets[i] % 8 != 0) {
+                    return null;
+                }
+
+                ret.channelsOrder[i] = bitOffsets[i] / 8;
+            }
+
+            ret.channels = 4;
+            ret.stride = sppsm1.getScanlineStride() * 4;
+        } else {
+            return null;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @return the int.
+     */
+    private final int slowFilter(Raster src, WritableRaster dst) {
+        int res = 0;
+
+        SampleModelInfo srcInfo, dstInfo;
+        int offsets[] = null;
+
+        srcInfo = checkSampleModel(src.getSampleModel());
+        dstInfo = checkSampleModel(dst.getSampleModel());
+        if (srcInfo == null || dstInfo == null) {
+            return verySlowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                    || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        int rmxWidth = (srcInfo.channels + 1); // width of the reordered matrix
+        float reorderedMatrix[] = new float[rmxWidth * dstInfo.channels];
+        for (int j = 0; j < dstInfo.channels; j++) {
+            if (j >= dstInfo.channelsOrder.length) {
+                continue;
+            }
+
+            for (int i = 0; i < srcInfo.channels; i++) {
+                if (i >= srcInfo.channelsOrder.length) {
+                    break;
+                }
+
+                reorderedMatrix[dstInfo.channelsOrder[j] * rmxWidth + srcInfo.channelsOrder[i]] = matrix[j][i];
+            }
+            if (mxWidth == rmxWidth) {
+                reorderedMatrix[(dstInfo.channelsOrder[j] + 1) * rmxWidth - 1] = matrix[j][mxWidth - 1];
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        simpleCombineBands(srcData, src.getWidth(), src.getHeight(), srcInfo.stride,
+                srcInfo.channels, dstData, dstInfo.stride, dstInfo.channels, reorderedMatrix,
+                offsets);
+
+        return res;
+    }
+
+    /**
+     * Very slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @return the int.
+     */
+    private int verySlowFilter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        int srcMinX = src.getMinX();
+        int srcY = src.getMinY();
+
+        int dstMinX = dst.getMinX();
+        int dstY = dst.getMinY();
+
+        int dX = src.getWidth();// < dst.getWidth() ? src.getWidth() :
+        // dst.getWidth();
+        int dY = src.getHeight();// < dst.getHeight() ? src.getHeight() :
+        // dst.getHeight();
+
+        float sample;
+        int srcPixels[] = new int[numBands * dX * dY];
+        int dstPixels[] = new int[mxHeight * dX * dY];
+
+        srcPixels = src.getPixels(srcMinX, srcY, dX, dY, srcPixels);
+
+        if (numBands == mxWidth) {
+            for (int i = 0, j = 0; i < srcPixels.length; i += numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i + srcB];
+                    }
+                    dstPixels[j++] = (int)sample;
+                }
+            }
+        } else {
+            for (int i = 0, j = 0; i < srcPixels.length; i += numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i + srcB];
+                    }
+                    dstPixels[j++] = (int)(sample + matrix[dstB][numBands]);
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstY, dX, dY, dstPixels);
+
+        return 0;
+    }
+
+    // TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @return the int.
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst) {
+        boolean invertChannels;
+        boolean inPlace = (src == dst);
+        int type;
+        int srcStride, dstStride;
+        int offsets[] = null;
+
+        int srcBands = src.getNumBands();
+        int dstBands = dst.getNumBands();
+
+        if (dstBands != 3
+                || (srcBands != 3 && !(srcBands == 4 && matrix[0][3] == 0 && matrix[1][3] == 0 && matrix[2][3] == 0))) {
+            return slowFilter(src, dst);
+        }
+
+        SampleModel srcSM = src.getSampleModel();
+        SampleModel dstSM = dst.getSampleModel();
+
+        if (srcSM instanceof SinglePixelPackedSampleModel
+                && dstSM instanceof SinglePixelPackedSampleModel) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
+            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
+
+            if (sppsm1.getDataType() != DataBuffer.TYPE_INT
+                    || sppsm2.getDataType() != DataBuffer.TYPE_INT) {
+                return slowFilter(src, dst);
+            }
+
+            // Check sample models
+            if (!Arrays.equals(sppsm2.getBitOffsets(), offsets3c)
+                    || !Arrays.equals(sppsm2.getBitMasks(), masks3c)) {
+                return slowFilter(src, dst);
+            }
+
+            if (srcBands == 3) {
+                if (!Arrays.equals(sppsm1.getBitOffsets(), offsets3c)
+                        || !Arrays.equals(sppsm1.getBitMasks(), masks3c)) {
+                    return slowFilter(src, dst);
+                }
+            } else if (srcBands == 4) {
+                if (!Arrays.equals(sppsm1.getBitOffsets(), offsets4ac)
+                        || !Arrays.equals(sppsm1.getBitMasks(), masks4ac)) {
+                    return slowFilter(src, dst);
+                }
+            }
+
+            type = TYPE_BYTE4AC;
+            invertChannels = true;
+
+            srcStride = sppsm1.getScanlineStride() * 4;
+            dstStride = sppsm2.getScanlineStride() * 4;
+        } else if (srcSM instanceof PixelInterleavedSampleModel
+                && dstSM instanceof PixelInterleavedSampleModel) {
+            if (srcBands != 3) {
+                return slowFilter(src, dst);
+            }
+
+            int srcDataType = srcSM.getDataType();
+
+            switch (srcDataType) {
+                case DataBuffer.TYPE_BYTE:
+                    type = TYPE_BYTE3C;
+                    break;
+                case DataBuffer.TYPE_USHORT:
+                    type = TYPE_USHORT3C;
+                    break;
+                case DataBuffer.TYPE_SHORT:
+                    type = TYPE_SHORT3C;
+                    break;
+                default:
+                    return slowFilter(src, dst);
+            }
+
+            // Check PixelInterleavedSampleModel
+            PixelInterleavedSampleModel pism1 = (PixelInterleavedSampleModel)srcSM;
+            PixelInterleavedSampleModel pism2 = (PixelInterleavedSampleModel)dstSM;
+
+            if (srcDataType != pism2.getDataType() || pism1.getPixelStride() != 3
+                    || pism2.getPixelStride() != 3
+                    || !Arrays.equals(pism1.getBandOffsets(), pism2.getBandOffsets())) {
+                return slowFilter(src, dst);
+            }
+
+            if (Arrays.equals(pism1.getBandOffsets(), piInvOffsets)) {
+                invertChannels = true;
+            } else if (Arrays.equals(pism1.getBandOffsets(), piOffsets)) {
+                invertChannels = false;
+            } else {
+                return slowFilter(src, dst);
+            }
+
+            int dataTypeSize = DataBuffer.getDataTypeSize(srcDataType) / 8;
+
+            srcStride = pism1.getScanlineStride() * dataTypeSize;
+            dstStride = pism2.getScanlineStride() * dataTypeSize;
+        } else { // XXX - todo - IPP allows support for planar data also
+            return slowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                    || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        float ippMatrix[] = new float[12];
+
+        if (invertChannels) {
+            // IPP treats big endian integers like BGR, so we have to
+            // swap columns 1 and 3 and rows 1 and 3
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i * 4] = matrix[2 - i][2];
+                ippMatrix[i * 4 + 1] = matrix[2 - i][1];
+                ippMatrix[i * 4 + 2] = matrix[2 - i][0];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i * 4 + 3] = matrix[2 - i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i * 4 + 3] = matrix[2 - i][4];
+                }
+            }
+        } else {
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i * 4] = matrix[i][0];
+                ippMatrix[i * 4 + 1] = matrix[i][1];
+                ippMatrix[i * 4 + 2] = matrix[i][2];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i * 4 + 3] = matrix[i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i * 4 + 3] = matrix[i][4];
+                }
+            }
+        }
+
+        return ippColorTwist(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst
+                .getWidth(), dst.getHeight(), dstStride, ippMatrix, type, offsets, inPlace);
+    }
+
+    /**
+     * Ipp color twist.
+     * 
+     * @param srcData
+     *            the src data.
+     * @param srcWidth
+     *            the src width.
+     * @param srcHeight
+     *            the src height.
+     * @param srcStride
+     *            the src stride.
+     * @param dstData
+     *            the dst data.
+     * @param dstWidth
+     *            the dst width.
+     * @param dstHeight
+     *            the dst height.
+     * @param dstStride
+     *            the dst stride.
+     * @param ippMatrix
+     *            the ipp matrix.
+     * @param type
+     *            the type.
+     * @param offsets
+     *            the offsets.
+     * @param inPlace
+     *            the in place.
+     * @return the int.
+     */
+    private final native int ippColorTwist(Object srcData, int srcWidth, int srcHeight,
+            int srcStride, Object dstData, int dstWidth, int dstHeight, int dstStride,
+            float ippMatrix[], int type, int offsets[], boolean inPlace);
+
+    /**
+     * Simple combine bands.
+     * 
+     * @param srcData
+     *            the src data.
+     * @param srcWidth
+     *            the src width.
+     * @param srcHeight
+     *            the src height.
+     * @param srcStride
+     *            the src stride.
+     * @param srcChannels
+     *            the src channels.
+     * @param dstData
+     *            the dst data.
+     * @param dstStride
+     *            the dst stride.
+     * @param dstChannels
+     *            the dst channels.
+     * @param m
+     *            the m.
+     * @param offsets
+     *            the offsets.
+     * @return the int.
+     */
+    private final native int simpleCombineBands(Object srcData, int srcWidth, int srcHeight,
+            int srcStride, int srcChannels, Object dstData, int dstStride, int dstChannels,
+            float m[], int offsets[]);
+}
diff --git a/awt/java/awt/image/BandedSampleModel.java b/awt/java/awt/image/BandedSampleModel.java
new file mode 100644
index 0000000..0aa30d7
--- /dev/null
+++ b/awt/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,425 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandedSampleModel class provides samples of pixels in an image which is
+ * stored in a band interleaved method. Each pixel's sample takes one data
+ * element of the DataBuffer. The pixel stride for a BandedSampleModel is one.
+ * 
+ * @since Android 1.0
+ */
+public final class BandedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Creates the indices.
+     * 
+     * @param numBands
+     *            the num bands.
+     * @return the int[].
+     */
+    private static int[] createIndices(int numBands) {
+        int indices[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            indices[i] = i;
+        }
+        return indices;
+    }
+
+    /**
+     * Creates the offsets.
+     * 
+     * @param numBands
+     *            the num bands.
+     * @return the int[].
+     */
+    private static int[] createOffsets(int numBands) {
+        int offsets[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            offsets[i] = 0;
+        }
+        return offsets;
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified data type
+     * of samples, the width, height and bands number of image data.
+     * 
+     * @param dataType
+     *            the data type of samples.
+     * @param w
+     *            the width of image data.
+     * @param h
+     *            the height of image data.
+     * @param numBands
+     *            the number of bands.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int numBands) {
+        this(dataType, w, h, w, BandedSampleModel.createIndices(numBands), BandedSampleModel
+                .createOffsets(numBands));
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified data type
+     * of samples, the width, height and bands number of image data.
+     * 
+     * @param dataType
+     *            the data type of samples.
+     * @param w
+     *            the width of image data.
+     * @param h
+     *            the height of image data.
+     * @param scanlineStride
+     *            the scanline stride of the of the image data.
+     * @param bankIndices
+     *            the array of the bank indices.
+     * @param bandOffsets
+     *            the array of the band offsets.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int scanlineStride, int bankIndices[],
+            int bandOffsets[]) {
+        super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(size, numBanks);
+                break;
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferShort(size, numBanks);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(size, numBanks);
+                break;
+            case DataBuffer.TYPE_FLOAT:
+                data = new DataBufferFloat(size, numBanks);
+                break;
+            case DataBuffer.TYPE_DOUBLE:
+                data = new DataBufferDouble(size, numBanks);
+                break;
+        }
+
+        return data;
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int[] bands) {
+        if (bands.length > numBands) {
+            // awt.64=The number of the bands in the subset is greater than the
+            // number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new BandedSampleModel(dataType, width, height, scanlineStride, indices, offsets);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE: {
+                byte bdata[];
+
+                if (obj == null) {
+                    bdata = new byte[numBands];
+                } else {
+                    bdata = (byte[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    bdata[i] = (byte)getSample(x, y, i, data);
+                }
+
+                obj = bdata;
+                break;
+            }
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT: {
+                short sdata[];
+
+                if (obj == null) {
+                    sdata = new short[numBands];
+                } else {
+                    sdata = (short[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    sdata[i] = (short)getSample(x, y, i, data);
+                }
+
+                obj = sdata;
+                break;
+            }
+            case DataBuffer.TYPE_INT: {
+                int idata[];
+
+                if (obj == null) {
+                    idata = new int[numBands];
+                } else {
+                    idata = (int[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    idata[i] = getSample(x, y, i, data);
+                }
+
+                obj = idata;
+                break;
+            }
+            case DataBuffer.TYPE_FLOAT: {
+                float fdata[];
+
+                if (obj == null) {
+                    fdata = new float[numBands];
+                } else {
+                    fdata = (float[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    fdata[i] = getSampleFloat(x, y, i, data);
+                }
+
+                obj = fdata;
+                break;
+            }
+            case DataBuffer.TYPE_DOUBLE: {
+                double ddata[];
+
+                if (obj == null) {
+                    ddata = new double[numBands];
+                } else {
+                    ddata = (double[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    ddata[i] = getSampleDouble(x, y, i, data);
+                }
+
+                obj = ddata;
+                break;
+            }
+        }
+
+        return obj;
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x55;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                byte bdata[] = (byte[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, bdata[i] & 0xff, data);
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                short sdata[] = (short[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, sdata[i] & 0xffff, data);
+                }
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int idata[] = (int[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, idata[i], data);
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fdata[] = (float[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, fdata[i], data);
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double ddata[] = (double[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, ddata[i], data);
+                }
+                break;
+        }
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/image/BufferStrategy.java b/awt/java/awt/image/BufferStrategy.java
new file mode 100644
index 0000000..3c8779d
--- /dev/null
+++ b/awt/java/awt/image/BufferStrategy.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;
+
+import java.awt.BufferCapabilities;
+import java.awt.Graphics;
+
+/**
+ * The BufferStrategy abstract class provides an opportunity to organize the
+ * buffers for a Canvas or Window. The BufferStrategy implementation depends on
+ * hardware and software limitations. These limitations are detectable through
+ * the capabilities object which can be obtained by the GraphicsConfiguration of
+ * the Canvas or Window.
+ * 
+ * @since Android 1.0
+ */
+public abstract class BufferStrategy {
+
+    /**
+     * Returns true if the drawing buffer was lost since the last call of
+     * getDrawGraphics.
+     * 
+     * @return true if the drawing buffer was lost since the last call of
+     *         getDrawGraphics, false otherwise.
+     */
+    public abstract boolean contentsLost();
+
+    /**
+     * Returns true if the drawing buffer is restored from a lost state.
+     * 
+     * @return true if the drawing buffer is restored from a lost state, false
+     *         otherwise.
+     */
+    public abstract boolean contentsRestored();
+
+    /**
+     * Gets the BufferCapabilities of BufferStrategy.
+     * 
+     * @return the BufferCapabilities of BufferStrategy.
+     */
+    public abstract BufferCapabilities getCapabilities();
+
+    /**
+     * Gets the Graphics object to use to draw to the buffer.
+     * 
+     * @return the Graphics object to use to draw to the buffer.
+     */
+    public abstract Graphics getDrawGraphics();
+
+    /**
+     * Shows the next available buffer.
+     */
+    public abstract void show();
+
+}
diff --git a/awt/java/awt/image/BufferedImage.java b/awt/java/awt/image/BufferedImage.java
new file mode 100644
index 0000000..c9d58d9
--- /dev/null
+++ b/awt/java/awt/image/BufferedImage.java
@@ -0,0 +1,952 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.BufferedImageSource;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BufferedImage class describes an Image which contains a buffer of image
+ * data and includes a ColorModel and a Raster for this data. This class
+ * provides methods for obtaining and setting the Raster and for manipulating
+ * the ColorModel parameters.
+ * 
+ * @since Android 1.0
+ */
+public class BufferedImage extends Image implements WritableRenderedImage, Transparency {
+
+    /**
+     * The Constant TYPE_CUSTOM indicates that Image type is unknown.
+     */
+    public static final int TYPE_CUSTOM = 0;
+
+    /**
+     * The Constant TYPE_INT_RGB indicates an image with 8 bit RGB color
+     * components, it has a DirectColorModel without alpha.
+     */
+    public static final int TYPE_INT_RGB = 1;
+
+    /**
+     * The Constant TYPE_INT_ARGB indicates an image with 8 bit RGBA color
+     * components, it has a DirectColorModel with alpha.
+     */
+    public static final int TYPE_INT_ARGB = 2;
+
+    /**
+     * The Constant TYPE_INT_ARGB_PRE indicates an image with 8 bit RGBA color
+     * components, it has a DirectColorModel with alpha, and image data is
+     * pre-multiplied by alpha.
+     */
+    public static final int TYPE_INT_ARGB_PRE = 3;
+
+    /**
+     * The Constant TYPE_INT_BGR indicates an image with 8 bit RGB color
+     * components, BGR color model (with the colors Blue, Green, and Red). There
+     * is no alpha. The image has a DirectColorModel.
+     */
+    public static final int TYPE_INT_BGR = 4;
+
+    /**
+     * The Constant TYPE_3BYTE_BGR indicates an image with 8 bit RGB color
+     * components, BGR color model (with the colors Blue, Green, and Red stored
+     * in 3 bytes). There is no alpha. The image has a ComponentColorModel.
+     */
+    public static final int TYPE_3BYTE_BGR = 5;
+
+    /**
+     * The Constant TYPE_4BYTE_ABGR indicates an image with 8 bit RGBA color
+     * components stored in 3 bytes and 1 byte of alpha. It has a
+     * ComponentColorModel with alpha.
+     */
+    public static final int TYPE_4BYTE_ABGR = 6;
+
+    /**
+     * The Constant TYPE_4BYTE_ABGR_PRE indicates an image with 8 bit RGBA color
+     * components stored in 3 bytes and 1 byte for alpha. The image has a
+     * ComponentColorModel with alpha. The color data is pre-multiplied with
+     * alpha.
+     */
+    public static final int TYPE_4BYTE_ABGR_PRE = 7;
+
+    /**
+     * The Constant TYPE_USHORT_565_RGB indicates an image with 565 RGB color
+     * components (5-bits red, 6-bits green, 5-bits blue) with no alpha. This
+     * image has a DirectColorModel.
+     */
+    public static final int TYPE_USHORT_565_RGB = 8;
+
+    /**
+     * The Constant TYPE_USHORT_555_RGB indicates an image with 555 RGB color
+     * components (5-bits red, 5-bits green, 5-bits blue) with no alpha. This
+     * image has a DirectColorModel.
+     */
+    public static final int TYPE_USHORT_555_RGB = 9;
+
+    /**
+     * The Constant TYPE_BYTE_GRAY indicates a unsigned byte image. This image
+     * has a ComponentColorModel with a CS_GRAY ColorSpace.
+     */
+    public static final int TYPE_BYTE_GRAY = 10;
+
+    /**
+     * The Constant TYPE_USHORT_GRAY indicates an unsigned short image. This
+     * image has a ComponentColorModel with a CS_GRAY ColorSpace.
+     */
+    public static final int TYPE_USHORT_GRAY = 11;
+
+    /**
+     * The Constant TYPE_BYTE_BINARY indicates an opaque byte-packed 1, 2 or 4
+     * bit image. The image has an IndexColorModel without alpha.
+     */
+    public static final int TYPE_BYTE_BINARY = 12;
+
+    /**
+     * The Constant TYPE_BYTE_INDEXED indicates an indexed byte image.
+     */
+    public static final int TYPE_BYTE_INDEXED = 13;
+
+    /**
+     * The Constant ALPHA_MASK.
+     */
+    private static final int ALPHA_MASK = 0xff000000;
+
+    /**
+     * The Constant RED_MASK.
+     */
+    private static final int RED_MASK = 0x00ff0000;
+
+    /**
+     * The Constant GREEN_MASK.
+     */
+    private static final int GREEN_MASK = 0x0000ff00;
+
+    /**
+     * The Constant BLUE_MASK.
+     */
+    private static final int BLUE_MASK = 0x000000ff;
+
+    /**
+     * The Constant RED_BGR_MASK.
+     */
+    private static final int RED_BGR_MASK = 0x000000ff;
+
+    /**
+     * The Constant GREEN_BGR_MASK.
+     */
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+
+    /**
+     * The Constant BLUE_BGR_MASK.
+     */
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+
+    /**
+     * The Constant RED_565_MASK.
+     */
+    private static final int RED_565_MASK = 0xf800;
+
+    /**
+     * The Constant GREEN_565_MASK.
+     */
+    private static final int GREEN_565_MASK = 0x07e0;
+
+    /**
+     * The Constant BLUE_565_MASK.
+     */
+    private static final int BLUE_565_MASK = 0x001f;
+
+    /**
+     * The Constant RED_555_MASK.
+     */
+    private static final int RED_555_MASK = 0x7c00;
+
+    /**
+     * The Constant GREEN_555_MASK.
+     */
+    private static final int GREEN_555_MASK = 0x03e0;
+
+    /**
+     * The Constant BLUE_555_MASK.
+     */
+    private static final int BLUE_555_MASK = 0x001f;
+
+    /**
+     * The cm.
+     */
+    private ColorModel cm;
+
+    /**
+     * The raster.
+     */
+    private final WritableRaster raster;
+
+    /**
+     * The image type.
+     */
+    private final int imageType;
+
+    /**
+     * The properties.
+     */
+    private Hashtable<?, ?> properties;
+
+    // Surface of the Buffered Image - used for blitting one Buffered Image
+    // on the other one or on the Component
+    /**
+     * The image surf.
+     */
+    private final ImageSurface imageSurf;
+
+    /**
+     * Instantiates a new BufferedImage with the specified ColorModel, and
+     * WritableRaster objects. The Raster data can be be divided or multiplied
+     * by alpha. It depends on the alphaPremultiplied state in the ColorModel.
+     * 
+     * @param cm
+     *            the ColorModel of the new image.
+     * @param raster
+     *            the WritableRaster of the new image.
+     * @param isRasterPremultiplied
+     *            if true the data of the specified Raster is pre-multiplied by
+     *            alpha.
+     * @param properties
+     *            the properties of new Image.
+     */
+    public BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied,
+            Hashtable<?, ?> properties) {
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+
+        if (raster.getMinX() != 0 || raster.getMinY() != 0) {
+            // awt.228=minX or minY of this raster not equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.228")); //$NON-NLS-1$
+        }
+
+        this.cm = cm;
+        this.raster = raster;
+        this.properties = properties;
+
+        coerceData(isRasterPremultiplied);
+
+        imageType = Surface.getType(cm, raster);
+
+        imageSurf = createImageSurface(imageType);
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * predefined image type (TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED) and the
+     * specified IndexColorModel.
+     * 
+     * @param width
+     *            the width of new image.
+     * @param height
+     *            the height of new image.
+     * @param imageType
+     *            the predefined image type.
+     * @param cm
+     *            the specified IndexColorModel.
+     */
+    public BufferedImage(int width, int height, int imageType, IndexColorModel cm) {
+        switch (imageType) {
+            case TYPE_BYTE_BINARY:
+                if (cm.hasAlpha()) {
+                    // awt.227=This image type can't have alpha
+                    throw new IllegalArgumentException(Messages.getString("awt.227")); //$NON-NLS-1$
+                }
+                int pixel_bits = 0;
+                int mapSize = cm.getMapSize();
+                if (mapSize <= 2) {
+                    pixel_bits = 1;
+                } else if (mapSize <= 4) {
+                    pixel_bits = 2;
+                } else if (mapSize <= 16) {
+                    pixel_bits = 4;
+                } else {
+                    // awt.221=The imageType is TYPE_BYTE_BINARY and the color
+                    // map has more than 16 entries
+                    throw new IllegalArgumentException(Messages.getString("awt.221")); //$NON-NLS-1$
+                }
+
+                raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
+                        pixel_bits, null);
+                break;
+
+            case TYPE_BYTE_INDEXED:
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
+                        null);
+                break;
+
+            default:
+                // awt.222=The imageType is not TYPE_BYTE_BINARY or
+                // TYPE_BYTE_INDEXED
+                throw new IllegalArgumentException(Messages.getString("awt.222")); //$NON-NLS-1$
+
+        }
+
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.223=The imageType is not compatible with ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.223")); //$NON-NLS-1$
+        }
+
+        this.cm = cm;
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height and
+     * predefined image type.
+     * 
+     * @param width
+     *            the width of new image.
+     * @param height
+     *            the height of new image.
+     * @param imageType
+     *            the predefined image type.
+     */
+    public BufferedImage(int width, int height, int imageType) {
+
+        switch (imageType) {
+            case TYPE_INT_RGB:
+                cm = new DirectColorModel(24, RED_MASK, GREEN_MASK, BLUE_MASK);
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_INT_ARGB:
+                cm = ColorModel.getRGBdefault();
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_INT_ARGB_PRE:
+                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, RED_MASK,
+                        GREEN_MASK, BLUE_MASK, ALPHA_MASK, true, DataBuffer.TYPE_INT);
+
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_INT_BGR:
+                cm = new DirectColorModel(24, RED_BGR_MASK, GREEN_BGR_MASK, BLUE_BGR_MASK);
+
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_3BYTE_BGR: {
+                int bits[] = {
+                        8, 8, 8
+                };
+                int bandOffsets[] = {
+                        2, 1, 0
+                };
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
+                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+                        width * 3, 3, bandOffsets, null);
+            }
+                break;
+
+            case TYPE_4BYTE_ABGR: {
+                int bits[] = {
+                        8, 8, 8, 8
+                };
+                int bandOffsets[] = {
+                        3, 2, 1, 0
+                };
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
+                        true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+                        width * 4, 4, bandOffsets, null);
+            }
+                break;
+
+            case TYPE_4BYTE_ABGR_PRE: {
+                int bits[] = {
+                        8, 8, 8, 8
+                };
+                int bandOffsets[] = {
+                        3, 2, 1, 0
+                };
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits,
+                        true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+                        width * 4, 4, bandOffsets, null);
+            }
+                break;
+
+            case TYPE_USHORT_565_RGB:
+                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 16,
+                        RED_565_MASK, GREEN_565_MASK, BLUE_565_MASK, 0, false,
+                        DataBuffer.TYPE_USHORT);
+
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_USHORT_555_RGB:
+                cm = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 15,
+                        RED_555_MASK, GREEN_555_MASK, BLUE_555_MASK, 0, false,
+                        DataBuffer.TYPE_USHORT);
+
+                raster = cm.createCompatibleWritableRaster(width, height);
+                break;
+
+            case TYPE_BYTE_GRAY: {
+                int bits[] = {
+                    8
+                };
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), bits,
+                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+
+                raster = cm.createCompatibleWritableRaster(width, height);
+            }
+                break;
+
+            case TYPE_USHORT_GRAY: {
+                int bits[] = {
+                    16
+                };
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), bits,
+                        false, false, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
+                raster = cm.createCompatibleWritableRaster(width, height);
+            }
+                break;
+
+            case TYPE_BYTE_BINARY: {
+                int colorMap[] = {
+                        0, 0xffffff
+                };
+                cm = new IndexColorModel(1, 2, colorMap, 0, false, -1, DataBuffer.TYPE_BYTE);
+
+                raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width, height, 1, 1, null);
+            }
+                break;
+
+            case TYPE_BYTE_INDEXED: {
+                int colorMap[] = new int[256];
+                int i = 0;
+                for (int r = 0; r < 256; r += 51) {
+                    for (int g = 0; g < 256; g += 51) {
+                        for (int b = 0; b < 256; b += 51) {
+                            colorMap[i] = (r << 16) | (g << 8) | b;
+                            i++;
+                        }
+                    }
+                }
+
+                int gray = 0x12;
+                for (; i < 256; i++, gray += 6) {
+                    colorMap[i] = (gray << 16) | (gray << 8) | gray;
+                }
+                cm = new IndexColorModel(8, 256, colorMap, 0, false, -1, DataBuffer.TYPE_BYTE);
+                raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, 1,
+                        null);
+
+            }
+                break;
+            default:
+                // awt.224=Unknown image type
+                throw new IllegalArgumentException(Messages.getString("awt.224")); //$NON-NLS-1$
+        }
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        return getProperty(name);
+    }
+
+    public Object getProperty(String name) {
+        if (name == null) {
+            // awt.225=Property name is null
+            throw new NullPointerException(Messages.getString("awt.225")); //$NON-NLS-1$
+        }
+        if (properties == null) {
+            return Image.UndefinedProperty;
+        }
+        Object property = properties.get(name);
+        if (property == null) {
+            property = Image.UndefinedProperty;
+        }
+        return property;
+    }
+
+    public WritableRaster copyData(WritableRaster outRaster) {
+        if (outRaster == null) {
+            outRaster = Raster.createWritableRaster(raster.getSampleModel(), new Point(raster
+                    .getSampleModelTranslateX(), raster.getSampleModelTranslateY()));
+        }
+
+        int w = outRaster.getWidth();
+        int h = outRaster.getHeight();
+        int minX = outRaster.getMinX();
+        int minY = outRaster.getMinY();
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outRaster.setDataElements(minX, minY, w, h, data);
+
+        return outRaster;
+    }
+
+    public Raster getData(Rectangle rect) {
+        int minX = rect.x;
+        int minY = rect.y;
+        int w = rect.width;
+        int h = rect.height;
+
+        SampleModel sm = raster.getSampleModel();
+        SampleModel nsm = sm.createCompatibleSampleModel(w, h);
+        WritableRaster outr = Raster.createWritableRaster(nsm, rect.getLocation());
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+        return outr;
+    }
+
+    public Vector<RenderedImage> getSources() {
+        return null;
+    }
+
+    public String[] getPropertyNames() {
+        if (properties == null) {
+            return null;
+        }
+        Vector<String> v = new Vector<String>();
+        for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
+            try {
+                v.add((String)e.nextElement());
+            } catch (ClassCastException ex) {
+            }
+        }
+        int size = v.size();
+        if (size > 0) {
+            String names[] = new String[size];
+            for (int i = 0; i < size; i++) {
+                names[i] = v.elementAt(i);
+            }
+            return names;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string representation of this BufferedImage object.
+     * 
+     * @return the string representation of this BufferedImage object.
+     */
+    @Override
+    public String toString() {
+        return "BufferedImage@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
+                ": type = " + imageType + " " + cm + " " + raster; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    public WritableRaster getWritableTile(int tileX, int tileY) {
+        return raster;
+    }
+
+    /**
+     * Gets the WritableRaster of this BufferedImage.
+     * 
+     * @return the WritableRaster of this BufferedImage.
+     */
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Gets a WritableRaster object which contains the alpha channel of
+     * BufferedImage object with ColorModel objects that supports a separate
+     * alpha channel such as ComponentColorModel or DirectColorModel.
+     * 
+     * @return the WritableRaster object which contains the alpha channel of
+     *         this BufferedImage.
+     */
+    public WritableRaster getAlphaRaster() {
+        return cm.getAlphaRaster(raster);
+    }
+
+    public void removeTileObserver(TileObserver to) {
+    }
+
+    public void addTileObserver(TileObserver to) {
+    }
+
+    public SampleModel getSampleModel() {
+        return raster.getSampleModel();
+    }
+
+    public void setData(Raster r) {
+
+        Rectangle from = r.getBounds();
+        Rectangle to = raster.getBounds();
+        Rectangle intersection = to.intersection(from);
+
+        int minX = intersection.x;
+        int minY = intersection.y;
+        int w = intersection.width;
+        int h = intersection.height;
+
+        Object data = null;
+
+        data = r.getDataElements(minX, minY, w, h, data);
+        raster.setDataElements(minX, minY, w, h, data);
+    }
+
+    public Raster getTile(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return raster;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public Raster getData() {
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        WritableRaster outr = Raster.createWritableRaster(raster.getSampleModel(), new Point(raster
+                .getSampleModelTranslateX(), raster.getSampleModelTranslateY()));
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+
+        return outr;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return new BufferedImageSource(this, properties);
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        return raster.getWidth();
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        return raster.getHeight();
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    /**
+     * Gets the rectangular area of this BufferedImage as a subimage.
+     * 
+     * @param x
+     *            the x coordinate.
+     * @param y
+     *            the y coordinate.
+     * @param w
+     *            the width of the subimage.
+     * @param h
+     *            the height of the subimage.
+     * @return the BufferedImage.
+     */
+    public BufferedImage getSubimage(int x, int y, int w, int h) {
+        WritableRaster wr = raster.createWritableChild(x, y, w, h, 0, 0, null);
+        return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);
+    }
+
+    public Point[] getWritableTileIndices() {
+        Point points[] = new Point[1];
+        points[0] = new Point(0, 0);
+        return points;
+    }
+
+    /**
+     * Creates the Graphics2D object which allows to draw into this
+     * BufferedImage.
+     * 
+     * @return the graphics2D object.
+     */
+    public Graphics2D createGraphics() {
+        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        // return ge.createGraphics(this);
+        // ???AWT hack, FIXME
+        // return AndroidGraphics2D.getInstance();
+        // throw new RuntimeException("Not implemented!");
+        return null;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    /**
+     * Coerces the data to achieve the state which is specified by the
+     * isAlphaPremultiplied variable.
+     * 
+     * @param isAlphaPremultiplied
+     *            the is alpha pre-multiplied state.
+     */
+    public void coerceData(boolean isAlphaPremultiplied) {
+        if (cm.hasAlpha() && cm.isAlphaPremultiplied() != isAlphaPremultiplied) {
+            cm = cm.coerceData(raster, isAlphaPremultiplied);
+        }
+    }
+
+    /**
+     * Gets an array of colors in the TYPE_INT_ARGB color model and default sRGB
+     * color space of the specified area of this BufferedImage. The result array
+     * is composed by the following algorithm:
+     * <p>
+     * pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)]
+     * </p>
+     * 
+     * @param startX
+     *            the start X area coordinate.
+     * @param startY
+     *            the start Y area coordinate.
+     * @param w
+     *            the width of the area.
+     * @param h
+     *            the height of the area.
+     * @param rgbArray
+     *            the result array will be stored to this array.
+     * @param offset
+     *            the offset of the rgbArray array.
+     * @param scansize
+     *            the scanline stride for the rgbArray.
+     * @return an array of colors for the specified area.
+     */
+    public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset,
+            int scansize) {
+        if (rgbArray == null) {
+            rgbArray = new int[offset + h * scansize];
+        }
+
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                rgbArray[i] = cm.getRGB(raster.getDataElements(x, y, null));
+            }
+        }
+        return rgbArray;
+    }
+
+    /**
+     * Sets RGB values from the specified array to the specified BufferedImage
+     * area. The pixels are in the default RGB color model (TYPE_INT_ARGB) and
+     * default sRGB color space.
+     * 
+     * @param startX
+     *            the start X coordinate.
+     * @param startY
+     *            the start Y coordinate.
+     * @param w
+     *            the width of the BufferedImage area.
+     * @param h
+     *            the height of the BufferedImage area.
+     * @param rgbArray
+     *            the array of RGB values.
+     * @param offset
+     *            the offset of the rgbArray array.
+     * @param scansize
+     *            the scanline stride for the rgbArray.
+     */
+    public void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset,
+            int scansize) {
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                raster.setDataElements(x, y, cm.getDataElements(rgbArray[i], null));
+            }
+        }
+    }
+
+    /**
+     * Sets a the specified RGB value to the specified pixel of this
+     * BufferedImage. The pixel should be in the default RGB color model
+     * (TYPE_INT_ARGB) and default sRGB color space.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param rgb
+     *            the RGB value to be set.
+     */
+    public synchronized void setRGB(int x, int y, int rgb) {
+        raster.setDataElements(x, y, cm.getDataElements(rgb, null));
+    }
+
+    public boolean isTileWritable(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return true;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public void releaseWritableTile(int tileX, int tileY) {
+    }
+
+    /**
+     * Gets a color in the TYPE_INT_ARGB color model and default sRGB color
+     * space of the specified pixel.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @return the color of the specified pixel in the TYPE_INT_ARGB color model
+     *         and default sRGB color space.
+     */
+    public int getRGB(int x, int y) {
+        return cm.getRGB(raster.getDataElements(x, y, null));
+    }
+
+    /**
+     * Returns true if alpha is pre-multiplied, false if alpha is not
+     * pre-multiplied or there is no alpha.
+     * 
+     * @return true if alpha is pre-multiplied, false if alpha is not
+     *         pre-multiplied or there is no alpha.
+     */
+    public boolean isAlphaPremultiplied() {
+        return cm.isAlphaPremultiplied();
+    }
+
+    public boolean hasTileWriters() {
+        return true;
+    }
+
+    @Override
+    public void flush() {
+        imageSurf.dispose();
+    }
+
+    public int getWidth() {
+        return raster.getWidth();
+    }
+
+    /**
+     * Gets the image type.
+     * 
+     * @return the image type.
+     */
+    public int getType() {
+        return imageType;
+    }
+
+    public int getTileWidth() {
+        return raster.getWidth();
+    }
+
+    public int getTileHeight() {
+        return raster.getHeight();
+    }
+
+    public int getTileGridYOffset() {
+        return raster.getSampleModelTranslateY();
+    }
+
+    public int getTileGridXOffset() {
+        return raster.getSampleModelTranslateX();
+    }
+
+    public int getNumYTiles() {
+        return 1;
+    }
+
+    public int getNumXTiles() {
+        return 1;
+    }
+
+    public int getMinY() {
+        return raster.getMinY();
+    }
+
+    public int getMinX() {
+        return raster.getMinX();
+    }
+
+    public int getMinTileY() {
+        return 0;
+    }
+
+    public int getMinTileX() {
+        return 0;
+    }
+
+    public int getHeight() {
+        return raster.getHeight();
+    }
+
+    /**
+     * Creates the image surface.
+     * 
+     * @param type
+     *            the type.
+     * @return the image surface.
+     */
+    private ImageSurface createImageSurface(int type) {
+        return new ImageSurface(getColorModel(), getRaster(), type);
+    }
+
+    /**
+     * Gets the image surface.
+     * 
+     * @return the image surface.
+     */
+    ImageSurface getImageSurface() {
+        return imageSurf;
+    }
+
+    public int getTransparency() {
+        return cm.getTransparency();
+    }
+}
diff --git a/awt/java/awt/image/BufferedImageFilter.java b/awt/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 0000000..8b6fcf0
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,397 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BufferedImageFilter class provides filtering operations to the
+ * BufferedImage objects using operators which implement BufferedImageOp
+ * interface.
+ * 
+ * @since Android 1.0
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable {
+
+    /**
+     * The Constant accessor.
+     */
+    private static final AwtImageBackdoorAccessor accessor = AwtImageBackdoorAccessor.getInstance();
+
+    /**
+     * The op.
+     */
+    private BufferedImageOp op;
+
+    /**
+     * The raster.
+     */
+    private WritableRaster raster;
+
+    /**
+     * The i data.
+     */
+    private int iData[];
+
+    /**
+     * The b data.
+     */
+    private byte bData[];
+
+    /**
+     * The width.
+     */
+    private int width;
+
+    /**
+     * The height.
+     */
+    private int height;
+
+    /**
+     * The cm.
+     */
+    private ColorModel cm;
+
+    /**
+     * The forced rgb.
+     */
+    private boolean forcedRGB = false;
+
+    /**
+     * The transfer type.
+     */
+    private int transferType = DataBuffer.TYPE_UNDEFINED;
+
+    /**
+     * Instantiates a new BufferedImageFilter with the specified BufferedImageOp
+     * operator.
+     * 
+     * @param op
+     *            the specified BufferedImageOp operator.
+     * @throws NullPointerException
+     *             if BufferedImageOp is null.
+     */
+    public BufferedImageFilter(BufferedImageOp op) {
+        if (op == null) {
+            throw new NullPointerException(Messages.getString("awt.05")); //$NON-NLS-1$
+        }
+        this.op = op;
+    }
+
+    /**
+     * Gets the BufferedImageOp operator associated with this
+     * BufferedImageFilter object.
+     * 
+     * @return the BufferedImageOp associated with this BufferedImageFilter
+     *         object.
+     */
+    public BufferedImageOp getBufferedImageOp() {
+        return op;
+    }
+
+    @Override
+    public void setDimensions(int width, int height) {
+        this.width = width;
+        this.height = height;
+        // Stop image consuming if no pixels expected.
+        if (width <= 0 || height <= 0) {
+            consumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            reset();
+        }
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if (this.cm != null && this.cm != model && raster != null) {
+            forceRGB();
+        } else {
+            this.cm = model;
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, true);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, false);
+    }
+
+    @Override
+    public void imageComplete(int status) {
+        if (status == STATICIMAGEDONE || status == SINGLEFRAMEDONE) {
+            BufferedImage bim = new BufferedImage(cm, raster, cm.isAlphaPremultiplied, null);
+            bim = op.filter(bim, null);
+            DataBuffer dstDb = bim.getRaster().getDataBuffer();
+            ColorModel dstCm = bim.getColorModel();
+            int dstW = bim.getWidth();
+            int dstH = bim.getHeight();
+
+            consumer.setDimensions(dstW, dstH);
+
+            if (dstDb.getDataType() == DataBuffer.TYPE_INT) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataInt(dstDb), 0, dstW);
+            } else if (dstDb.getDataType() == DataBuffer.TYPE_BYTE) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataByte(dstDb), 0, dstW);
+            } else {
+                int dstData[] = bim.getRGB(0, 0, dstW, dstH, null, 0, dstW);
+                dstCm = ColorModel.getRGBdefault();
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, dstData, 0, dstW);
+            }
+        } else if (status == IMAGEERROR || status == IMAGEABORTED) {
+            reset();
+        }
+
+        consumer.imageComplete(status);
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     * @param w
+     *            the w.
+     * @param h
+     *            the h.
+     * @param model
+     *            the model.
+     * @param pixels
+     *            the pixels.
+     * @param off
+     *            the off.
+     * @param scansize
+     *            the scansize.
+     * @param isByteData
+     *            the is byte data.
+     */
+    private void setPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off,
+            int scansize, boolean isByteData) {
+        // Check bounds
+        // Need to copy only the pixels that will fit into the destination area
+        if (x < 0) {
+            w -= x;
+            off += x;
+            x = 0;
+        }
+
+        if (y < 0) {
+            h -= y;
+            off += y * scansize;
+            y = 0;
+        }
+
+        if (x + w > width) {
+            w = width - x;
+        }
+
+        if (y + h > height) {
+            h = height - y;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        // Check model
+        if (this.cm == null) {
+            setColorModel(model);
+        } else if (model == null) {
+            model = this.cm;
+        } else if (!model.equals(this.cm)) {
+            forceRGB();
+        }
+
+        boolean canArraycopy;
+        // Process pixels
+        switch (transferType) {
+            case DataBuffer.TYPE_UNDEFINED: {
+                if (isByteData) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                    createRaster(transferType);
+                    // bData = new byte[width*height];
+                    canArraycopy = !forcedRGB;
+                    break;
+                }
+                transferType = DataBuffer.TYPE_INT;
+                createRaster(transferType);
+                // iData = new int[width*height];
+                canArraycopy = !forcedRGB || model.equals(ColorModel.getRGBdefault());
+                break;
+            } // And proceed to copy the pixels
+            case DataBuffer.TYPE_INT: {
+                if (isByteData) { // There are int data already but the new data
+                    // are bytes
+                    forceRGB();
+                    canArraycopy = false;
+                    break;
+                } else if (!forcedRGB || model.equals(ColorModel.getRGBdefault())) {
+                    canArraycopy = true;
+                    break;
+                } // Else fallback to the RGB conversion
+            }
+            case DataBuffer.TYPE_BYTE: {
+                if (isByteData && !forcedRGB) {
+                    canArraycopy = true;
+                    break;
+                }
+
+                // RGB conversion
+                canArraycopy = false;
+                break;
+            }
+            default: {
+                throw new IllegalStateException(Messages.getString("awt.06")); //$NON-NLS-1$
+            }
+        }
+
+        off += x;
+        int maxOffset = off + h * scansize;
+        int dstOffset = x + y * width;
+
+        if (canArraycopy) {
+            Object dstArray = isByteData ? (Object)bData : (Object)iData;
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                System.arraycopy(pixels, off, dstArray, dstOffset, w);
+            }
+        } else {
+            // RGB conversion
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                int srcPos = off;
+                int dstPos = dstOffset;
+                int maxDstPos = dstOffset + w;
+                for (; dstPos < maxDstPos; dstPos++, srcPos++) {
+                    iData[dstPos] = model.getRGB(isByteData ? ((byte[])pixels)[srcPos]
+                            : ((int[])pixels)[srcPos]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Force rgb.
+     */
+    private void forceRGB() {
+        if (!forcedRGB) {
+            forcedRGB = true;
+            int size = width * height;
+            int rgbData[] = new int[size];
+
+            if (bData != null) {
+                for (int i = 0; i < size; i++) {
+                    rgbData[i] = cm.getRGB(bData[i]);
+                }
+            } else if (iData != null) {
+                for (int i = 0; i < size; i++) {
+                    rgbData[i] = cm.getRGB(iData[i]);
+                }
+            }
+
+            cm = ColorModel.getRGBdefault();
+            DataBufferInt db = new DataBufferInt(rgbData, size);
+            int masks[] = new int[] {
+                    0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
+            };
+            raster = Raster.createPackedRaster(db, width, height, width, masks, null);
+            iData = accessor.getDataInt(db);
+            bData = null;
+            transferType = DataBuffer.TYPE_INT;
+        }
+    }
+
+    /**
+     * Reset.
+     */
+    private void reset() {
+        width = 0;
+        height = 0;
+        forcedRGB = false;
+        cm = null;
+        iData = null;
+        bData = null;
+        transferType = DataBuffer.TYPE_UNDEFINED;
+        raster = null;
+    }
+
+    /**
+     * Creates the raster.
+     * 
+     * @param dataType
+     *            the data type.
+     */
+    private void createRaster(int dataType) {
+        boolean createdValidBuffer = false;
+        try {
+            raster = cm.createCompatibleWritableRaster(width, height);
+            int rasterType = raster.getDataBuffer().getDataType();
+            if (rasterType == dataType) {
+                switch (rasterType) {
+                    case DataBuffer.TYPE_INT: {
+                        iData = accessor.getDataInt(raster.getDataBuffer());
+                        if (iData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    case DataBuffer.TYPE_BYTE: {
+                        bData = accessor.getDataByte(raster.getDataBuffer());
+                        if (bData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    default:
+                        createdValidBuffer = false;
+                }
+
+                if (cm == ColorModel.getRGBdefault()) {
+                    forcedRGB = true;
+                }
+            } else {
+                createdValidBuffer = false;
+            }
+        } catch (Exception e) {
+            createdValidBuffer = false;
+        }
+
+        if (createdValidBuffer == false) {
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            iData = accessor.getDataInt(raster.getDataBuffer());
+            bData = null;
+            forcedRGB = true;
+        }
+    }
+}
diff --git a/awt/java/awt/image/BufferedImageOp.java b/awt/java/awt/image/BufferedImageOp.java
new file mode 100644
index 0000000..883a39d
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageOp.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The BufferedImageOp interface provides methods for performing transformations
+ * from source data to destination data for BufferedImage objects. An object
+ * implementing this interface can be passed into a BufferedImageFilter to
+ * operate on a BufferedImage.
+ * 
+ * @since Android 1.0
+ */
+public interface BufferedImageOp {
+
+    /**
+     * Creates a destination image with the specified BufferedImage and
+     * ColorModel; this destination image is empty and has the correct size and
+     * number of bands.
+     * 
+     * @param src
+     *            the source BufferedImage.
+     * @param destCM
+     *            the destination ColorModel.
+     * @return the BufferedImage.
+     */
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM);
+
+    /**
+     * Performs a filter operation on the source BufferedImage and stores the
+     * resulting BufferedImage to the destination BufferedImage. If the
+     * destination BufferedImage is null, a BufferedImage with an appropriate
+     * ColorModel is created.
+     * 
+     * @param src
+     *            the source BufferedImage.
+     * @param dest
+     *            the destination BufferedImage, where the result is stored.
+     * @return the filtered BufferedImage.
+     */
+    public BufferedImage filter(BufferedImage src, BufferedImage dest);
+
+    /**
+     * Gets the bounds of filtered image.
+     * 
+     * @param src
+     *            the source BufferedImage to be filtered.
+     * @return the rectangle bounds of filtered image.
+     */
+    public Rectangle2D getBounds2D(BufferedImage src);
+
+    /**
+     * Gets the point of the destination image which corresponds to the
+     * specified point in the source image.
+     * 
+     * @param srcPt
+     *            the point of the source image.
+     * @param dstPt
+     *            the point where the result will be stored.
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
+
+    /**
+     * Gets the RenderingHints of the BufferedImageOp.
+     * 
+     * @return the RenderingHints of the BufferedImageOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/ByteLookupTable.java b/awt/java/awt/image/ByteLookupTable.java
new file mode 100644
index 0000000..27cee30
--- /dev/null
+++ b/awt/java/awt/image/ByteLookupTable.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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ByteLookupTable class provides functionality for lookup operations, and
+ * is defined by an input byte array for bands or components of image and an
+ * offset value. The offset value will be subtracted from the input values
+ * before indexing the input arrays. The output of a lookup operation is
+ * represented as an array of unsigned bytes.
+ * 
+ * @since Android 1.0
+ */
+public class ByteLookupTable extends LookupTable {
+
+    /**
+     * The data.
+     */
+    private byte data[][];
+
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value and
+     * the specified byte array which represents the lookup table for all bands.
+     * 
+     * @param offset
+     *            the offset value.
+     * @param data
+     *            the data array of bytes.
+     */
+    public ByteLookupTable(int offset, byte[] data) {
+        super(offset, 1);
+        if (data.length < 1)
+            throw new IllegalArgumentException("Length of data should not be less then one");
+        this.data = new byte[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value and
+     * the specified byte array of arrays which represents the lookup table for
+     * each band.
+     * 
+     * @param offset
+     *            the offset value.
+     * @param data
+     *            the data array of bytes array for each band.
+     */
+    public ByteLookupTable(int offset, byte[][] data) {
+        super(offset, data.length);
+        this.data = new byte[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ByteLookupTable object. If this
+     * ByteLookupTable object has one byte array for all bands, the returned
+     * array length is one.
+     * 
+     * @return the lookup table of this ByteLookupTable object.
+     */
+    public final byte[][] getTable() {
+        // Returns data by reference
+        return data;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i] - offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i] - offset];
+            }
+        }
+
+        return dst;
+    }
+
+    /**
+     * Returns a byte array which contains samples of the specified pixel which
+     * is translated with the lookup table of this ByteLookupTable object. The
+     * resulted array is stored to the dst array.
+     * 
+     * @param src
+     *            the source array.
+     * @param dst
+     *            the destination array where the result can be stored.
+     * @return the byte array of translated samples of a pixel.
+     */
+    public byte[] lookupPixel(byte[] src, byte[] dst) {
+        if (dst == null) {
+            dst = new byte[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i] - offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i] - offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/ColorConvertOp.java b/awt/java/awt/image/ColorConvertOp.java
new file mode 100644
index 0000000..1a1700b
--- /dev/null
+++ b/awt/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,710 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorConvertOp class converts the pixels of the data in the source image
+ * with the specified ColorSpace objects or an array of ICC_Profile objects. The
+ * result pixels are scaled to the precision of the destination image.
+ * 
+ * @since Android 1.0
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp {
+    // Unused but required by interfaces
+    /**
+     * The rendering hints.
+     */
+    RenderingHints renderingHints;
+
+    // Sequence consisting of ColorSpace and ICC_Profile elements
+    /**
+     * The conversion sequence.
+     */
+    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for
+
+    // null
+
+    // Not null if ColorConvertOp is constructed from the array of ICC profiles
+    /**
+     * The mid profiles.
+     */
+    private ICC_Profile midProfiles[];
+
+    /**
+     * The cc.
+     */
+    private final ColorConverter cc = new ColorConverter();
+
+    /**
+     * The t creator.
+     */
+    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
+
+    /**
+     * The is icc.
+     */
+    private boolean isICC = true;
+
+    // Cached ICC_Transform
+    /**
+     * The Class ICC_TransfomCreator.
+     */
+    private class ICC_TransfomCreator {
+
+        /**
+         * The transform.
+         */
+        private ICC_Transform transform;
+
+        /**
+         * The max components.
+         */
+        private int maxComponents;
+
+        /**
+         * For the full ICC case.
+         * 
+         * @param src
+         *            the src.
+         * @param dst
+         *            the dst.
+         * @param convSeq
+         *            the conv seq.
+         * @return the transform.
+         */
+        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
+            if (transform != null && src == transform.getSrc() && dst == transform.getDst()) {
+                return transform;
+            }
+
+            int length = convSeq.length;
+            int srcFlg = 0, dstFlg = 0;
+
+            if (length == 0 || src != convSeq[0]) {
+                if (src != null) {
+                    srcFlg = 1; // need src profile
+                }
+            }
+            if (length == 0 || dst != convSeq[length - 1]) {
+                if (dst != null) {
+                    dstFlg = 1; // need dst profile
+                }
+            }
+
+            ICC_Profile profiles[];
+            int nProfiles = length + srcFlg + dstFlg;
+            if (nProfiles == length) {
+                profiles = convSeq;
+            } else {
+                profiles = new ICC_Profile[nProfiles];
+                int pos = 0;
+                if (srcFlg != 0) {
+                    profiles[pos++] = src;
+                }
+                for (int i = 0; i < length; i++) {
+                    profiles[pos++] = convSeq[i];
+                }
+                if (dstFlg != 0) {
+                    profiles[pos++] = dst;
+                }
+            }
+
+            return transform = new ICC_Transform(profiles);
+        }
+
+        /**
+         * Used only when there are non-ICC color spaces. Returns sequence of
+         * non-ICC color spaces and ICC transforms made from src, dst and
+         * conversionSequence.
+         * 
+         * @param src
+         *            the src.
+         * @param dst
+         *            the dst.
+         * @return the sequence.
+         */
+        public Object[] getSequence(Object src, Object dst) {
+            ArrayList<Object> profiles = new ArrayList<Object>(10);
+            ArrayList<Object> sequence = new ArrayList<Object>(10);
+
+            // We need this profile anyway
+            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+
+            Object conversionFirst = null, conversionLast = null;
+            int conversionLength = conversionSequence.length;
+            if (conversionLength > 0) {
+                conversionFirst = conversionSequence[0];
+                conversionLast = conversionSequence[conversionLength - 1];
+            }
+
+            boolean iccSequenceStarted = false;
+
+            if (src != conversionFirst && src != null) {
+                if (src instanceof ICC_Profile) {
+                    profiles.add(src);
+                    iccSequenceStarted = true;
+                } else {
+                    profiles.add(xyzProfile);
+                    sequence.add(src); // Add non-ICC color space to the
+                    // sequence
+                }
+            } else {
+                profiles.add(xyzProfile);
+            }
+
+            for (int i = 0; i < conversionLength; i++) {
+                if (conversionSequence[i] instanceof ICC_Profile) {
+                    profiles.add(conversionSequence[i]);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+
+                    // Eliminate same profiles if there are any
+                    // (e.g. xyzProfile may occur several times)
+                    Object prev = profiles.get(0);
+                    for (int k = 1; k < profiles.size(); k++) {
+                        if (prev == profiles.get(k)) {
+                            k--;
+                            profiles.remove(k);
+                        }
+                        prev = profiles.get(k);
+                    }
+
+                    // If only one profile left we skip the transform -
+                    // it can be only CIEXYZ
+                    if (profiles.size() > 1) {
+                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+
+                        // Add non-ICC color space to the sequence
+                        sequence.add(conversionSequence[i]);
+                    }
+
+                    profiles.clear();
+                    profiles.add(xyzProfile);
+                    iccSequenceStarted = false; // Sequence of ICC profiles is
+                    // processed
+                } else { // Add non-ICC color space to the sequence
+                    sequence.add(conversionSequence[i]);
+                }
+            }
+
+            if (dst != conversionLast && dst != null) { // Add last profile if
+                // needed
+                if (dst instanceof ICC_Profile) {
+                    profiles.add(dst);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                } else {
+                    sequence.add(dst); // Add last non-ICC color space to the
+                    // sequence
+                }
+            }
+
+            if (iccSequenceStarted) { // Make last transform if needed
+                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+                if (dst != null && !(dst instanceof ICC_Profile)) {
+                    sequence.add(dst); // Add last non-ICC color space to the
+                    // sequence
+                }
+            }
+
+            // Calculate max number of components
+            // This number will be used for memory allocation
+            maxComponents = 0;
+            Object o;
+            for (int i = 0, size = sequence.size(); i < size; i++) {
+                o = sequence.get(i);
+                if (o instanceof ICC_Transform) {
+                    ICC_Transform t = (ICC_Transform)o;
+                    maxComponents = (maxComponents > t.getNumInputChannels() + 1) ? maxComponents
+                            : t.getNumInputChannels() + 1;
+                    maxComponents = (maxComponents > t.getNumOutputChannels() + 1) ? maxComponents
+                            : t.getNumOutputChannels() + 1;
+                } else {
+                    ColorSpace cs = (ColorSpace)o;
+                    maxComponents = (maxComponents > cs.getNumComponents() + 1) ? maxComponents
+                            : cs.getNumComponents() + 1;
+                }
+            }
+
+            return sequence.toArray();
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object using two specified ColorSpace
+     * objects.
+     * 
+     * @param srcCS
+     *            the source ColorSpace.
+     * @param dstCS
+     *            the destination ColorSpace.
+     * @param hints
+     *            the RenderingHints object used for the color conversion, or
+     *            null.
+     */
+    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
+        if (srcCS == null || dstCS == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+
+        boolean srcICC = srcCS instanceof ICC_ColorSpace;
+        boolean dstICC = dstCS instanceof ICC_ColorSpace;
+
+        if (srcICC && dstICC) {
+            conversionSequence = new ICC_Profile[2];
+        } else {
+            conversionSequence = new Object[2];
+            isICC = false;
+        }
+
+        if (srcICC) {
+            conversionSequence[0] = ((ICC_ColorSpace)srcCS).getProfile();
+        } else {
+            conversionSequence[0] = srcCS;
+        }
+
+        if (dstICC) {
+            conversionSequence[1] = ((ICC_ColorSpace)dstCS).getProfile();
+        } else {
+            conversionSequence[1] = dstCS;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object from the specified ICC_Profile
+     * objects.
+     * 
+     * @param profiles
+     *            the array of ICC_Profile objects.
+     * @param hints
+     *            the RenderingHints object used for the color conversion, or
+     *            null.
+     */
+    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
+        if (profiles == null) {
+            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+
+        // This array is not used in the program logic, so don't need to copy it
+        // Store it only to return back
+        midProfiles = profiles;
+
+        conversionSequence = new ICC_Profile[midProfiles.length];
+
+        // Add profiles to the conversion sequence
+        for (int i = 0, length = midProfiles.length; i < length; i++) {
+            conversionSequence[i] = midProfiles[i];
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object using the specified ColorSpace
+     * object.
+     * 
+     * @param cs
+     *            the destination ColorSpace or an intermediate ColorSpace.
+     * @param hints
+     *            the RenderingHints object used for the color conversion, or
+     *            null.
+     */
+    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
+        if (cs == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+
+        if (cs instanceof ICC_ColorSpace) {
+            conversionSequence = new ICC_Profile[1];
+            conversionSequence[0] = ((ICC_ColorSpace)cs).getProfile();
+        } else {
+            conversionSequence = new Object[1];
+            conversionSequence[0] = cs;
+            isICC = false;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object which converts from a source
+     * color space to a destination color space.
+     * 
+     * @param hints
+     *            the RenderingHints object used for the color conversion, or
+     *            null.
+     */
+    public ColorConvertOp(RenderingHints hints) {
+        renderingHints = hints;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (conversionSequence.length < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
+        }
+
+        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
+        int nSrcColorComps, nDstColorComps;
+        Object first = conversionSequence[0];
+        Object last = conversionSequence[conversionSequence.length - 1];
+
+        // Get the number of input/output color components
+        if (isICC) {
+            srcPf = (ICC_Profile)first;
+            dstPf = (ICC_Profile)last;
+            nSrcColorComps = srcPf.getNumComponents();
+            nDstColorComps = dstPf.getNumComponents();
+        } else {
+            if (first instanceof ICC_Profile) {
+                srcPf = (ICC_Profile)first;
+                nSrcColorComps = srcPf.getNumComponents();
+            } else {
+                nSrcColorComps = ((ColorSpace)first).getNumComponents();
+            }
+
+            if (last instanceof ICC_Profile) {
+                dstPf = (ICC_Profile)last;
+                nDstColorComps = dstPf.getNumComponents();
+            } else {
+                nDstColorComps = ((ColorSpace)last).getNumComponents();
+            }
+        }
+
+        // Check that source and destination rasters are compatible with
+        // transforms and with each other
+        if (src.getNumBands() != nSrcColorComps) {
+            // awt.25E=Incorrect number of source raster bands. Should be equal
+            // to the number of color components of source colorspace.
+            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
+        }
+
+        if (dst != null) { // Check destination raster
+            if (dst.getNumBands() != nDstColorComps) {
+                // awt.25F=Incorrect number of destination raster bands. Should
+                // be equal to the number of color components of destination
+                // colorspace.
+                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
+            }
+
+            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
+            }
+
+        } else {
+            dst = createCompatibleDestRaster(src);
+        }
+
+        if (isICC) {
+            // Create transform
+            ICC_Transform t = tCreator
+                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
+            cc.translateColor(t, src, dst);
+        } else {
+            Object[] sequence = tCreator.getSequence(null, null);
+
+            // Get data from the source raster
+            ColorScaler scaler = new ColorScaler();
+            scaler.loadScalingData(src, null);
+            float tmpData[][] = scaler.scaleNormalize(src);
+
+            // Get source and destination color spaces
+            ColorSpace srcCS = (srcPf == null) ? (ColorSpace)first : new ICC_ColorSpace(srcPf);
+            ColorSpace dstCS = (dstPf == null) ? (ColorSpace)last : new ICC_ColorSpace(dstPf);
+
+            applySequence(sequence, tmpData, srcCS, dstCS);
+
+            scaler.loadScalingData(dst, null);
+            scaler.unscaleNormalized(dst, tmpData);
+        }
+
+        return dst;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        // If destination color model is passed only one line needed
+        if (destCM != null) {
+            return new BufferedImage(destCM, destCM.createCompatibleWritableRaster(src.getWidth(),
+                    src.getHeight()), destCM.isAlphaPremultiplied(), null);
+        }
+
+        int nSpaces = conversionSequence.length;
+
+        if (nSpaces < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+
+        // Get destination color space
+        Object destination = conversionSequence[nSpaces - 1];
+        ColorSpace dstCS = (destination instanceof ColorSpace) ? (ColorSpace)destination
+                : new ICC_ColorSpace((ICC_Profile)destination);
+
+        ColorModel srcCM = src.getColorModel();
+        ColorModel dstCM = new ComponentColorModel(dstCS, srcCM.hasAlpha(), srcCM
+                .isAlphaPremultiplied(), srcCM.getTransparency(), srcCM.getTransferType());
+
+        return new BufferedImage(dstCM, destCM.createCompatibleWritableRaster(src.getWidth(), src
+                .getHeight()), destCM.isAlphaPremultiplied(), null);
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (dst == null && conversionSequence.length < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        // First handle index color model
+        if (srcCM instanceof IndexColorModel) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), false);
+        }
+        ColorSpace srcCS = srcCM.getColorSpace();
+
+        BufferedImage res;
+        boolean isDstIndex = false;
+        if (dst != null) {
+
+            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
+            }
+
+            if (dst.getColorModel() instanceof IndexColorModel) {
+                isDstIndex = true;
+                res = createCompatibleDestImage(src, null);
+            } else {
+                res = dst;
+            }
+        } else {
+            res = createCompatibleDestImage(src, null);
+        }
+        ColorModel dstCM = res.getColorModel();
+        ColorSpace dstCS = dstCM.getColorSpace();
+
+        ICC_Profile srcPf = null, dstPf = null;
+        if (srcCS instanceof ICC_ColorSpace) {
+            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
+        }
+        if (dstCS instanceof ICC_ColorSpace) {
+            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
+        }
+
+        boolean isFullICC = isICC && srcPf != null && dstPf != null;
+
+        if (isFullICC) {
+            ICC_Transform t = tCreator
+                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
+            cc.translateColor(t, src, res);
+        } else { // Perform non-ICC transform
+            Object sequence[] = tCreator.getSequence(srcPf == null ? (Object)srcCS : srcPf,
+                    dstPf == null ? (Object)dstCS : dstPf);
+
+            int srcW = src.getWidth();
+            int srcH = src.getHeight();
+            int numPixels = srcW * srcH;
+
+            // Load all pixel data into array tmpData
+            float tmpData[][] = new float[numPixels][tCreator.maxComponents];
+            for (int row = 0, dataPos = 0; row < srcW; row++) {
+                for (int col = 0; col < srcH; col++) {
+                    tmpData[dataPos] = srcCM.getNormalizedComponents(src.getRaster()
+                            .getDataElements(row, col, null), tmpData[dataPos], 0);
+                    dataPos++;
+                }
+            }
+
+            // Copy alpha channel if needed
+            float alpha[] = null;
+            int alphaIdx = srcCM.numComponents - 1;
+            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
+                alpha = new float[numPixels];
+                for (int i = 0; i < numPixels; i++) {
+                    alpha[i] = tmpData[i][alphaIdx];
+                }
+            }
+
+            // Translate colors
+            applySequence(sequence, tmpData, srcCS, dstCS);
+
+            // Copy alpha if needed
+            if (dstCM.hasAlpha()) {
+                alphaIdx = dstCM.numComponents - 1;
+                if (alpha != null) {
+                    for (int i = 0; i < numPixels; i++) {
+                        tmpData[i][alphaIdx] = alpha[i];
+                    }
+                } else {
+                    for (int i = 0; i < numPixels; i++) {
+                        tmpData[i][alphaIdx] = 1f;
+                    }
+                }
+            }
+
+            // Store data back to the image
+            for (int row = 0, dataPos = 0; row < srcW; row++) {
+                for (int col = 0; col < srcH; col++) {
+                    res.getRaster().setDataElements(row, col,
+                            dstCM.getDataElements(tmpData[dataPos++], 0, null));
+                }
+            }
+        }
+
+        if (isDstIndex) { // Convert image into indexed color
+            Graphics2D g2d = dst.createGraphics();
+            g2d.drawImage(res, 0, 0, null);
+            g2d.dispose();
+            return dst;
+        }
+
+        return res;
+    }
+
+    /**
+     * Apply sequence.
+     * 
+     * @param sequence
+     *            the sequence.
+     * @param tmpData
+     *            the tmp data.
+     * @param srcCS
+     *            the src cs.
+     * @param dstCS
+     *            the dst cs.
+     */
+    private void applySequence(Object sequence[], float tmpData[][], ColorSpace srcCS,
+            ColorSpace dstCS) {
+        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+
+        int numPixels = tmpData.length;
+
+        // First transform...
+        if (sequence[0] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[0];
+            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
+        } else { // non ICC
+            for (int k = 0; k < numPixels; k++) {
+                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]);
+            }
+            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
+        }
+
+        for (Object element : sequence) {
+            if (element instanceof ICC_Transform) {
+                ICC_Transform t = (ICC_Transform)element;
+                cc.translateColor(t, tmpData, null, null, numPixels);
+            } else {
+                ColorSpace cs = (ColorSpace)element;
+                for (int k = 0; k < numPixels; k++) {
+                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
+                    tmpData[k] = cs.toCIEXYZ(tmpData[k]);
+                }
+            }
+        }
+
+        // Last transform...
+        if (sequence[sequence.length - 1] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[sequence.length - 1];
+            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
+        } else { // non ICC
+            for (int k = 0; k < numPixels; k++) {
+                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]);
+            }
+        }
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt != null) {
+            dstPt.setLocation(srcPt);
+            return dstPt;
+        }
+        return new Point2D.Float((float)srcPt.getX(), (float)srcPt.getY());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        int nComps = 0;
+        int nSpaces = conversionSequence.length;
+
+        if (nSpaces < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+
+        Object lastCS = conversionSequence[nSpaces - 1];
+        if (lastCS instanceof ColorSpace) {
+            nComps = ((ColorSpace)lastCS).getNumComponents();
+        } else {
+            nComps = ((ICC_Profile)lastCS).getNumComponents();
+        }
+
+        // Calculate correct data type
+        int dstDataType = src.getDataBuffer().getDataType();
+        if (dstDataType != DataBuffer.TYPE_BYTE && dstDataType != DataBuffer.TYPE_SHORT) {
+            dstDataType = DataBuffer.TYPE_SHORT;
+        }
+
+        return Raster.createInterleavedRaster(dstDataType, src.getWidth(), src.getHeight(), nComps,
+                new Point(src.getMinX(), src.getMinY()));
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return src.getRaster().getBounds();
+    }
+
+    /**
+     * Gets an array of ICC_Profiles objects which constructs this
+     * ColorConvertOp object or returns null if this ColorConvertOp is not
+     * constructed from array of ICC_Profiles.
+     * 
+     * @return an array of ICC_Profiles objects which constructs this
+     *         ColorConvertOp object or returns null if this ColorConvertOp is
+     *         not constructed from array of ICC_Profiles.
+     */
+    public final ICC_Profile[] getICC_Profiles() {
+        if (midProfiles != null) {
+            return midProfiles;
+        }
+        return null;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return renderingHints;
+    }
+}
diff --git a/awt/java/awt/image/ColorModel.java b/awt/java/awt/image/ColorModel.java
new file mode 100644
index 0000000..1b084e1
--- /dev/null
+++ b/awt/java/awt/image/ColorModel.java
@@ -0,0 +1,964 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class ColorModel.
+ * 
+ * @since Android 1.0
+ */
+public abstract class ColorModel implements Transparency {
+
+    /**
+     * The pixel_bits.
+     */
+    protected int pixel_bits; // Pixel length in bits
+
+    /**
+     * The transfer type.
+     */
+    protected int transferType;
+
+    /**
+     * The cs.
+     */
+    ColorSpace cs;
+
+    /**
+     * The has alpha.
+     */
+    boolean hasAlpha;
+
+    /**
+     * The is alpha premultiplied.
+     */
+    boolean isAlphaPremultiplied;
+
+    /**
+     * The transparency.
+     */
+    int transparency;
+
+    /**
+     * The num color components.
+     */
+    int numColorComponents;
+
+    /**
+     * The num components.
+     */
+    int numComponents;
+
+    /**
+     * The bits.
+     */
+    int[] bits; // Array of components masks
+
+    /**
+     * The max values.
+     */
+    int[] maxValues = null; // Max values that may be represent by color
+
+    // components
+
+    /**
+     * The max bit length.
+     */
+    int maxBitLength; // Max length color components in bits
+
+    /**
+     * The RG bdefault.
+     */
+    private static ColorModel RGBdefault;
+
+    /**
+     * Instantiates a new color model with the specified values.
+     * 
+     * @param pixel_bits
+     *            the pixel length in bits.
+     * @param bits
+     *            the array of component masks.
+     * @param cspace
+     *            the color space.
+     * @param hasAlpha
+     *            whether the color model has alpha.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied.
+     * @param transparency
+     *            the transparency strategy, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     */
+    protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace, boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+
+        if (pixel_bits < 1) {
+            // awt.26B=The number of bits in the pixel values is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.26B")); //$NON-NLS-1$
+        }
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        int sum = 0;
+        for (int element : bits) {
+            if (element < 0) {
+                // awt.26D=The elements in bits is less than 0
+                throw new IllegalArgumentException(Messages.getString("awt.26D")); //$NON-NLS-1$
+            }
+            sum += element;
+        }
+
+        if (sum < 1) {
+            // awt.26E=The sum of the number of bits in bits is less than 1
+            throw new NullPointerException(Messages.getString("awt.26E")); //$NON-NLS-1$
+        }
+
+        if (cspace == null) {
+            // awt.26F=The cspace is null
+            throw new IllegalArgumentException(Messages.getString("awt.26F")); //$NON-NLS-1$
+        }
+
+        if (transparency < Transparency.OPAQUE || transparency > Transparency.TRANSLUCENT) {
+            // awt.270=The transparency is not a valid value
+            throw new IllegalArgumentException(Messages.getString("awt.270")); //$NON-NLS-1$
+        }
+
+        this.pixel_bits = pixel_bits;
+        this.bits = bits.clone();
+
+        maxValues = new int[bits.length];
+        maxBitLength = 0;
+        for (int i = 0; i < maxValues.length; i++) {
+            maxValues[i] = (1 << bits[i]) - 1;
+            if (bits[i] > maxBitLength) {
+                maxBitLength = bits[i];
+            }
+        }
+
+        cs = cspace;
+        this.hasAlpha = hasAlpha;
+        this.isAlphaPremultiplied = isAlphaPremultiplied;
+        numColorComponents = cs.getNumComponents();
+
+        if (hasAlpha) {
+            numComponents = numColorComponents + 1;
+        } else {
+            numComponents = numColorComponents;
+        }
+
+        this.transparency = transparency;
+        this.transferType = transferType;
+
+    }
+
+    /**
+     * Instantiates a new color model with the specified pixel bit depth. The
+     * transferType is chosen based on the pixel bits, and the other data fields
+     * are given default values.
+     * 
+     * @param bits
+     *            the array of component masks.
+     */
+    public ColorModel(int bits) {
+
+        if (bits < 1) {
+            // awt.271=The number of bits in bits is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.271")); //$NON-NLS-1$
+        }
+
+        pixel_bits = bits;
+        transferType = getTransferType(bits);
+        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        hasAlpha = true;
+        isAlphaPremultiplied = false;
+        transparency = Transparency.TRANSLUCENT;
+
+        numColorComponents = 3;
+        numComponents = 4;
+
+        this.bits = null;
+    }
+
+    /**
+     * Gets the data elements from the specified component array, transforming
+     * them according to rules of the color model.
+     * 
+     * @param components
+     *            the components.
+     * @param offset
+     *            the offset in the normComponents array.
+     * @param obj
+     *            the array that the result is written to: an array of values
+     *            whose length must be the number of components used by the
+     *            color model and whose type depends on the transfer type (based
+     *            on the pixel bit depth), or null to have the appropriate array
+     *            created.
+     * @return the array of data elements.
+     */
+    public Object getDataElements(int[] components, int offset, Object obj) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the data elements from the specified array of normalized components.
+     * 
+     * @param normComponents
+     *            the array normalized components.
+     * @param normOffset
+     *            the offset in the normComponents array.
+     * @param obj
+     *            the array that the result is written to: an array of values
+     *            whose length must be the number of components used by the
+     *            color model and whose type depends on the transfer type (based
+     *            on the pixel bit depth), or null to have the appropriate array
+     *            created.
+     * @return the array of data elements.
+     */
+    public Object getDataElements(float[] normComponents, int normOffset, Object obj) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents, normOffset, null, 0);
+        return getDataElements(unnormComponents, 0, obj);
+    }
+
+    /**
+     * Gets the data elements corresponding to the pixel determined by the RGB
+     * data.
+     * 
+     * @param rgb
+     *            the RGB integer value that defines the pixel.
+     * @param pixel
+     *            the array that the result is written to: an array of values
+     *            whose length must be the number of components used by the
+     *            color model and whose type depends on the transfer type (based
+     *            on the pixel bit depth), or null to have the appropriate array
+     *            created.
+     * @return the array of data elements.
+     */
+    public Object getDataElements(int rgb, Object pixel) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the child raster corresponding to the alpha channel of the specified
+     * writable raster, or null if alpha is not supported.
+     * 
+     * @param raster
+     *            the raster.
+     * @return the alpha raster.
+     */
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        return null;
+    }
+
+    /**
+     * Creates a new color model by coercing the data in the writable raster in
+     * accordance with the alpha strategy of this color model.
+     * 
+     * @param raster
+     *            the raster.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied in this color model
+     * @return the new color model.
+     */
+    public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behavior.
+        // It could be reveled such way:
+        // ColorModel cm = new
+        // ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB,
+        // false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+        // System.out.println(cm.toString());
+        return "ColorModel: Color Space = " + cs.toString() + "; has alpha = " //$NON-NLS-1$ //$NON-NLS-2$
+                + hasAlpha + "; is alpha premultipied = " //$NON-NLS-1$
+                + isAlphaPremultiplied + "; transparency = " + transparency //$NON-NLS-1$
+                + "; number color components = " + numColorComponents //$NON-NLS-1$
+                + "; pixel bits = " + pixel_bits + "; transfer type = " //$NON-NLS-1$ //$NON-NLS-2$
+                + transferType;
+    }
+
+    /**
+     * Gets the components of the pixel determined by the data array.
+     * 
+     * @param pixel
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @param components
+     *            the the array where the resulting components are written (or
+     *            null to prompt the method to create the return array).
+     * @param offset
+     *            the offset that tells where the results should be written in
+     *            the return array.
+     * @return the array of components.
+     */
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the normalized components of the pixel determined by the data array.
+     * 
+     * @param pixel
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @param normComponents
+     *            the array where the resulting normalized components are
+     *            written (or null to prompt the method to create the return
+     *            array).
+     * @param normOffset
+     *            the offset that tells where the results should be written in
+     *            the return array.
+     * @return the array of normalized components.
+     */
+    public float[] getNormalizedComponents(Object pixel, float[] normComponents, int normOffset) {
+
+        if (pixel == null) {
+            // awt.294=pixel is null
+            throw new NullPointerException(Messages.getString("awt.294")); //$NON-NLS-1$
+        }
+
+        int unnormComponents[] = getComponents(pixel, null, 0);
+        return getNormalizedComponents(unnormComponents, 0, normComponents, normOffset);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ColorModel)) {
+            return false;
+        }
+        ColorModel cm = (ColorModel)obj;
+
+        return (pixel_bits == cm.getPixelSize() && transferType == cm.getTransferType()
+                && cs.getType() == cm.getColorSpace().getType() && hasAlpha == cm.hasAlpha()
+                && isAlphaPremultiplied == cm.isAlphaPremultiplied()
+                && transparency == cm.getTransparency()
+                && numColorComponents == cm.getNumColorComponents()
+                && numComponents == cm.getNumComponents() && Arrays.equals(bits, cm
+                .getComponentSize()));
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the data array.
+     * 
+     * @param inData
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @return the red.
+     */
+    public int getRed(Object inData) {
+        return getRed(constructPixel(inData));
+    }
+
+    /**
+     * Gets the RGB integer value corresponding to the pixel defined by the data
+     * array.
+     * 
+     * @param inData
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @return the integer value that gives the pixel's colors in RGB format.
+     */
+    public int getRGB(Object inData) {
+        return (getAlpha(inData) << 24 | getRed(inData) << 16 | getGreen(inData) << 8 | getBlue(inData));
+    }
+
+    /**
+     * Gets the green component of the pixel defined by the data array.
+     * 
+     * @param inData
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @return the green.
+     */
+    public int getGreen(Object inData) {
+        return getGreen(constructPixel(inData));
+    }
+
+    /**
+     * Gets the blue component of the pixel defined by the data array.
+     * 
+     * @param inData
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @return the blue.
+     */
+    public int getBlue(Object inData) {
+        return getBlue(constructPixel(inData));
+    }
+
+    /**
+     * Gets the alpha component of the pixel defined by the data array.
+     * 
+     * @param inData
+     *            the data array that defines the pixel (whose primitive type
+     *            corresponds to the pixel length in bits.
+     * @see ColorModel#getTransferType()
+     * @return the alpha.
+     */
+    public int getAlpha(Object inData) {
+        return getAlpha(constructPixel(inData));
+    }
+
+    /**
+     * Creates a compatible writable raster.
+     * 
+     * @param w
+     *            the width of the desired writable raster.
+     * @param h
+     *            the height of the desired writable raster.
+     * @return the writable raster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the sample model is compatible with this color model.
+     * 
+     * @param sm
+     *            the sample model.
+     * @return true, if the sample model is compatible with this color model.
+     */
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates the compatible sample model.
+     * 
+     * @param w
+     *            the width of the desired sample model.
+     * @param h
+     *            the height of the desired sample model.
+     * @return the sample model.
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the specified raster is compatible with this color model.
+     * 
+     * @param raster
+     *            the raster to inspect.
+     * @return true, if the raster is compatible with this color model.
+     */
+    public boolean isCompatibleRaster(Raster raster) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the color space of this color model.
+     * 
+     * @return the color space.
+     */
+    public final ColorSpace getColorSpace() {
+        return cs;
+    }
+
+    /**
+     * Gets the normalized components corresponding to the specified
+     * unnormalized components.
+     * 
+     * @param components
+     *            the array of unnormalized components.
+     * @param offset
+     *            the offset where the components should be read from the array
+     *            of unnormalized components.
+     * @param normComponents
+     *            the array where the resulting normalized components are
+     *            written (or null to prompt the method to create the return
+     *            array).
+     * @param normOffset
+     *            the offset that tells where the results should be written in
+     *            the return array.
+     * @return the normalized components.
+     */
+    public float[] getNormalizedComponents(int[] components, int offset, float normComponents[],
+            int normOffset) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float normAlpha = (float)components[offset + numColorComponents]
+                    / maxValues[numColorComponents];
+            if (normAlpha != 0.0f) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComponents[normOffset + i] = components[offset + i]
+                            / (normAlpha * maxValues[i]);
+                }
+                normComponents[normOffset + numColorComponents] = normAlpha;
+            } else {
+                for (int i = 0; i < numComponents; i++) {
+                    normComponents[normOffset + i] = 0.0f;
+                }
+            }
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                normComponents[normOffset + i] = (float)components[offset + i] / maxValues[i];
+            }
+        }
+
+        return normComponents;
+    }
+
+    /**
+     * Gets the data element corresponding to the unnormalized components.
+     * 
+     * @param components
+     *            the components.
+     * @param offset
+     *            the offset to start reading the components from the array of
+     *            components.
+     * @return the data element.
+     */
+    public int getDataElement(int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the unnormalized components corresponding to the specified
+     * normalized components.
+     * 
+     * @param normComponents
+     *            the array of normalized components.
+     * @param normOffset
+     *            the offset where the components should be read from the array
+     *            of normalized components.
+     * @param components
+     *            the array where the resulting unnormalized components are
+     *            written (or null to prompt the method to create the return
+     *            array).
+     * @param offset
+     *            the offset that tells where the results should be written in
+     *            the return array.
+     * @return the unnormalized components.
+     */
+    public int[] getUnnormalizedComponents(float normComponents[], int normOffset,
+            int components[], int offset) {
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.273=The length of normComponents minus normOffset is less
+            // than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.273")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        } else {
+            if (components.length - offset < numComponents) {
+                // awt.272=The length of components minus offset is less than
+                // numComponents
+                throw new IllegalArgumentException(Messages.getString("awt.272")); //$NON-NLS-1$
+            }
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                components[offset + i] = (int)(normComponents[normOffset + i] * maxValues[i]
+                        * alpha + 0.5f);
+            }
+            components[offset + numColorComponents] = (int)(normComponents[normOffset
+                    + numColorComponents]
+                    * maxValues[numColorComponents] + 0.5f);
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                components[offset + i] = (int)(normComponents[normOffset + i] * maxValues[i] + 0.5f);
+            }
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the data element corresponding to the normalized components.
+     * 
+     * @param normComponents
+     *            the normalized components.
+     * @param normOffset
+     *            the offset where the normalized components should be read from
+     *            the normalized component array.
+     * @return the data element.
+     */
+    public int getDataElement(float normComponents[], int normOffset) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents, normOffset, null, 0);
+        return getDataElement(unnormComponents, 0);
+    }
+
+    /**
+     * Takes a pixel whose data is defined by an integer, and writes the
+     * corresponding components into the components array, starting from the
+     * index offset.
+     * 
+     * @param pixel
+     *            the pixel data.
+     * @param components
+     *            the data array to write the components to (or null to have the
+     *            method create the return array).
+     * @param offset
+     *            the offset that determines where the results are written in
+     *            the components array.
+     * @return the array of components corresponding to the pixel.
+     */
+    public int[] getComponents(int pixel, int components[], int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the pixel data.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @return the red component of the given pixel.
+     */
+    public abstract int getRed(int pixel);
+
+    /**
+     * Takes the pixel data and returns the integer value corresponding to the
+     * pixel's color in RGB format.
+     * 
+     * @param pixel
+     *            the pixel data.
+     * @return the corresponding RGB integer value.
+     */
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24 | getRed(pixel) << 16 | getGreen(pixel) << 8 | getBlue(pixel));
+    }
+
+    /**
+     * Gets the green component of the pixel determined by the pixel data.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @return the green component of the given pixel.
+     */
+    public abstract int getGreen(int pixel);
+
+    /**
+     * Gets the size of the desired component of this color model.
+     * 
+     * @param componentIdx
+     *            the index that determines which component size to get.
+     * @return the component size corresponding to the index.
+     * @throws NullPointerException
+     *             if this color model doesn't support an array of separate
+     *             components.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the index is negative or greater than or equal to the
+     *             number of components.
+     */
+    public int getComponentSize(int componentIdx) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (componentIdx < 0 || componentIdx >= bits.length) {
+            // awt.274=componentIdx is greater than the number of components or
+            // less than zero
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.274")); //$NON-NLS-1$
+        }
+
+        return bits[componentIdx];
+    }
+
+    /**
+     * Gets the blue component of the pixel determined by the pixel data.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @return the blue component of the given pixel.
+     */
+    public abstract int getBlue(int pixel);
+
+    /**
+     * Gets the alpha component of the pixel determined by the pixel data.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @return the alpha component of the given pixel.
+     */
+    public abstract int getAlpha(int pixel);
+
+    /**
+     * Gets the array of sizes of the different components.
+     * 
+     * @return the array of sizes of the different components.
+     */
+    public int[] getComponentSize() {
+        if (bits != null) {
+            return bits.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the alpha component is pre-multiplied.
+     * 
+     * @return true, if the alpha component is pre-multiplied.
+     */
+    public final boolean isAlphaPremultiplied() {
+        return isAlphaPremultiplied;
+    }
+
+    /**
+     * Checks whether this color model supports alpha.
+     * 
+     * @return true, if this color model has alpha.
+     */
+    public final boolean hasAlpha() {
+        return hasAlpha;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp;
+
+        if (hasAlpha) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+        if (isAlphaPremultiplied) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+
+        tmp = hash >>> 24;
+        hash ^= numColorComponents;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transparency;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= cs.getType();
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= pixel_bits;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transferType;
+        hash <<= 8;
+        hash |= tmp;
+
+        if (bits != null) {
+
+            for (int element : bits) {
+                tmp = hash >>> 24;
+                hash ^= element;
+                hash <<= 8;
+                hash |= tmp;
+            }
+
+        }
+
+        return hash;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive value that
+     * corresponds to the bit length per pixel: either
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @return the transfer type.
+     */
+    public final int getTransferType() {
+        return transferType;
+    }
+
+    /**
+     * Gets the pixel size in bits.
+     * 
+     * @return the pixel size.
+     */
+    public int getPixelSize() {
+        return pixel_bits;
+    }
+
+    /**
+     * Gets the number of components of this color model.
+     * 
+     * @return the number of components.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Gets the number of color components of this color model.
+     * 
+     * @return the number color components.
+     */
+    public int getNumColorComponents() {
+        return numColorComponents;
+    }
+
+    /**
+     * Gets the default RGB color model.
+     * 
+     * @return the default RGB color model.
+     */
+    public static ColorModel getRGBdefault() {
+        if (RGBdefault == null) {
+            RGBdefault = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
+        }
+        return RGBdefault;
+    }
+
+    /*
+     * Construct INT pixel representation from Object
+     * @param obj
+     * @return
+     */
+    /**
+     * Construct pixel.
+     * 
+     * @param obj
+     *            the obj.
+     * @return the int.
+     */
+    private int constructPixel(Object obj) {
+        int pixel = 0;
+
+        switch (getTransferType()) {
+
+            case DataBuffer.TYPE_BYTE:
+                byte[] bPixel = (byte[])obj;
+                if (bPixel.length > 1) {
+                    // awt.275=This pixel representation is not suuported by tis
+                    // Color Model
+                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+                }
+                pixel = bPixel[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short[] sPixel = (short[])obj;
+                if (sPixel.length > 1) {
+                    // awt.275=This pixel representation is not suuported by tis
+                    // Color Model
+                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+                }
+                pixel = sPixel[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int[] iPixel = (int[])obj;
+                if (iPixel.length > 1) {
+                    // awt.275=This pixel representation is not suuported by tis
+                    // Color Model
+                    throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+                }
+                pixel = iPixel[0];
+                break;
+
+            default:
+                // awt.22D=This transferType ( {0} ) is not supported by this
+                // color model
+                throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                        transferType));
+
+        }
+        return pixel;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive value that
+     * corresponds to the bit length per pixel: either
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @return the transfer type.
+     */
+    static int getTransferType(int bits) {
+        if (bits <= 8) {
+            return DataBuffer.TYPE_BYTE;
+        } else if (bits <= 16) {
+            return DataBuffer.TYPE_USHORT;
+        } else if (bits <= 32) {
+            return DataBuffer.TYPE_INT;
+        } else {
+            return DataBuffer.TYPE_UNDEFINED;
+        }
+    }
+
+    @Override
+    public void finalize() {
+        // This method is added for the API compatibility
+        // Don't need to call super since Object's finalize is always empty
+    }
+}
diff --git a/awt/java/awt/image/ComponentColorModel.java b/awt/java/awt/image/ComponentColorModel.java
new file mode 100644
index 0000000..4328fd3
--- /dev/null
+++ b/awt/java/awt/image/ComponentColorModel.java
@@ -0,0 +1,1482 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ComponentColorModel represents a color model that is defined in
+ * terms of its components.
+ * 
+ * @since Android 1.0
+ */
+public class ComponentColorModel extends ColorModel {
+
+    /**
+     * The signed.
+     */
+    private boolean signed; // Pixel samples are signed.
+
+    // Samples with TransferType DataBuffer.TYPE_BYTE,
+    // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT -
+    // unsigned. Samples with others TransferType -
+    // signed.
+
+    /**
+     * The integral.
+     */
+    private boolean integral; // Pixel samples are integral.
+
+    // Samples with TransferType DataBuffer.TYPE_BYTE,
+    // DataBuffer.TYPE_USHORT, DataBuffer.Short and
+    // DataBuffer.TYPE_INT - integral.
+
+    /**
+     * The scale factors.
+     */
+    private float scaleFactors[]; // Array of factors for reduction components
+
+    // values into the form scaled from 0 to 255
+
+    /**
+     * The donot support unnormalized.
+     */
+    private boolean donotSupportUnnormalized; // This Color Model don't support
+
+    // unnormolized form
+
+    /**
+     * The need alpha divide.
+     */
+    private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
+
+    /**
+     * The calc value.
+     */
+    private boolean calcValue; // Value was culculated
+
+    /**
+     * The need scale.
+     */
+    private boolean needScale; // Normalized value need to scale
+
+    /**
+     * The min vals.
+     */
+    private float minVals[]; // Array of Min normalized values
+
+    /**
+     * The ranges.
+     */
+    private float ranges[]; // Array of range normalized values
+
+    /**
+     * The alpha lut.
+     */
+    private byte alphaLUT[]; // Lookup table for scale alpha value
+
+    /**
+     * The color lu ts.
+     */
+    private byte colorLUTs[][]; // Lookup tables for scale color values
+
+    /**
+     * The from_ linea r_ rg b_ lut.
+     */
+    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
+
+    // Linear RGB Color Space into sRGB
+
+    /**
+     * The to_ linea r_8 rg b_ lut.
+     */
+    private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
+
+    // sRGB Color Space into Linear RGB
+    // 8 bit
+
+    /**
+     * The to_ linea r_16 rg b_ lut.
+     */
+    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
+
+    // sRGB Color Space into Linear RGB
+    // 16 bit
+
+    /**
+     * The LINEA r_ rg b_ length.
+     */
+    private int LINEAR_RGB_Length; // Linear RGB bit length
+
+    /**
+     * The factor.
+     */
+    private float fFactor; // Scale factor
+
+    /**
+     * The is_s rgb.
+     */
+    private boolean is_sRGB; // ColorModel has sRGB ColorSpace
+
+    /**
+     * The is_ linea r_ rgb.
+     */
+    private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
+
+    // Space
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace
+     *            the color space.
+     * @param bits
+     *            the array of component masks.
+     * @param hasAlpha
+     *            whether the color model has alpha.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied.
+     * @param transparency
+     *            the transparency strategy, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     */
+    public ComponentColorModel(ColorSpace colorSpace, int bits[], boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+        super(createPixelBits(colorSpace, hasAlpha, transferType), validateBits(bits, colorSpace,
+                hasAlpha, transferType), colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
+                transferType);
+
+        needScale = false;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                signed = false;
+                integral = true;
+                donotSupportUnnormalized = false;
+                scaleFactors = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    scaleFactors[i] = 1.0f / maxValues[i];
+                    if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                        donotSupportUnnormalized = true;
+                    }
+                }
+                if (hasAlpha) {
+                    maxValues[numColorComponents] = (1 << bits[numColorComponents]) - 1;
+                    scaleFactors[numColorComponents] = 1.0f / maxValues[numColorComponents];
+                }
+                break;
+            case DataBuffer.TYPE_SHORT:
+                signed = true;
+                integral = true;
+                donotSupportUnnormalized = true;
+                scaleFactors = new float[numComponents];
+                for (int i = 0; i < numComponents; i++) {
+                    maxValues[i] = Short.MAX_VALUE;
+                    scaleFactors[i] = 1.0f / maxValues[i];
+                    if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                        needScale = true;
+                    }
+                }
+                if (needScale) {
+                    minVals = new float[numColorComponents];
+                    ranges = new float[numColorComponents];
+                    for (int i = 0; i < numColorComponents; i++) {
+                        minVals[i] = cs.getMinValue(i);
+                        ranges[i] = cs.getMaxValue(i) - minVals[i];
+                    }
+                }
+                break;
+            case DataBuffer.TYPE_FLOAT:
+            case DataBuffer.TYPE_DOUBLE:
+                signed = true;
+                integral = false;
+                donotSupportUnnormalized = true;
+                break;
+            default:
+                // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
+                // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+                // DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+                // DataBuffer.TYPE_DOUBLE
+                throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
+        }
+
+        needAlphaDivide = hasAlpha && isAlphaPremultiplied;
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace
+     *            the color space.
+     * @param hasAlpha
+     *            whether the color model has alpha.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied.
+     * @param transparency
+     *            the transparency strategy, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     */
+    public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+
+        this(colorSpace, createPixelBitsArray(colorSpace, hasAlpha, transferType), hasAlpha,
+                isAlphaPremultiplied, transparency, transferType);
+    }
+
+    /**
+     * Validate bits.
+     * 
+     * @param bits
+     *            the bits.
+     * @param colorSpace
+     *            the color space.
+     * @param hasAlpha
+     *            the has alpha.
+     * @param transferType
+     *            the transfer type.
+     * @return the int[].
+     */
+    private static int[] validateBits(int bits[], ColorSpace colorSpace, boolean hasAlpha,
+            int transferType) {
+        if (bits != null) {
+            return bits;
+        }
+
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        bits = new int[numComponents];
+
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+
+        for (int i = 0; i < numComponents; i++) {
+            bits[i] = componentLength;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the pixel bits.
+     * 
+     * @param colorSpace
+     *            the color space.
+     * @param hasAlpha
+     *            the has alpha.
+     * @param transferType
+     *            the transfer type.
+     * @return the int.
+     */
+    private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha, int transferType) {
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+        return numComponents * componentLength;
+    }
+
+    /**
+     * Creates the pixel bits array.
+     * 
+     * @param colorSpace
+     *            the color space.
+     * @param hasAlpha
+     *            the has alpha.
+     * @param transferType
+     *            the transfer type.
+     * @return the int[].
+     */
+    private static int[] createPixelBitsArray(ColorSpace colorSpace, boolean hasAlpha,
+            int transferType) {
+
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+
+        int bits[] = new int[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            bits[i] = DataBuffer.getDataTypeSize(transferType);
+        }
+        return bits;
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (offset + numComponents > components.length) {
+            // awt.216=The components array is not large enough to hold all the
+            // color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[];
+                if (obj == null) {
+                    ba = new byte[numComponents];
+                } else {
+                    ba = (byte[])obj;
+                }
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    ba[i] = (byte)components[idx];
+                }
+                return ba;
+            case DataBuffer.TYPE_USHORT:
+                short sa[];
+                if (obj == null) {
+                    sa = new short[numComponents];
+                } else {
+                    sa = (short[])obj;
+                }
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    sa[i] = (short)components[idx];
+                }
+                return sa;
+            case DataBuffer.TYPE_INT:
+                int ia[];
+                if (obj == null) {
+                    ia = new int[numComponents];
+                } else {
+                    ia = (int[])obj;
+                }
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    ia[i] = components[idx];
+                }
+                return ia;
+            default:
+                // awt.217=The transfer type of this ComponentColorModel is not
+                // one
+                // of the following transfer types: DataBuffer.TYPE_BYTE,
+                // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+                throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(float normComponents[], int normOffset, Object obj) {
+        if (needScale) {
+            for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                normComponents[idx] = (normComponents[idx] - minVals[i]) / ranges[i];
+            }
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[];
+                if (obj == null) {
+                    ba = new byte[numComponents];
+                } else {
+                    ba = (byte[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    float alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
+                        ba[i] = (byte)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
+                    }
+                    ba[numColorComponents] = (byte)(normComponents[normOffset + numColorComponents]
+                            * maxValues[numColorComponents] + 0.5f);
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        ba[idx] = (byte)(normComponents[idx] * maxValues[i] + 0.5f);
+                    }
+                }
+                return ba;
+
+            case DataBuffer.TYPE_USHORT:
+                short usa[];
+                if (obj == null) {
+                    usa = new short[numComponents];
+                } else {
+                    usa = (short[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    float alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                        usa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
+                    }
+                    usa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        usa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
+                    }
+                }
+                return usa;
+
+            case DataBuffer.TYPE_INT:
+                int ia[];
+                if (obj == null) {
+                    ia = new int[numComponents];
+                } else {
+                    ia = (int[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    float alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                        ia[i] = (int)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
+                    }
+                    ia[numColorComponents] = (int)(alpha * maxValues[numColorComponents] + 0.5f);
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        ia[i] = (int)(normComponents[idx] * maxValues[i] + 0.5f);
+                    }
+                }
+                return ia;
+
+            case DataBuffer.TYPE_SHORT:
+                short sa[];
+                if (obj == null) {
+                    sa = new short[numComponents];
+                } else {
+                    sa = (short[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    float alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                        sa[i] = (short)(normComponents[idx] * alpha * maxValues[i] + 0.5f);
+                    }
+                    sa[numColorComponents] = (short)(alpha * maxValues[numColorComponents] + 0.5f);
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        sa[i] = (short)(normComponents[idx] * maxValues[i] + 0.5f);
+                    }
+                }
+                return sa;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fa[];
+                if (obj == null) {
+                    fa = new float[numComponents];
+                } else {
+                    fa = (float[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    float alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                        fa[i] = normComponents[idx] * alpha;
+                    }
+                    fa[numColorComponents] = alpha;
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        fa[i] = normComponents[idx];
+                    }
+                }
+                return fa;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double da[];
+                if (obj == null) {
+                    da = new double[numComponents];
+                } else {
+                    da = (double[])obj;
+                }
+
+                if (needAlphaDivide) {
+                    double alpha = normComponents[normOffset + numColorComponents];
+                    for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                        da[i] = normComponents[idx] * alpha;
+                    }
+                    da[numColorComponents] = alpha;
+                } else {
+                    for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                        da[i] = normComponents[idx];
+                    }
+                }
+                return da;
+
+            default:
+                // awt.213=This ComponentColorModel does not support the
+                // unnormalized form
+                throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        float normComp[];
+        float comp[];
+
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = (rgb >> 24) & 0xff;
+
+        comp = new float[3];
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float[] defComp = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = defComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = defComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+        if (hasAlpha && isAlphaPremultiplied) {
+            normComp[0] *= normComp[numColorComponents];
+            normComp[1] *= normComp[numColorComponents];
+            normComp[2] *= normComp[numColorComponents];
+        }
+
+        return getDataElements(normComp, 0, pixel);
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if (!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int bandList[] = new int[1];
+        bandList[0] = raster.getNumBands() - 1;
+
+        return raster.createWritableChild(x, y, raster.getWidth(), raster.getHeight(), x, y,
+                bandList);
+    }
+
+    @Override
+    public ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+                case DataBuffer.TYPE_BYTE:
+                case DataBuffer.TYPE_USHORT:
+                case DataBuffer.TYPE_INT:
+                    float alphaFactor = maxValues[numColorComponents];
+                    int iComponents[] = null;
+                    int iTransparentComponents[] = new int[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            iComponents = raster.getPixel(x, minY, iComponents);
+                            if (iComponents[numColorComponents] == 0) {
+                                raster.setPixel(x, minY, iTransparentComponents);
+                            } else {
+                                float alpha = iComponents[numColorComponents] / alphaFactor;
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    iComponents[n] = (int)(alpha * iComponents[n] + 0.5f);
+                                }
+                                raster.setPixel(x, minY, iComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_SHORT:
+                    float sAlphaFactor = maxValues[numColorComponents];
+                    short sComponents[] = null;
+                    short sTransparentComponents[] = new short[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            sComponents = (short[])raster.getDataElements(x, minY, sComponents);
+                            if (sComponents[numColorComponents] == 0) {
+                                raster.setDataElements(x, minY, sTransparentComponents);
+                            } else {
+                                float alpha = sComponents[numColorComponents] / sAlphaFactor;
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    sComponents[n] = (byte)(alpha * sComponents[n] + 0.5f);
+                                }
+                                raster.setDataElements(x, minY, sComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_FLOAT:
+                    float fComponents[] = null;
+                    float fTransparentComponents[] = new float[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            fComponents = raster.getPixel(x, minY, fComponents);
+                            if (fComponents[numColorComponents] == 0.0f) {
+                                raster.setDataElements(x, minY, fTransparentComponents);
+                            } else {
+                                float alpha = fComponents[numColorComponents];
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    fComponents[n] = fComponents[n] * alpha;
+                                }
+                                raster.setPixel(x, minY, fComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_DOUBLE:
+                    double dComponents[] = null;
+                    double dTransparentComponents[] = new double[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            dComponents = raster.getPixel(x, minY, dComponents);
+                            if (dComponents[numColorComponents] == 0.0) {
+                                raster.setPixel(x, minY, dTransparentComponents);
+                            } else {
+                                double alpha = dComponents[numColorComponents];
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    dComponents[n] = dComponents[n] * alpha;
+                                }
+                                raster.setPixel(x, minY, dComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                default:
+                    // awt.219=This transferType is not supported by this color
+                    // model
+                    throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+                case DataBuffer.TYPE_BYTE:
+                case DataBuffer.TYPE_USHORT:
+                case DataBuffer.TYPE_INT:
+                    float alphaFactor = maxValues[numColorComponents];
+                    int iComponents[] = null;
+                    int iTransparentComponents[] = new int[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            iComponents = raster.getPixel(x, minY, iComponents);
+                            if (iComponents[numColorComponents] == 0) {
+                                raster.setPixel(x, minY, iTransparentComponents);
+                            } else {
+                                float alpha = iComponents[numColorComponents] / alphaFactor;
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    iComponents[n] = (int)(iComponents[n] / alpha + 0.5f);
+                                }
+                                raster.setPixel(x, minY, iComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_SHORT:
+                    float sAlphaFactor = maxValues[numColorComponents];
+                    short sComponents[] = null;
+                    short sTransparentComponents[] = new short[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            sComponents = (short[])raster.getDataElements(x, minY, sComponents);
+                            if (sComponents[numColorComponents] == 0) {
+                                raster.setDataElements(x, minY, sTransparentComponents);
+                            } else {
+                                float alpha = sComponents[numColorComponents] / sAlphaFactor;
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    sComponents[n] = (byte)(sComponents[n] / alpha + 0.5f);
+                                }
+                                raster.setDataElements(x, minY, sComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_FLOAT:
+                    float fComponents[] = null;
+                    float fTransparentComponents[] = new float[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            fComponents = raster.getPixel(x, minY, fComponents);
+                            if (fComponents[numColorComponents] == 0.0f) {
+                                raster.setDataElements(x, minY, fTransparentComponents);
+                            } else {
+                                float alpha = fComponents[numColorComponents];
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    fComponents[n] = fComponents[n] / alpha;
+                                }
+                                raster.setPixel(x, minY, fComponents);
+                            }
+                        }
+
+                    }
+                    break;
+
+                case DataBuffer.TYPE_DOUBLE:
+                    double dComponents[] = null;
+                    double dTransparentComponents[] = new double[numComponents];
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            dComponents = raster.getPixel(x, minY, dComponents);
+                            if (dComponents[numColorComponents] == 0.0) {
+                                raster.setPixel(x, minY, dTransparentComponents);
+                            } else {
+                                double alpha = dComponents[numColorComponents];
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    dComponents[n] = dComponents[n] / alpha;
+                                }
+                                raster.setPixel(x, minY, dComponents);
+                            }
+                        }
+
+                    }
+                    break;
+                default:
+                    // awt.219=This transferType is not supported by this color
+                    // model
+                    throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        }
+
+        if (!signed) {
+            return new ComponentColorModel(cs, bits, hasAlpha, isAlphaPremultiplied, transparency,
+                    transferType);
+        }
+
+        return new ComponentColorModel(cs, null, hasAlpha, isAlphaPremultiplied, transparency,
+                transferType);
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + numComponents];
+        } else if (offset + numComponents > components.length) {
+            // awt.218=The components array is not large enough to hold all the
+            // color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])pixel;
+
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    components[idx] = ba[i] & 0xff;
+                }
+                return components;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])pixel;
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    components[idx] = sa[i] & 0xffff;
+                }
+                return components;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])pixel;
+                for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                    components[idx] = ia[i];
+                }
+                return components;
+
+            default:
+                // awt.217=The transfer type of this ComponentColorModel is not
+                // one
+                // of the following transfer types: DataBuffer.TYPE_BYTE,
+                // DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+                throw new UnsupportedOperationException(Messages.getString("awt.217")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public float[] getNormalizedComponents(Object pixel, float normComponents[], int normOffset) {
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
+                }
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short usa[] = (short[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = (usa[i] & 0xffff) * scaleFactors[i];
+                }
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = ia[i] * scaleFactors[i];
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                short sa[] = (short[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = sa[i] * scaleFactors[i];
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fa[] = (float[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = fa[i];
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double da[] = (double[])pixel;
+                for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                    normComponents[idx] = (float)da[i];
+                }
+                break;
+
+            default:
+                // awt.21A=This ComponentColorModel does not support this
+                // transferType
+                throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
+        }
+
+        if (needAlphaDivide) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
+                normComponents[idx] /= alpha;
+            }
+        }
+
+        if (needScale) {
+            for (int i = 0, idx = normOffset; i < numColorComponents; i++, idx++) {
+                normComponents[idx] = minVals[i] + ranges[i] * normComponents[idx];
+            }
+        }
+        return normComponents;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ComponentColorModel)) {
+            return false;
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        return getRGBComponent(inData, 0);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int alpha = getAlpha(inData);
+        if (cs.getType() == ColorSpace.TYPE_GRAY) {
+            int gray = getRed(inData);
+            return (alpha << 24 | gray << 16 | gray << 8 | gray);
+        }
+        return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 | getBlue(inData));
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        return getRGBComponent(inData, 1);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        return getRGBComponent(inData, 2);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int alpha = 0;
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE: {
+                byte ba[] = (byte[])inData;
+                alpha = ba[numColorComponents] & 0xff;
+                if (bits[numColorComponents] != 8) {
+                    return alphaLUT[alpha] & 0xff;
+                }
+                return alpha;
+            }
+            case DataBuffer.TYPE_USHORT: {
+                short usa[] = (short[])inData;
+                alpha = usa[numColorComponents] & 0xffff;
+                if (bits[numColorComponents] != 8) {
+                    return alphaLUT[alpha] & 0xff;
+                }
+                return alpha;
+            }
+            case DataBuffer.TYPE_INT: {
+                int ia[] = (int[])inData;
+                alpha = ia[numColorComponents];
+                if (bits[numColorComponents] != 8) {
+                    return alphaLUT[alpha] & 0xff;
+                }
+                return alpha;
+            }
+            case DataBuffer.TYPE_SHORT: {
+                short sa[] = (short[])inData;
+                alpha = sa[numColorComponents];
+                if (bits[numColorComponents] != 8) {
+                    return alphaLUT[alpha] & 0xff;
+                }
+                return alpha;
+            }
+            case DataBuffer.TYPE_FLOAT: {
+                float fa[] = (float[])inData;
+                return (int)(fa[numColorComponents] * 255.0f + 0.5f);
+            }
+            case DataBuffer.TYPE_DOUBLE: {
+                double da[] = (double[])inData;
+                return (int)(da[numColorComponents] * 255.0 + 0.5);
+            }
+            default: {
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        SampleModel sm = createCompatibleSampleModel(w, h);
+        DataBuffer db = sm.createDataBuffer();
+        return Raster.createWritableRaster(sm, db, null);
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+        if (numComponents != sm.getNumBands()) {
+            return false;
+        }
+        if (transferType != sm.getTransferType()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int bandOffsets[] = new int[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            bandOffsets[i] = i;
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+                return new PixelInterleavedSampleModel(transferType, w, h, numComponents, w
+                        * numComponents, bandOffsets);
+
+            default:
+                return new ComponentSampleModel(transferType, w, h, numComponents, w
+                        * numComponents, bandOffsets);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int sampleSizes[] = sm.getSampleSize();
+        for (int i = 0; i < numComponents; i++) {
+            if (bits[i] != sampleSizes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public float[] getNormalizedComponents(int components[], int offset, float normComponents[],
+            int normOffset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        return super.getNormalizedComponents(components, offset, normComponents, normOffset);
+    }
+
+    @Override
+    public int getDataElement(int[] components, int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+        return components[offset];
+    }
+
+    @Override
+    public int[] getUnnormalizedComponents(float[] normComponents, int normOffset,
+            int[] components, int offset) {
+
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.21B=The length of normComponents minus normOffset is less
+            // than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
+        }
+
+        return super.getUnnormalizedComponents(normComponents, normOffset, components, offset);
+    }
+
+    @Override
+    public int getDataElement(float normComponents[], int normOffset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        Object pixel = getDataElements(normComponents, normOffset, null);
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])pixel;
+                return ba[0] & 0xff;
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])pixel;
+                return sa[0] & 0xffff;
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])pixel;
+                return ia[0];
+            default:
+                // awt.211=Pixel values for this ColorModel are not conveniently
+                // representable as a single int
+                throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the
+            // unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + 1];
+        }
+
+        components[offset] = pixel & maxValues[0];
+        return components;
+    }
+
+    @Override
+    public int getRed(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int)(rgb[0] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) | (getGreen(pixel) << 8)
+                | getBlue(pixel);
+    }
+
+    @Override
+    public int getGreen(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int)(rgb[1] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getBlue(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int)(rgb[2] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getAlpha(int pixel) {
+
+        // This method throw IllegalArgumentException according to
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        return 255;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (hasAlpha && bits[numColorComponents] != 8 && integral) {
+            alphaLUT = new byte[maxValues[numColorComponents] + 1];
+            for (int i = 0; i <= maxValues[numColorComponents]; i++) {
+                alphaLUT[i] = (byte)(scaleFactors[numColorComponents] * i + 0.5f);
+            }
+        }
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT = LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT = LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (!isAlphaPremultiplied && integral) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            colorLUTs[i][j] = (byte)(scaleFactors[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int)(scaleFactors[i] * j + 0.5f);
+                            } else {
+                                idx = (int)(scaleFactors[i] * j * 257.0f + 0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * To rgb.
+     * 
+     * @param pixel
+     *            the integer representation of the pixel.
+     * @return the array of normalized sRGB components.
+     */
+    private float[] toRGB(int pixel) {
+
+        // This method throw IllegalArgumentException according to
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        Object obj = null;
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = new byte[1];
+                ba[0] = (byte)pixel;
+                obj = ba;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = new short[1];
+                sa[0] = (short)pixel;
+                obj = sa;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = new int[1];
+                ia[0] = pixel;
+                obj = ia;
+                break;
+
+        }
+
+        return cs.toRGB(getNormalizedComponents(obj, null, 0));
+    }
+
+    /**
+     * Gets the RGB component.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @param idx
+     *            the index of component.
+     * @return the RGB value from 0 to 255 pixel's component.
+     */
+    private int getRGBComponent(Object pixel, int idx) {
+        if (is_sRGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == 8) {
+                return comp;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        } else if (is_LINEAR_RGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == LINEAR_RGB_Length) {
+                return from_LINEAR_RGB_LUT[comp] & 0xff;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        }
+
+        float normComp[] = getNormalizedComponents(pixel, null, 0);
+        float rgbComp[] = cs.toRGB(normComp);
+        return (int)(rgbComp[idx] * 255.0f + 0.5f);
+    }
+
+    /**
+     * Gets the def component.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @param idx
+     *            the index of component.
+     * @return the tentative value of the pixel component.
+     */
+    private int getDefComponent(Object pixel, int idx) {
+        int comp = 0;
+        calcValue = false;
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])pixel;
+                comp = ba[idx] & 0xff;
+                if (needAlphaDivide) {
+                    int alpha = ba[numColorComponents] & 0xff;
+                    if (alpha == 0) {
+                        comp = 0;
+                    } else {
+                        float normAlpha = scaleFactors[numColorComponents] * alpha;
+                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
+                    }
+                    calcValue = true;
+                }
+                return comp;
+
+            case DataBuffer.TYPE_USHORT:
+                short usa[] = (short[])pixel;
+                comp = usa[idx] & 0xffff;
+                if (needAlphaDivide) {
+                    int alpha = usa[numColorComponents] & 0xffff;
+                    if (alpha == 0) {
+                        comp = 0;
+                    } else {
+                        float normAlpha = scaleFactors[numColorComponents] * alpha;
+                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
+                    }
+                    calcValue = true;
+                }
+                return comp;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])pixel;
+                comp = ia[idx];
+                if (needAlphaDivide) {
+                    int alpha = ia[numColorComponents];
+                    if (alpha == 0) {
+                        comp = 0;
+                    } else {
+                        float normAlpha = scaleFactors[numColorComponents] * alpha;
+                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
+                    }
+                    calcValue = true;
+                }
+                return comp;
+
+            case DataBuffer.TYPE_SHORT:
+                short sa[] = (short[])pixel;
+                comp = sa[idx];
+                if (needAlphaDivide) {
+                    int alpha = sa[numColorComponents];
+                    if (alpha == 0) {
+                        comp = 0;
+                    } else {
+                        float normAlpha = scaleFactors[numColorComponents] * alpha;
+                        comp = (int)(comp * fFactor / normAlpha + 0.5f);
+                    }
+                    calcValue = true;
+                }
+                return comp;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fa[] = (float[])pixel;
+                if (needAlphaDivide) {
+                    float alpha = fa[numColorComponents];
+                    if (fa[numColorComponents] == 0.0f) {
+                        comp = 0;
+                    } else {
+                        comp = (int)(fa[idx] * fFactor / alpha + 0.5f);
+                    }
+                } else {
+                    comp = (int)(fa[idx] * fFactor + 0.5f);
+                }
+                calcValue = true;
+                return comp;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double da[] = (double[])pixel;
+                if (needAlphaDivide) {
+                    if (da[numColorComponents] == 0.0) {
+                        comp = 0;
+                    } else {
+                        comp = (int)(da[idx] * fFactor / da[numColorComponents] + 0.5);
+                    }
+                } else {
+                    comp = (int)(da[idx] * fFactor + 0.5);
+                }
+                calcValue = true;
+                return comp;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+}
diff --git a/awt/java/awt/image/ComponentSampleModel.java b/awt/java/awt/image/ComponentSampleModel.java
new file mode 100644
index 0000000..7f81409
--- /dev/null
+++ b/awt/java/awt/image/ComponentSampleModel.java
@@ -0,0 +1,705 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ComponentSampleModel class represents a set of image data whose each
+ * element - the sample of a pixel - takes one data element of the DataBuffer.
+ * <p>
+ * The Bank indices denote the correspondence between the bank of data buffers
+ * and a band of image data. The Pixel stride is the number of data array
+ * elements between two samples for the same band on the same scanline. The
+ * pixel stride for a BandedSampleModel is one. The scanline stride represents
+ * the number of data array elements between a specified sample and the
+ * corresponding sample in the same column in the next scanline. The array of
+ * band offsets gives the starting offsets within each data banks of the in the
+ * DataBuffer. The bank indices represents the indices within each bank of the
+ * DataBuffer corresponding to a band of image data.
+ * 
+ * @since Android 1.0
+ */
+public class ComponentSampleModel extends SampleModel {
+
+    /**
+     * The band offsets array of this ComponentSampleModel.
+     */
+    protected int bandOffsets[];
+
+    /**
+     * The bank indices array of this ComponentSampleModel.
+     */
+    protected int bankIndices[];
+
+    /**
+     * The number of bands in this ComponentSampleModel.
+     */
+    protected int numBands;
+
+    /**
+     * The number banks of this ComponentSampleModel.
+     */
+    protected int numBanks;
+
+    /**
+     * The scanline stride of this ComponentSampleModel.
+     */
+    protected int scanlineStride;
+
+    /**
+     * The pixel stride of this ComponentSampleModel.
+     */
+    protected int pixelStride;
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified properties.
+     * 
+     * @param dataType
+     *            the data type of samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param pixelStride
+     *            the pixel stride of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bankIndices
+     *            the array of the bank indices.
+     * @param bandOffsets
+     *            the array of the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride,
+            int bankIndices[], int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        if (bankIndices.length != bandOffsets.length) {
+            // awt.24D=Bank Indices length must be equal Bank Offsets length
+            throw new IllegalArgumentException(Messages.getString("awt.24D")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.bankIndices = bankIndices.clone();
+        this.numBands = bandOffsets.length;
+
+        int maxBank = 0;
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bankIndices[i] < 0) {
+                // awt.24E=Index of {0} bank must be >= 0
+                throw new IllegalArgumentException(Messages.getString("awt.24E", i)); //$NON-NLS-1$
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+        this.numBanks = maxBank + 1;
+
+    }
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified properties.
+     * 
+     * @param dataType
+     *            the data type of the samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param pixelStride
+     *            the pixel stride of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bandOffsets
+     *            the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride, int scanlineStride,
+            int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.numBands = bandOffsets.length;
+        this.numBanks = 1;
+
+        this.bankIndices = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            bankIndices[i] = 0;
+        }
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                byte bdata[];
+                if (obj == null) {
+                    bdata = new byte[numBands];
+                } else {
+                    bdata = (byte[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    bdata[i] = (byte)getSample(x, y, i, data);
+                }
+
+                obj = bdata;
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                short sdata[];
+                if (obj == null) {
+                    sdata = new short[numBands];
+                } else {
+                    sdata = (short[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    sdata[i] = (short)getSample(x, y, i, data);
+                }
+
+                obj = sdata;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int idata[];
+                if (obj == null) {
+                    idata = new int[numBands];
+                } else {
+                    idata = (int[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    idata[i] = getSample(x, y, i, data);
+                }
+
+                obj = idata;
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fdata[];
+                if (obj == null) {
+                    fdata = new float[numBands];
+                } else {
+                    fdata = (float[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    fdata[i] = getSampleFloat(x, y, i, data);
+                }
+
+                obj = fdata;
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double ddata[];
+                if (obj == null) {
+                    ddata = new double[numBands];
+                } else {
+                    ddata = (double[])obj;
+                }
+
+                for (int i = 0; i < numBands; i++) {
+                    ddata[i] = getSampleDouble(x, y, i, data);
+                }
+
+                obj = ddata;
+                break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                byte barr[] = (byte[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, barr[i] & 0xff, data);
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                short sarr[] = (short[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, sarr[i] & 0xffff, data);
+                }
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int iarr[] = (int[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, iarr[i], data);
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float farr[] = (float[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, farr[i], data);
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double darr[] = (double[])obj;
+                for (int i = 0; i < numBands; i++) {
+                    setSample(x, y, i, darr[i], data);
+                }
+                break;
+        }
+    }
+
+    /**
+     * Compares this ComponentSampleModel with the specified Object.
+     * 
+     * @param o
+     *            the Object.
+     * @return true, if the object is a ComponentSampleModel with identical data
+     *         values to this ComponentSampleModel, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof ComponentSampleModel)) {
+            return false;
+        }
+        ComponentSampleModel model = (ComponentSampleModel)o;
+        return this.width == model.width && this.height == model.height
+                && this.numBands == model.numBands && this.dataType == model.dataType
+                && Arrays.equals(this.bandOffsets, model.bandOffsets)
+                && Arrays.equals(this.bankIndices, model.bankIndices)
+                && this.numBands == model.numBands && this.numBanks == model.numBanks
+                && this.scanlineStride == model.scanlineStride
+                && this.pixelStride == model.pixelStride;
+    }
+
+    /**
+     * @see java.awt.image.SampleModel#createSubsetSampleModel(int[])
+     */
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the
+            // number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new ComponentSampleModel(dataType, width, height, pixelStride, scanlineStride,
+                indices, offsets);
+
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new ComponentSampleModel(dataType, w, h, pixelStride, pixelStride * w, bankIndices,
+                bandOffsets);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride + x * pixelStride
+                + bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride + x * pixelStride
+                + bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x > this.width || x + w > this.width || y > this.height
+                || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[] = null;
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        if (data == null) {
+            // awt.295=data is null
+            throw new NullPointerException(Messages.getString("awt.295")); //$NON-NLS-1$
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data
+                .setElemDouble(bankIndices[b], y * scanlineStride + x * pixelStride
+                        + bandOffsets[b], s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+
+        int maxOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+        }
+        int size = (height - 1) * scanlineStride + (width - 1) * pixelStride + maxOffset + 1;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(size, numBanks);
+                break;
+            case DataBuffer.TYPE_SHORT:
+                data = new DataBufferShort(size, numBanks);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(size, numBanks);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(size, numBanks);
+                break;
+            case DataBuffer.TYPE_FLOAT:
+                data = new DataBufferFloat(size, numBanks);
+                break;
+            case DataBuffer.TYPE_DOUBLE:
+                data = new DataBufferDouble(size, numBanks);
+                break;
+        }
+
+        return data;
+
+    }
+
+    /**
+     * Gets the offset of the specified band of the specified pixel.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the band.
+     * @return the offset of the specified band of the specified pixel.
+     */
+    public int getOffset(int x, int y, int b) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[b];
+    }
+
+    /**
+     * Gets the offset of the first band of the specified pixel.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @return the offset of the first band of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[0];
+    }
+
+    @Override
+    public final int getSampleSize(int band) {
+        return DataBuffer.getDataTypeSize(dataType);
+    }
+
+    @Override
+    public final int[] getSampleSize() {
+        int sampleSizes[] = new int[numBands];
+        int size = DataBuffer.getDataTypeSize(dataType);
+
+        for (int i = 0; i < numBands; i++) {
+            sampleSizes[i] = size;
+        }
+        return sampleSizes;
+    }
+
+    /**
+     * Gets an array of bank indices corresponding to this ComponentSampleModel.
+     * 
+     * @return the array of bank indices.
+     */
+    public final int[] getBankIndices() {
+        return bankIndices.clone();
+    }
+
+    /**
+     * Gets an array of the band offsets corresponding to this
+     * ComponentSampleModel.
+     * 
+     * @return the array of band offsets.
+     */
+    public final int[] getBandOffsets() {
+        return bandOffsets.clone();
+    }
+
+    /**
+     * Gets a hash code of this ComponentSampleModel object.
+     * 
+     * @return a hash code of this ComponentSampleModel object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bandOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bankIndices) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= pixelStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride of this ComponentSampleModel.
+     * 
+     * @return the scanline stride of this ComponentSampleModel.
+     */
+    public final int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel stride.
+     * 
+     * @return the pixel stride.
+     */
+    public final int getPixelStride() {
+        return pixelStride;
+    }
+
+    @Override
+    public final int getNumDataElements() {
+        return numBands;
+    }
+
+}
diff --git a/awt/java/awt/image/ConvolveOp.java b/awt/java/awt/image/ConvolveOp.java
new file mode 100644
index 0000000..6eb8909
--- /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.
+ * 
+ * @since Android 1.0
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp {
+
+    /**
+     * The Constant EDGE_ZERO_FILL indicates that pixels at the edge of the
+     * destination image are set to zero.
+     */
+    public static final int EDGE_ZERO_FILL = 0;
+
+    /**
+     * The Constant EDGE_NO_OP indicates that pixels at the edge of the source
+     * image are converted to the edge pixels in the destination without
+     * modification.
+     */
+    public static final int EDGE_NO_OP = 1;
+
+    /**
+     * The kernel.
+     */
+    private Kernel kernel;
+
+    /**
+     * The edge cond.
+     */
+    private int edgeCond;
+
+    /**
+     * The rhs.
+     */
+    private RenderingHints rhs = null;
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel and
+     * specified edges condition.
+     * 
+     * @param kernel
+     *            the specified Kernel.
+     * @param edgeCondition
+     *            the specified edge condition.
+     * @param hints
+     *            the RenderingHints object, or null.
+     */
+    public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
+        this.kernel = kernel;
+        this.edgeCond = edgeCondition;
+        this.rhs = hints;
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel and
+     * EDGE_ZERO_FILL edge condition.
+     * 
+     * @param kernel
+     *            the specified Kernel.
+     */
+    public ConvolveOp(Kernel kernel) {
+        this.kernel = kernel;
+        this.edgeCond = EDGE_ZERO_FILL;
+    }
+
+    /**
+     * Gets the Kernel object of this ConvolveOp.
+     * 
+     * @return the Kernel object of this ConvolveOp.
+     */
+    public final Kernel getKernel() {
+        return (Kernel)kernel.clone();
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return rhs;
+    }
+
+    /**
+     * Gets the edge condition of this ConvolveOp.
+     * 
+     * @return the edge condition: EDGE_NO_OP or EDGE_ZERO_FILL.
+     */
+    public int getEdgeCondition() {
+        return edgeCond;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == null) { // Should throw according to spec
+            // awt.256=Source raster is null
+            throw new NullPointerException(Messages.getString("awt.256")); //$NON-NLS-1$
+        }
+
+        if (src == dst) {
+            // awt.257=Source raster is equal to destination
+            throw new IllegalArgumentException(Messages.getString("awt.257")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.258=Number of source bands ({0}) is not equal to number of
+            // destination bands ({1})
+            throw new IllegalArgumentException(Messages.getString(
+                    "awt.258", src.getNumBands(), dst.getNumBands())); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+        if (slowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @return the int.
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        try {
+            SampleModel sm = src.getSampleModel();
+
+            int numBands = src.getNumBands();
+            int srcHeight = src.getHeight();
+            int srcWidth = src.getWidth();
+
+            int xOrigin = kernel.getXOrigin();
+            int yOrigin = kernel.getYOrigin();
+            int kWidth = kernel.getWidth();
+            int kHeight = kernel.getHeight();
+            float[] data = kernel.getKernelData(null);
+
+            int srcMinX = src.getMinX();
+            int srcMinY = src.getMinY();
+            int dstMinX = dst.getMinX();
+            int dstMinY = dst.getMinY();
+
+            int srcConvMaxX = srcWidth - (kWidth - xOrigin - 1);
+            int srcConvMaxY = srcHeight - (kHeight - yOrigin - 1);
+
+            int[] maxValues = new int[numBands];
+            int[] masks = new int[numBands];
+            int[] sampleSizes = sm.getSampleSize();
+
+            for (int i = 0; i < numBands; i++) {
+                maxValues[i] = (1 << sampleSizes[i]) - 1;
+                masks[i] = ~(maxValues[i]);
+            }
+
+            // Processing bounds
+            float[] pixels = null;
+            pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+            float[] newPixels = new float[pixels.length];
+            int rowLength = srcWidth * numBands;
+            if (this.edgeCond == ConvolveOp.EDGE_NO_OP) {
+                // top
+                int start = 0;
+                int length = yOrigin * rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // bottom
+                start = (srcHeight - (kHeight - yOrigin - 1)) * rowLength;
+                length = (kHeight - yOrigin - 1) * rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // middle
+                length = xOrigin * numBands;
+                int length1 = (kWidth - xOrigin - 1) * numBands;
+                start = yOrigin * rowLength;
+                int start1 = (yOrigin + 1) * rowLength - length1;
+                for (int i = yOrigin; i < (srcHeight - (kHeight - yOrigin - 1)); i++) {
+                    System.arraycopy(pixels, start, newPixels, start, length);
+                    System.arraycopy(pixels, start1, newPixels, start1, length1);
+                    start += rowLength;
+                    start1 += rowLength;
+                }
+
+            }
+
+            // Cycle over pixels to be calculated
+            for (int i = yOrigin; i < srcConvMaxY; i++) {
+                for (int j = xOrigin; j < srcConvMaxX; j++) {
+
+                    // Take kernel data in backward direction, convolution
+                    int kernelIdx = data.length - 1;
+
+                    int pixelIndex = i * rowLength + j * numBands;
+                    for (int hIdx = 0, rasterHIdx = i - yOrigin; hIdx < kHeight; hIdx++, rasterHIdx++) {
+                        for (int wIdx = 0, rasterWIdx = j - xOrigin; wIdx < kWidth; wIdx++, rasterWIdx++) {
+                            int curIndex = rasterHIdx * rowLength + rasterWIdx * numBands;
+                            for (int idx = 0; idx < numBands; idx++) {
+                                newPixels[pixelIndex + idx] += data[kernelIdx]
+                                        * pixels[curIndex + idx];
+                            }
+                            kernelIdx--;
+                        }
+                    }
+
+                    // Check for overflow now
+                    for (int idx = 0; idx < numBands; idx++) {
+                        if (((int)newPixels[pixelIndex + idx] & masks[idx]) != 0) {
+                            if (newPixels[pixelIndex + idx] < 0) {
+                                newPixels[pixelIndex + idx] = 0;
+                            } else {
+                                newPixels[pixelIndex + idx] = maxValues[idx];
+                            }
+                        }
+                    }
+                }
+            }
+
+            dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, newPixels);
+        } catch (Exception e) { // Something goes wrong, signal error
+            return 1;
+        }
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == null) {
+            // awt.259=Source image is null
+            throw new NullPointerException(Messages.getString("awt.259")); //$NON-NLS-1$
+        }
+
+        if (src == dst) {
+            // awt.25A=Source equals to destination
+            throw new IllegalArgumentException(Messages.getString("awt.25A")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (srcCM instanceof IndexColorModel) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        // TODO
+        // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param imageType
+     *            the image type.
+     * @return the int.
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth() * 3;
+                dstStride = dst.getWidth() * 3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
+                // native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (srcSM instanceof PixelInterleavedSampleModel
+                        && dstSM instanceof PixelInterleavedSampleModel) {
+                    // Check PixelInterleavedSampleModel
+                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
+                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
+                    // 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst);
+                    }
+
+                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
+                } else if (srcSM instanceof SinglePixelPackedSampleModel
+                        && dstSM instanceof SinglePixelPackedSampleModel) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                    // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
+                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
+                            || !(channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
+                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i = 0; i < channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) { // Cannot skip channel, don't know
+                        // which is alpha...
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                            || dst.getSampleModelTranslateX() != 0
+                            || dst.getSampleModelTranslateY() != 0) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippFilter32f(kernel.data, kernel.getWidth(), kernel.getHeight(),
+                kernel.getXOrigin(), kernel.getYOrigin(), edgeCond, srcData, src.getWidth(), src
+                        .getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(),
+                dstStride, channels, skipChannel, offsets);
+    }
+
+    /**
+     * Ipp filter32f.
+     * 
+     * @param kernel
+     *            the kernel.
+     * @param kWidth
+     *            the k width.
+     * @param kHeight
+     *            the k height.
+     * @param anchorX
+     *            the anchor x.
+     * @param anchorY
+     *            the anchor y.
+     * @param borderType
+     *            the border type.
+     * @param src
+     *            the src.
+     * @param srcWidth
+     *            the src width.
+     * @param srcHeight
+     *            the src height.
+     * @param srcStride
+     *            the src stride.
+     * @param dst
+     *            the dst.
+     * @param dstWidth
+     *            the dst width.
+     * @param dstHeight
+     *            the dst height.
+     * @param dstStride
+     *            the dst stride.
+     * @param channels
+     *            the channels.
+     * @param skipChannel
+     *            the skip channel.
+     * @param offsets
+     *            the offsets.
+     * @return the int.
+     */
+    private native int ippFilter32f(float kernel[], int kWidth, int kHeight, int anchorX,
+            int anchorY, int borderType, Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride, int channels,
+            boolean skipChannel, int offsets[]);
+}
diff --git a/awt/java/awt/image/CropImageFilter.java b/awt/java/awt/image/CropImageFilter.java
new file mode 100644
index 0000000..2f4ca78
--- /dev/null
+++ b/awt/java/awt/image/CropImageFilter.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;
+
+import java.util.Hashtable;
+
+/**
+ * The CropImageFilter class crops a rectangular region of an source Image and
+ * provides a source for a new image containing the extracted region.
+ * 
+ * @since Android 1.0
+ */
+public class CropImageFilter extends ImageFilter {
+
+    /**
+     * The HEIGHT.
+     */
+    private final int X, Y, WIDTH, HEIGHT;
+
+    /**
+     * Instantiates a new CropImageFilter object with the specified rectangular
+     * area.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     */
+    public CropImageFilter(int x, int y, int w, int h) {
+        X = x;
+        Y = y;
+        WIDTH = w;
+        HEIGHT = h;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>)props.clone();
+        }
+        String propName = "Crop Filters"; //$NON-NLS-1$
+        String prop = "x=" + X + "; y=" + Y + "; width=" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                WIDTH + "; height=" + HEIGHT; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+
+        if (x + w < X || X + WIDTH < x || y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY, srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if (x <= X) {
+            destX = 0;
+            newOffset += X;
+            if (endX >= srcEndX) {
+                destWidth = srcEndX - X;
+            } else {
+                destWidth = WIDTH;
+            }
+        } else {
+            destX = x - X;
+            if (endX >= srcEndX) {
+                destWidth = w;
+            } else {
+                destWidth = endX - x;
+            }
+        }
+
+        if (y <= Y) {
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if (endY >= srcEndY) {
+                destHeight = srcEndY - Y;
+            } else {
+                destHeight = HEIGHT;
+            }
+        } else {
+            destY = y - Y;
+            if (endY >= srcEndY) {
+                destHeight = h;
+            } else {
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+
+        if (x + w < X || X + WIDTH < x || y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY, srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if (x <= X) {
+            destX = 0;
+            newOffset += X;
+            if (endX >= srcEndX) {
+                destWidth = srcEndX - X;
+            } else {
+                destWidth = WIDTH;
+            }
+        } else {
+            destX = x - X;
+            if (endX >= srcEndX) {
+                destWidth = w;
+            } else {
+                destWidth = endX - x;
+            }
+        }
+
+        if (y <= Y) {
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if (endY >= srcEndY) {
+                destHeight = srcEndY - Y;
+            } else {
+                destHeight = HEIGHT;
+            }
+        } else {
+            destY = y - Y;
+            if (endY >= srcEndY) {
+                destHeight = h;
+            } else {
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        consumer.setDimensions(WIDTH, HEIGHT);
+    }
+
+}
diff --git a/awt/java/awt/image/DataBuffer.java b/awt/java/awt/image/DataBuffer.java
new file mode 100644
index 0000000..92f900f
--- /dev/null
+++ b/awt/java/awt/image/DataBuffer.java
@@ -0,0 +1,481 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBuffer is a wrapper class for a data array to be used for the
+ * situation where a suite of functionality acts on a set of data in a
+ * consistent way even though the primitive type of the data may vary from one
+ * use to the next.
+ * 
+ * @since Android 1.0
+ */
+public abstract class DataBuffer {
+
+    /**
+     * The Constant TYPE_BYTE.
+     */
+    public static final int TYPE_BYTE = 0;
+
+    /**
+     * The Constant TYPE_USHORT.
+     */
+    public static final int TYPE_USHORT = 1;
+
+    /**
+     * The Constant TYPE_SHORT.
+     */
+    public static final int TYPE_SHORT = 2;
+
+    /**
+     * The Constant TYPE_INT.
+     */
+    public static final int TYPE_INT = 3;
+
+    /**
+     * The Constant TYPE_FLOAT.
+     */
+    public static final int TYPE_FLOAT = 4;
+
+    /**
+     * The Constant TYPE_DOUBLE.
+     */
+    public static final int TYPE_DOUBLE = 5;
+
+    /**
+     * The Constant TYPE_UNDEFINED.
+     */
+    public static final int TYPE_UNDEFINED = 32;
+
+    /**
+     * The data type indicates the primitive type of the data in this
+     * DataBuffer.
+     */
+    protected int dataType;
+
+    /**
+     * The number of data arrays in this DataBuffer.
+     */
+    protected int banks;
+
+    /**
+     * The starting index for reading the data from the first (or only) internal
+     * data array.
+     */
+    protected int offset;
+
+    /**
+     * The length (number of elements) of the data arrays.
+     */
+    protected int size;
+
+    /**
+     * The starting indices for reading the data from the internal data arrays.
+     */
+    protected int offsets[];
+
+    /**
+     * The data changed.
+     */
+    boolean dataChanged = true;
+
+    /**
+     * The data taken.
+     */
+    boolean dataTaken = false;
+
+    /**
+     * The listener.
+     */
+    DataBufferListener listener;
+
+    static {
+        AwtImageBackdoorAccessorImpl.init();
+    }
+
+    /**
+     * Instantiates a new data buffer.
+     * 
+     * @param dataType
+     *            the data type.
+     * @param size
+     *            the length (number of elements) of the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offsets = offsets.clone();
+        this.offset = offsets[0];
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the data arrays starting at
+     * the same index.
+     * 
+     * @param dataType
+     *            the data type.
+     * @param size
+     *            the length (number of elements) of the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     * @param offset
+     *            the offset to use for all of the data arrays.
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = offset;
+        this.offsets = new int[numBanks];
+        int i = 0;
+        while (i < numBanks) {
+            offsets[i++] = offset;
+        }
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the data arrays read from the
+     * beginning (at offset zero).
+     * 
+     * @param dataType
+     *            the data type.
+     * @param size
+     *            the length (number of elements) of the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    protected DataBuffer(int dataType, int size, int numBanks) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = 0;
+        this.offsets = new int[numBanks];
+    }
+
+    /**
+     * Instantiates a new data buffer with one internal data array read from the
+     * beginning (at offset zero).
+     * 
+     * @param dataType
+     *            the data type.
+     * @param size
+     *            the length (number of elements) of the data arrays.
+     */
+    protected DataBuffer(int dataType, int size) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = 1;
+        this.offset = 0;
+        this.offsets = new int[1];
+    }
+
+    /**
+     * Sets the data value in the specified array at the specified index.
+     * 
+     * @param bank
+     *            the internal array to the data to.
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public abstract void setElem(int bank, int i, int val);
+
+    /**
+     * Sets the float data value in the specified array at the specified index.
+     * 
+     * @param bank
+     *            the internal array to the data to.
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public void setElemFloat(int bank, int i, float val) {
+        setElem(bank, i, (int)val);
+    }
+
+    /**
+     * Sets the double data value in the specified array at the specified index.
+     * 
+     * @param bank
+     *            the internal array to the data to.
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public void setElemDouble(int bank, int i, double val) {
+        setElem(bank, i, (int)val);
+    }
+
+    /**
+     * Sets the data value in the first array at the specified index.
+     * 
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public void setElem(int i, int val) {
+        setElem(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the specified data array at the specified index.
+     * 
+     * @param bank
+     *            the data array to read from.
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public abstract int getElem(int bank, int i);
+
+    /**
+     * Gets the float-type data value from the specified data array at the
+     * specified index.
+     * 
+     * @param bank
+     *            the data array to read from.
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public float getElemFloat(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Gets the double-type data value from the specified data array at the
+     * specified index.
+     * 
+     * @param bank
+     *            the data array to read from.
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public double getElemDouble(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Sets the float data value in the first array at the specified index.
+     * 
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public void setElemFloat(int i, float val) {
+        setElemFloat(0, i, val);
+    }
+
+    /**
+     * Sets the double data value in the first array at the specified index.
+     * 
+     * @param i
+     *            the index within the array where the data should be written.
+     * @param val
+     *            the value to write into the array.
+     */
+    public void setElemDouble(int i, double val) {
+        setElemDouble(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the first data array at the specified index and
+     * returns it as an integer.
+     * 
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public int getElem(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first data array at the specified index and
+     * returns it as a float.
+     * 
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public float getElemFloat(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first data array at the specified index and
+     * returns it as a double.
+     * 
+     * @param i
+     *            the index within the array where the data should be read.
+     * @return the data element.
+     */
+    public double getElemDouble(int i) {
+        return getElem(i);
+    }
+
+    /**
+     * Gets the array giving the offsets corresponding to the internal data
+     * arrays.
+     * 
+     * @return the array of offsets.
+     */
+    public int[] getOffsets() {
+        return offsets;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @return the size in bits of the primitive data type.
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Gets the offset corresponding to the first internal data array.
+     * 
+     * @return the offset.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of data arrays in this DataBuffer.
+     * 
+     * @return the number of data arrays.
+     */
+    public int getNumBanks() {
+        return banks;
+    }
+
+    /**
+     * Gets the primitive type of this buffer's data.
+     * 
+     * @return the data type.
+     */
+    public int getDataType() {
+        return this.dataType;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @param type
+     *            the primitive type.
+     * @return the size in bits of the primitive data type.
+     */
+    public static int getDataTypeSize(int type) {
+        switch (type) {
+
+            case TYPE_BYTE:
+                return 8;
+
+            case TYPE_USHORT:
+            case TYPE_SHORT:
+                return 16;
+
+            case TYPE_INT:
+            case TYPE_FLOAT:
+                return 32;
+
+            case TYPE_DOUBLE:
+                return 64;
+
+            default:
+                // awt.22C=Unknown data type {0}
+                throw new IllegalArgumentException(Messages.getString("awt.22C", type)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Notifies the listener that the data has changed.
+     */
+    void notifyChanged() {
+        if (listener != null && !dataChanged) {
+            dataChanged = true;
+            listener.dataChanged();
+        }
+    }
+
+    /**
+     * Notifies the listener that the data has been released.
+     */
+    void notifyTaken() {
+        if (listener != null && !dataTaken) {
+            dataTaken = true;
+            listener.dataTaken();
+        }
+    }
+
+    /**
+     * Release the data.
+     */
+    void releaseData() {
+        if (listener != null && dataTaken) {
+            dataTaken = false;
+            listener.dataReleased();
+        }
+    }
+
+    /**
+     * Adds the data buffer listener.
+     * 
+     * @param listener
+     *            the listener.
+     */
+    void addDataBufferListener(DataBufferListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Removes the data buffer listener.
+     */
+    void removeDataBufferListener() {
+        listener = null;
+    }
+
+    /**
+     * Validate.
+     */
+    void validate() {
+        dataChanged = false;
+    }
+
+}
diff --git a/awt/java/awt/image/DataBufferByte.java b/awt/java/awt/image/DataBufferByte.java
new file mode 100644
index 0000000..3407de8
--- /dev/null
+++ b/awt/java/awt/image/DataBufferByte.java
@@ -0,0 +1,183 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The Class DataBufferByte is the subclass of DataBuffer for the case where the
+ * underlying data is of type byte.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferByte extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    byte data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferByte(byte dataArrays[][], int size, int offsets[]) {
+        super(TYPE_BYTE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferByte(byte dataArrays[][], int size) {
+        super(TYPE_BYTE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short with a single
+     * underlying array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferByte(byte dataArray[], int size, int offset) {
+        super(TYPE_BYTE, size, 1, offset);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferByte(byte dataArray[], int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short with offsets
+     * equal to zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferByte(int size, int numBanks) {
+        super(TYPE_BYTE, size, numBanks);
+        data = new byte[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new byte[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = new byte[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (byte)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (byte)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired data array.
+     * @return the data.
+     */
+    public byte[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public byte[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public byte[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+
+}
diff --git a/awt/java/awt/image/DataBufferDouble.java b/awt/java/awt/image/DataBufferDouble.java
new file mode 100644
index 0000000..5d0a516
--- /dev/null
+++ b/awt/java/awt/image/DataBufferDouble.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The Class DataBufferDouble is the subclass of DataBuffer for the case where
+ * the underlying data is of type double.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferDouble extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    double data[][];
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferDouble(double dataArrays[][], int size, int offsets[]) {
+        super(TYPE_DOUBLE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferDouble(double dataArrays[][], int size) {
+        super(TYPE_DOUBLE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double with a single underlying
+     * array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferDouble(double dataArray[], int size, int offset) {
+        super(TYPE_DOUBLE, size, 1, offset);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type double with a single underlying
+     * array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferDouble(double dataArray[], int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double with offsets equal to
+     * zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferDouble(int size, int numBanks) {
+        super(TYPE_DOUBLE, size, numBanks);
+        data = new double[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new double[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = new double[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int)(data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return (float)(data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired data array.
+     * @return the data.
+     */
+    public double[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int)(data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return (float)(data[0][offset + i]);
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public double[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public double[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
diff --git a/awt/java/awt/image/DataBufferFloat.java b/awt/java/awt/image/DataBufferFloat.java
new file mode 100644
index 0000000..9a4a6bf
--- /dev/null
+++ b/awt/java/awt/image/DataBufferFloat.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The Class DataBufferFloat is the subclass of DataBuffer for the case where
+ * the underlying data is float.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferFloat extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    float data[][];
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferFloat(float dataArrays[][], int size, int offsets[]) {
+        super(TYPE_FLOAT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferFloat(float dataArrays[][], int size) {
+        super(TYPE_FLOAT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float with a single underlying
+     * array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferFloat(float dataArray[], int size, int offset) {
+        super(TYPE_FLOAT, size, 1, offset);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type float with a single underlying
+     * array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferFloat(float dataArray[], int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float with offsets equal to
+     * zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferFloat(int size, int numBanks) {
+        super(TYPE_FLOAT, size, numBanks);
+        data = new float[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new float[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = new float[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = (float)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int)(data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = (float)val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired array.
+     * @return the data.
+     */
+    public float[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int)(data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return data[0][offset + i];
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public float[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public float[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
diff --git a/awt/java/awt/image/DataBufferInt.java b/awt/java/awt/image/DataBufferInt.java
new file mode 100644
index 0000000..380a127
--- /dev/null
+++ b/awt/java/awt/image/DataBufferInt.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;
+
+/**
+ * The Class DataBufferInt is the subclass of DataBuffer for the case where the
+ * underlying data is of type integer.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferInt extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    int data[][];
+
+    /**
+     * Instantiates a new data buffer of type integer.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferInt(int dataArrays[][], int size, int offsets[]) {
+        super(TYPE_INT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type integer.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferInt(int dataArrays[][], int size) {
+        super(TYPE_INT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type integer with a single underlying
+     * array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferInt(int dataArray[], int size, int offset) {
+        super(TYPE_INT, size, 1, offset);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type integer with a single underlying
+     * array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferInt(int dataArray[], int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type integer with offsets equal
+     * to zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferInt(int size, int numBanks) {
+        super(TYPE_INT, size, numBanks);
+        data = new int[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new int[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type integer with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = new int[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired data array.
+     * @return the data.
+     */
+    public int[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public int[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public int[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
diff --git a/awt/java/awt/image/DataBufferShort.java b/awt/java/awt/image/DataBufferShort.java
new file mode 100644
index 0000000..1b11b29
--- /dev/null
+++ b/awt/java/awt/image/DataBufferShort.java
@@ -0,0 +1,181 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The Class DataBufferShort is the subclass of DataBuffer for the case where
+ * the underlying data is short.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferShort extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_SHORT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferShort(short dataArrays[][], int size) {
+        super(TYPE_SHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short with a single underlying
+     * array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferShort(short dataArray[], int size, int offset) {
+        super(TYPE_SHORT, size, 1, offset);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short with a single underlying
+     * array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferShort(short dataArray[], int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short with offsets equal to zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferShort(int size, int numBanks) {
+        super(TYPE_SHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type short with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]);
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired data array.
+     * @return the data.
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]);
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
diff --git a/awt/java/awt/image/DataBufferUShort.java b/awt/java/awt/image/DataBufferUShort.java
new file mode 100644
index 0000000..58d9d83
--- /dev/null
+++ b/awt/java/awt/image/DataBufferUShort.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBufferUShort is the subclass of DataBuffer for the case where
+ * the underlying data is unsigned short.
+ * 
+ * @since Android 1.0
+ */
+public final class DataBufferUShort extends DataBuffer {
+
+    /**
+     * The data.
+     */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param offsets
+     *            the starting indices for reading the data from the internal
+     *            data arrays.
+     */
+    public DataBufferUShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_USHORT, size, dataArrays.length, offsets);
+        for (int i = 0; i < dataArrays.length; i++) {
+            if (dataArrays[i].length < offsets[i] + size) {
+                // awt.28d=Length of dataArray[{0}] is less than size +
+                // offset[{1}]
+                throw new IllegalArgumentException(Messages.getString("awt.28D", i, i)); //$NON-NLS-1$
+            }
+        }
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays
+     *            the data arrays to copy the data from.
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     */
+    public DataBufferUShort(short dataArrays[][], int size) {
+        super(TYPE_USHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short with a single
+     * underlying array of data.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     * @param offset
+     *            the starting index to use when reading the data.
+     */
+    public DataBufferUShort(short dataArray[], int size, int offset) {
+        super(TYPE_USHORT, size, 1, offset);
+        if (dataArray.length < size + offset) {
+            // awt.28E=Length of dataArray is less than size + offset
+            throw new IllegalArgumentException(Messages.getString("awt.28E")); //$NON-NLS-1$
+        }
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param dataArray
+     *            the data array to copy the data from.
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferUShort(short dataArray[], int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short with offsets
+     * equal to zero.
+     * 
+     * @param size
+     *            the length (number of elements) to use from the data arrays.
+     * @param numBanks
+     *            the number of data arrays to create.
+     */
+    public DataBufferUShort(int size, int numBanks) {
+        super(TYPE_USHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short with a single
+     * underlying array of data starting at index 0.
+     * 
+     * @param size
+     *            the length (number of elements) to use.
+     */
+    public DataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank
+     *            the index of the desired data array.
+     * @return the data.
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data.
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data.
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
diff --git a/awt/java/awt/image/DirectColorModel.java b/awt/java/awt/image/DirectColorModel.java
new file mode 100644
index 0000000..700eb7a
--- /dev/null
+++ b/awt/java/awt/image/DirectColorModel.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+import java.awt.Transparency;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DirectColorModel represents a standard (packed) RGB color model
+ * with additional support for converting between sRGB color space and 8 or 16
+ * bit linear RGB color space using lookup tables.
+ * 
+ * @since Android 1.0
+ */
+public class DirectColorModel extends PackedColorModel {
+
+    /**
+     * The from_ linea r_ rg b_ lut.
+     */
+    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
+
+    // Linear RGB Color Space into sRGB
+
+    /**
+     * The to_ linea r_8 rg b_ lut.
+     */
+    private byte to_LINEAR_8RGB_LUT[]; // Lookup table for conversion from
+
+    // sRGB Color Space into Linear RGB
+    // 8 bit
+
+    /**
+     * The to_ linea r_16 rg b_ lut.
+     */
+    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
+
+    // sRGB Color Space into Linear RGB
+    // 16 bit
+
+    /**
+     * The alpha lut.
+     */
+    private byte alphaLUT[]; // Lookup table for scale alpha value
+
+    /**
+     * The color lu ts.
+     */
+    private byte colorLUTs[][]; // Lookup tables for scale color values
+
+    /**
+     * The is_s rgb.
+     */
+    private boolean is_sRGB; // ColorModel has sRGB ColorSpace
+
+    /**
+     * The is_ linea r_ rgb.
+     */
+    private boolean is_LINEAR_RGB; // Color Model has Linear RGB Color
+
+    // Space
+
+    /**
+     * The LINEA r_ rg b_ length.
+     */
+    private int LINEAR_RGB_Length; // Linear RGB bit length
+
+    /**
+     * The factor.
+     */
+    private float fFactor; // Scale factor
+
+    /**
+     * Instantiates a new direct color model.
+     * 
+     * @param space
+     *            the color space.
+     * @param bits
+     *            the array of component masks.
+     * @param rmask
+     *            the bitmask corresponding to the red band.
+     * @param gmask
+     *            the bitmask corresponding to the green band.
+     * @param bmask
+     *            the bitmask corresponding to the blue band.
+     * @param amask
+     *            the bitmask corresponding to the alpha band.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied in this color model.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     * @throws IllegalArgumentException
+     *             if the number of bits in the combined bitmasks for the color
+     *             bands is less than one or greater than 32.
+     */
+    public DirectColorModel(ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask,
+            boolean isAlphaPremultiplied, int transferType) {
+
+        super(space, bits, rmask, gmask, bmask, amask, isAlphaPremultiplied,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT), transferType);
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model, determining the transfer type from
+     * the bits array, the transparency from the alpha mask, and the default
+     * color space {@link ColorSpace#CS_sRGB}.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param rmask
+     *            the bitmask corresponding to the red band.
+     * @param gmask
+     *            the bitmask corresponding to the green band.
+     * @param bmask
+     *            the bitmask corresponding to the blue band.
+     * @param amask
+     *            the bitmask corresponding to the alpha band.
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask, int amask) {
+
+        super(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask, bmask, amask, false,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT), ColorModel
+                        .getTransferType(bits));
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model with no alpha channel, determining
+     * the transfer type from the bits array, the default color space
+     * {@link ColorSpace#CS_sRGB}, and with the transparency set to
+     * {@link Transparency#OPAQUE}.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param rmask
+     *            the bitmask corresponding to the red band.
+     * @param gmask
+     *            the bitmask corresponding to the green band.
+     * @param bmask
+     *            the bitmask corresponding to the blue band.
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
+        this(bits, rmask, gmask, bmask, 0);
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[];
+                if (obj == null) {
+                    ba = new byte[1];
+                } else {
+                    ba = (byte[])obj;
+                }
+                ba[0] = (byte)pixel;
+                obj = ba;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[];
+                if (obj == null) {
+                    sa = new short[1];
+                } else {
+                    sa = (short[])obj;
+                }
+                sa[0] = (short)pixel;
+                obj = sa;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[];
+                if (obj == null) {
+                    ia = new int[1];
+                } else {
+                    ia = (int[])obj;
+                }
+                ia[0] = pixel;
+                obj = ia;
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+
+        return obj;
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        if (equals(ColorModel.getRGBdefault())) {
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[])pixel;
+            }
+            ia[0] = rgb;
+            return ia;
+        }
+
+        int alpha = (rgb >> 24) & 0xff;
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+
+        float comp[] = new float[numColorComponents];
+        float normComp[] = null;
+
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float rgbComp[] = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = rgbComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = rgbComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+
+        int pxl = 0;
+        if (hasAlpha) {
+            float normAlpha = normComp[numColorComponents];
+            alpha = (int)(normAlpha * maxValues[numColorComponents] + 0.5f);
+            if (isAlphaPremultiplied) {
+                red = (int)(normComp[0] * normAlpha * maxValues[0] + 0.5f);
+                green = (int)(normComp[1] * normAlpha * maxValues[1] + 0.5f);
+                blue = (int)(normComp[2] * normAlpha * maxValues[2] + 0.5f);
+            } else {
+                red = (int)(normComp[0] * maxValues[0] + 0.5f);
+                green = (int)(normComp[1] * maxValues[1] + 0.5f);
+                blue = (int)(normComp[2] * maxValues[2] + 0.5f);
+            }
+            pxl = (alpha << offsets[3]) & componentMasks[3];
+        } else {
+            red = (int)(normComp[0] * maxValues[0] + 0.5f);
+            green = (int)(normComp[1] * maxValues[1] + 0.5f);
+            blue = (int)(normComp[2] * maxValues[2] + 0.5f);
+        }
+
+        pxl |= ((red << offsets[0]) & componentMasks[0])
+                | ((green << offsets[1]) & componentMasks[1])
+                | ((blue << offsets[2]) & componentMasks[2]);
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[];
+                if (pixel == null) {
+                    ba = new byte[1];
+                } else {
+                    ba = (byte[])pixel;
+                }
+                ba[0] = (byte)pxl;
+                return ba;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[];
+                if (pixel == null) {
+                    sa = new short[1];
+                } else {
+                    sa = (short[])pixel;
+                }
+                sa[0] = (short)pxl;
+                return sa;
+
+            case DataBuffer.TYPE_INT:
+                int ia[];
+                if (pixel == null) {
+                    ia = new int[1];
+                } else {
+                    ia = (int[])pixel;
+                }
+                ia[0] = pxl;
+                return ia;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public final ColorModel coerceData(WritableRaster raster, boolean isAlphaPremultiplied) {
+
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        int components[] = null;
+        int transparentComponents[] = new int[numComponents];
+
+        float alphaFactor = maxValues[numColorComponents];
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+                case DataBuffer.TYPE_BYTE:
+                case DataBuffer.TYPE_USHORT:
+                case DataBuffer.TYPE_INT:
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            components = raster.getPixel(x, minY, components);
+                            if (components[numColorComponents] == 0) {
+                                raster.setPixel(x, minY, transparentComponents);
+                            } else {
+                                float alpha = components[numColorComponents] / alphaFactor;
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    components[n] = (int)(alpha * components[n] + 0.5f);
+                                }
+                                raster.setPixel(x, minY, components);
+                            }
+                        }
+
+                    }
+                    break;
+
+                default:
+                    // awt.214=This Color Model doesn't support this
+                    // transferType
+                    throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+                case DataBuffer.TYPE_BYTE:
+                case DataBuffer.TYPE_USHORT:
+                case DataBuffer.TYPE_INT:
+                    for (int i = 0; i < h; i++, minY++) {
+                        for (int j = 0, x = minX; j < w; j++, x++) {
+                            components = raster.getPixel(x, minY, components);
+                            if (components[numColorComponents] != 0) {
+                                float alpha = alphaFactor / components[numColorComponents];
+                                for (int n = 0; n < numColorComponents; n++) {
+                                    components[n] = (int)(alpha * components[n] + 0.5f);
+                                }
+                                raster.setPixel(x, minY, components);
+                            }
+                        }
+
+                    }
+                    break;
+
+                default:
+                    // awt.214=This Color Model doesn't support this
+                    // transferType
+                    throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+
+        }
+
+        return new DirectColorModel(cs, pixel_bits, componentMasks[0], componentMasks[1],
+                componentMasks[2], componentMasks[3], isAlphaPremultiplied, transferType);
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour.
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1,
+        // BufferedImage.TYPE_INT_ARGB);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
+                Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
+                Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
+                Integer.toHexString(componentMasks[2]) + " amask = " + //$NON-NLS-1$
+                (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public final int[] getComponents(Object pixel, int components[], int offset) {
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+
+        int intPixel = 0;
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])pixel;
+                intPixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])pixel;
+                intPixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])pixel;
+                intPixel = ia[0];
+                break;
+
+            default:
+                // awt.22D=This transferType ( {0} ) is not supported by this
+                // color model
+                throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                        transferType));
+        }
+
+        return getComponents(intPixel, components, offset);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])inData;
+                pixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])inData;
+                pixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])inData;
+                pixel = ia[0];
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRed(pixel);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])inData;
+                pixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])inData;
+                pixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])inData;
+                pixel = ia[0];
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRGB(pixel);
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])inData;
+                pixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])inData;
+                pixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])inData;
+                pixel = ia[0];
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getGreen(pixel);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])inData;
+                pixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])inData;
+                pixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])inData;
+                pixel = ia[0];
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getBlue(pixel);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])inData;
+                pixel = ba[0] & 0xff;
+                break;
+
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])inData;
+                pixel = sa[0] & 0xffff;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ia[] = (int[])inData;
+                pixel = ia[0];
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getAlpha(pixel);
+    }
+
+    @Override
+    public final WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        int bandMasks[] = componentMasks.clone();
+
+        if (pixel_bits > 16) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h, bandMasks, null);
+        } else if (pixel_bits > 8) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w, h, bandMasks, null);
+        } else {
+            return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, bandMasks, null);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel)sm;
+
+        if (sppsm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int maskBands[] = sppsm.getBitMasks();
+        return Arrays.equals(maskBands, componentMasks);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+        return pixel;
+    }
+
+    @Override
+    public final int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+        for (int i = 0; i < numComponents; i++) {
+            components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
+        }
+        return components;
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 0);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 0);
+        }
+        return getComponentFrom_RGB(pixel, 0);
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) | (getGreen(pixel) << 8)
+                | getBlue(pixel);
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 1);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 1);
+        }
+        return getComponentFrom_RGB(pixel, 1);
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 2);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 2);
+        }
+        return getComponentFrom_RGB(pixel, 2);
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int a = (pixel & componentMasks[3]) >>> offsets[3];
+        if (bits[3] == 8) {
+            return a;
+        }
+        return alphaLUT[a] & 0xff;
+    }
+
+    /**
+     * Gets the red mask.
+     * 
+     * @return the red mask.
+     */
+    public final int getRedMask() {
+        return componentMasks[0];
+    }
+
+    /**
+     * Gets the green mask.
+     * 
+     * @return the green mask.
+     */
+    public final int getGreenMask() {
+        return componentMasks[1];
+    }
+
+    /**
+     * Gets the blue mask.
+     * 
+     * @return the blue mask.
+     */
+    public final int getBlueMask() {
+        return componentMasks[2];
+    }
+
+    /**
+     * Gets the alpha mask.
+     * 
+     * @return the alpha mask.
+     */
+    public final int getAlphaMask() {
+        if (hasAlpha) {
+            return componentMasks[3];
+        }
+        return 0;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT = LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT = LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT = LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (hasAlpha && bits[3] != 8) {
+            alphaLUT = new byte[maxValues[3] + 1];
+            for (int i = 0; i <= maxValues[3]; i++) {
+                alphaLUT[i] = (byte)(scales[3] * i + 0.5f);
+            }
+
+        }
+
+        if (!isAlphaPremultiplied) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[i]; j++) {
+                            colorLUTs[i][j] = (byte)(scales[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int)(scales[i] * j + 0.5f);
+                            } else {
+                                idx = (int)(scales[i] * j * 257.0f + 0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * This method return RGB component value if Color Model has sRGB
+     * ColorSpace.
+     * 
+     * @param pixel
+     *            the integer representation of the pixel.
+     * @param idx
+     *            the index of the pixel component.
+     * @return the value of the pixel component scaled from 0 to 255.
+     */
+    private int getComponentFrom_sRGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            int alpha = (pixel & componentMasks[3]) >>> offsets[3];
+            comp = alpha == 0 ? 0 : (int)(scales[idx] * comp * 255.0f / (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != 8) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has Linear RGB
+     * ColorSpace.
+     * 
+     * @param pixel
+     *            the integer representation of the pixel.
+     * @param idx
+     *            the index of the pixel component.
+     * @return the value of the pixel component scaled from 0 to 255.
+     */
+    private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            float factor = ((1 << LINEAR_RGB_Length) - 1);
+            int alpha = (pixel & componentMasks[3]) >> offsets[3];
+            comp = alpha == 0 ? 0 : (int)(scales[idx] * comp * factor / (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != LINEAR_RGB_Length) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        } else {
+            comp = from_LINEAR_RGB_LUT[comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has arbitrary RGB
+     * ColorSapce.
+     * 
+     * @param pixel
+     *            the integer representation of the pixel.
+     * @param idx
+     *            the index of the pixel component.
+     * @return the value of the pixel component scaled from 0 to 255.
+     */
+    private int getComponentFrom_RGB(int pixel, int idx) {
+        int components[] = getComponents(pixel, null, 0);
+        float[] normComponents = getNormalizedComponents(components, 0, null, 0);
+        float[] sRGBcomponents = cs.toRGB(normComponents);
+        return (int)(sRGBcomponents[idx] * 255.0f + 0.5f);
+    }
+
+}
diff --git a/awt/java/awt/image/FilteredImageSource.java b/awt/java/awt/image/FilteredImageSource.java
new file mode 100644
index 0000000..ed8558d
--- /dev/null
+++ b/awt/java/awt/image/FilteredImageSource.java
@@ -0,0 +1,98 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The FilteredImageSource class is used for producing image data for a new
+ * filtered version of the original image using the specified filter object.
+ * 
+ * @since Android 1.0
+ */
+public class FilteredImageSource implements ImageProducer {
+
+    /**
+     * The source.
+     */
+    private final ImageProducer source;
+
+    /**
+     * The filter.
+     */
+    private final ImageFilter filter;
+
+    /**
+     * The cons table.
+     */
+    private final Hashtable<ImageConsumer, ImageConsumer> consTable = new Hashtable<ImageConsumer, ImageConsumer>();
+
+    /**
+     * Instantiates a new FilteredImageSource object with the specified
+     * ImageProducer and the ImageFilter objects.
+     * 
+     * @param orig
+     *            the specified ImageProducer.
+     * @param imgf
+     *            the specified ImageFilter.
+     */
+    public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
+        source = orig;
+        filter = imgf;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        if (ic != null) {
+            return consTable.containsKey(ic);
+        }
+        return false;
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        ImageConsumer fic = consTable.get(ic);
+        source.startProduction(fic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+        if (ic != null && isConsumer(ic)) {
+            ImageFilter fic = (ImageFilter)consTable.get(ic);
+            fic.resendTopDownLeftRight(source);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if (ic != null && isConsumer(ic)) {
+            ImageConsumer fic = consTable.get(ic);
+            source.removeConsumer(fic);
+            consTable.remove(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (ic != null && !isConsumer(ic)) {
+            ImageConsumer fic = filter.getFilterInstance(ic);
+            source.addConsumer(fic);
+            consTable.put(ic, fic);
+        }
+    }
+}
diff --git a/awt/java/awt/image/ImageConsumer.java b/awt/java/awt/image/ImageConsumer.java
new file mode 100644
index 0000000..caf87d1
--- /dev/null
+++ b/awt/java/awt/image/ImageConsumer.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageConsumer interface provides the data about the image and about how
+ * its data is delivered. A ImageProducer provides all of the information about
+ * the image using the methods defined in this interface.
+ * 
+ * @since Android 1.0
+ */
+public interface ImageConsumer {
+
+    /**
+     * The Constant RANDOMPIXELORDER indicates that the pixels are delivered in
+     * a random order.
+     */
+    public static final int RANDOMPIXELORDER = 1;
+
+    /**
+     * The Constant TOPDOWNLEFTRIGHT indicates that the pixels are delivered in
+     * top-down, left-to-right order.
+     */
+    public static final int TOPDOWNLEFTRIGHT = 2;
+
+    /**
+     * The Constant COMPLETESCANLINES indicates that the pixels are delivered in
+     * complete scanline.
+     */
+    public static final int COMPLETESCANLINES = 4;
+
+    /**
+     * The Constant SINGLEPASS indicates that pixels are delivered in a single
+     * pass.
+     */
+    public static final int SINGLEPASS = 8;
+
+    /**
+     * The Constant SINGLEFRAME indicates that image consists of single frame.
+     */
+    public static final int SINGLEFRAME = 16;
+
+    /**
+     * The Constant IMAGEERROR indicates an image error during image producing.
+     */
+    public static final int IMAGEERROR = 1;
+
+    /**
+     * The Constant SINGLEFRAMEDONE indicates that only one of the image's
+     * frames is completed.
+     */
+    public static final int SINGLEFRAMEDONE = 2;
+
+    /**
+     * The Constant STATICIMAGEDONE indicates that the image is completed.
+     */
+    public static final int STATICIMAGEDONE = 3;
+
+    /**
+     * The Constant IMAGEABORTED indicates that the image producing process is
+     * aborted.
+     */
+    public static final int IMAGEABORTED = 4;
+
+    /**
+     * Sets the properties for the image associated with this ImageConsumer.
+     * 
+     * @param props
+     *            the properties for the image associated with this
+     *            ImageConsumer.
+     */
+    public void setProperties(Hashtable<?, ?> props);
+
+    /**
+     * Sets the ColorModel object.
+     * 
+     * @param model
+     *            the new ColorModel.
+     */
+    public void setColorModel(ColorModel model);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     * @param model
+     *            the specified ColorModel to be used for pixels converting.
+     * @param pixels
+     *            the array of pixels.
+     * @param off
+     *            the offset of pixels array.
+     * @param scansize
+     *            the distance from the one row of pixels to the next row in the
+     *            specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     * @param model
+     *            the specified ColorModel to be used for pixels converting.
+     * @param pixels
+     *            the array of pixels.
+     * @param off
+     *            the offset of pixels array.
+     * @param scansize
+     *            the distance from the one row of pixels to the next row in the
+     *            specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize);
+
+    /**
+     * Sets the dimensions of a source image.
+     * 
+     * @param width
+     *            the width of the image.
+     * @param height
+     *            the height of the image.
+     */
+    public void setDimensions(int width, int height);
+
+    /**
+     * Sets the hint flags of pixels order, which is used by the ImageConsumer
+     * for obtaining pixels from the ImageProducer for which this ImageConsumer
+     * is added.
+     * 
+     * @param hintflags
+     *            the mask of hint flags.
+     */
+    public void setHints(int hintflags);
+
+    /**
+     * THis method is called in the one of the following cases:
+     * <ul>
+     * <li>The ImageProducer (for which this ImageConsumer is added) has been
+     * delivered all pixels of the source image.</li>
+     * <li>A one frame of an animation has been completed.</li>
+     * <li>An error while loading or producing of the image has occurred.
+     * </ul>
+     * 
+     * @param status
+     *            the status of image producing.
+     */
+    public void imageComplete(int status);
+
+}
diff --git a/awt/java/awt/image/ImageFilter.java b/awt/java/awt/image/ImageFilter.java
new file mode 100644
index 0000000..d2c9f50
--- /dev/null
+++ b/awt/java/awt/image/ImageFilter.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageFilter class provides a filter for delivering image data from an
+ * ImageProducer to an ImageConsumer.
+ * 
+ * @since Android 1.0
+ */
+public class ImageFilter implements ImageConsumer, Cloneable {
+
+    /**
+     * The consumer.
+     */
+    protected ImageConsumer consumer;
+
+    /**
+     * Instantiates a new ImageFilter.
+     */
+    public ImageFilter() {
+        super();
+    }
+
+    /**
+     * Gets an instance of an ImageFilter object which performs the filtering
+     * for the specified ImageConsumer.
+     * 
+     * @param ic
+     *            the specified ImageConsumer.
+     * @return an ImageFilter used to perform the filtering for the specified
+     *         ImageConsumer.
+     */
+    public ImageFilter getFilterInstance(ImageConsumer ic) {
+        ImageFilter filter = (ImageFilter)clone();
+        filter.consumer = ic;
+        return filter;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>)props.clone();
+        }
+        String propName = "Filters"; //$NON-NLS-1$
+        String prop = "Null filter"; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    /**
+     * Returns a copy of this ImageFilter.
+     * 
+     * @return a copy of this ImageFilter.
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Responds to a request for a Top-Down-Left-Right ordered resend of the
+     * pixel data from an ImageConsumer.
+     * 
+     * @param ip
+     *            the ImageProducer that provides this instance of the filter.
+     */
+    public void resendTopDownLeftRight(ImageProducer ip) {
+        ip.requestTopDownLeftRightResend(this);
+    }
+
+    public void setColorModel(ColorModel model) {
+        consumer.setColorModel(model);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setDimensions(int width, int height) {
+        consumer.setDimensions(width, height);
+    }
+
+    public void setHints(int hints) {
+        consumer.setHints(hints);
+    }
+
+    public void imageComplete(int status) {
+        consumer.imageComplete(status);
+    }
+
+}
diff --git a/awt/java/awt/image/ImageObserver.java b/awt/java/awt/image/ImageObserver.java
new file mode 100644
index 0000000..21ec41b
--- /dev/null
+++ b/awt/java/awt/image/ImageObserver.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.Image;
+
+/**
+ * the ImageObserver interface is an asynchronous update interface for receiving
+ * notifications about Image construction status.
+ * 
+ * @since Android 1.0
+ */
+public interface ImageObserver {
+
+    /**
+     * The Constant WIDTH indicates that the width of the image is available.
+     */
+    public static final int WIDTH = 1;
+
+    /**
+     * The Constant HEIGHT indicates that the width of the image is available.
+     */
+    public static final int HEIGHT = 2;
+
+    /**
+     * The Constant PROPERTIES indicates that the properties of the image are
+     * available.
+     */
+    public static final int PROPERTIES = 4;
+
+    /**
+     * The Constant SOMEBITS indicates that more bits needed for drawing a
+     * scaled variation of the image pixels are available.
+     */
+    public static final int SOMEBITS = 8;
+
+    /**
+     * The Constant FRAMEBITS indicates that complete frame of a image which was
+     * previously drawn is now available for drawing again.
+     */
+    public static final int FRAMEBITS = 16;
+
+    /**
+     * The Constant ALLBITS indicates that an image which was previously drawn
+     * is now complete and can be drawn again.
+     */
+    public static final int ALLBITS = 32;
+
+    /**
+     * The Constant ERROR indicates that error occurred.
+     */
+    public static final int ERROR = 64;
+
+    /**
+     * The Constant ABORT indicates that the image producing is aborted.
+     */
+    public static final int ABORT = 128;
+
+    /**
+     * This method is called when information about an Image interface becomes
+     * available. This method returns true if further updates are needed, false
+     * if not.
+     * 
+     * @param img
+     *            the image to be observed.
+     * @param infoflags
+     *            the bitwise OR combination of information flags: ABORT,
+     *            ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS,
+     *            WIDTH.
+     * @param x
+     *            the X coordinate.
+     * @param y
+     *            the Y coordinate.
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     * @return true if further updates are needed, false if not.
+     */
+    public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height);
+
+}
diff --git a/awt/java/awt/image/ImageProducer.java b/awt/java/awt/image/ImageProducer.java
new file mode 100644
index 0000000..9138be2
--- /dev/null
+++ b/awt/java/awt/image/ImageProducer.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The ImageProducer provides an interface for objects which produce the image
+ * data. ImageProducer is used for reconstructing the image. Each image contains
+ * an ImageProducer.
+ * 
+ * @since Android 1.0
+ */
+public interface ImageProducer {
+
+    /**
+     * Checks if the specified ImageConsumer is registered with this
+     * ImageProvider or not.
+     * 
+     * @param ic
+     *            the ImageConsumer to be checked.
+     * @return true, if the specified ImageConsumer is registered with this
+     *         ImageProvider, false otherwise.
+     */
+    public boolean isConsumer(ImageConsumer ic);
+
+    /**
+     * Starts a reconstruction of the image data which will be delivered to this
+     * consumer. This method adds the specified ImageConsumer before
+     * reconstructing the image.
+     * 
+     * @param ic
+     *            the specified ImageConsumer.
+     */
+    public void startProduction(ImageConsumer ic);
+
+    /**
+     * Requests the ImageProducer to resend the image data in
+     * ImageConsumer.TOPDOWNLEFTRIGHT order.
+     * 
+     * @param ic
+     *            the specified ImageConsumer.
+     */
+    public void requestTopDownLeftRightResend(ImageConsumer ic);
+
+    /**
+     * Deregisters the specified ImageConsumer.
+     * 
+     * @param ic
+     *            the specified ImageConsumer.
+     */
+    public void removeConsumer(ImageConsumer ic);
+
+    /**
+     * Adds the specified ImageConsumer object to this ImageProducer.
+     * 
+     * @param ic
+     *            the specified ImageConsumer.
+     */
+    public void addConsumer(ImageConsumer ic);
+
+}
diff --git a/awt/java/awt/image/ImagingOpException.java b/awt/java/awt/image/ImagingOpException.java
new file mode 100644
index 0000000..e0c0127
--- /dev/null
+++ b/awt/java/awt/image/ImagingOpException.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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 5, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ImagingOpException class provides error notification when the
+ * BufferedImageOp or RasterOp filter methods can not perform the desired filter
+ * operation.
+ * 
+ * @since Android 1.0
+ */
+public class ImagingOpException extends RuntimeException {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 8026288481846276658L;
+
+    /**
+     * Instantiates a new ImagingOpException with a detail message.
+     * 
+     * @param s
+     *            the detail message.
+     */
+    public ImagingOpException(String s) {
+        super(s);
+    }
+}
diff --git a/awt/java/awt/image/IndexColorModel.java b/awt/java/awt/image/IndexColorModel.java
new file mode 100644
index 0000000..0b06acd
--- /dev/null
+++ b/awt/java/awt/image/IndexColorModel.java
@@ -0,0 +1,1080 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class IndexColorModel represents a color model in which the color values
+ * of the pixels are read from a palette.
+ * 
+ * @since Android 1.0
+ */
+public class IndexColorModel extends ColorModel {
+
+    /**
+     * The color map.
+     */
+    private int colorMap[]; // Color Map
+
+    /**
+     * The map size.
+     */
+    private int mapSize; // Color Map size
+
+    /**
+     * The transparent index.
+     */
+    private int transparentIndex; // Index of fully transparent pixel
+
+    /**
+     * The gray palette.
+     */
+    private boolean grayPalette; // Color Model has Color Map with Gray Pallete
+
+    /**
+     * The valid bits.
+     */
+    private BigInteger validBits; // Specify valid Color Map values
+
+    /**
+     * The Constant CACHESIZE.
+     */
+    private static final int CACHESIZE = 20; // Cache size. Cache used for
+
+    // improving performace of selection
+    // nearest color in Color Map
+
+    /**
+     * The cachetable.
+     */
+    private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table -
+
+    // used for
+
+    // storing RGB values and that appropriate indices
+    // in the Color Map
+
+    /**
+     * The next insert idx.
+     */
+    private int nextInsertIdx = 0; // Next index for insertion into Cache table
+
+    /**
+     * The total inserted.
+     */
+    private int totalInserted = 0; // Number of inserted values into Cache table
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param cmap
+     *            the array that gives the color mapping.
+     * @param start
+     *            the start index of the color mapping data within the cmap
+     *            array.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     * @param validBits
+     *            a list of which bits represent valid colormap values, or null
+     *            if all are valid.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start, int transferType,
+            BigInteger validBits) {
+
+        super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                true, false, Transparency.OPAQUE, validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        if (validBits != null) {
+            for (int i = 0; i < mapSize; i++) {
+                if (!validBits.testBit(i)) {
+                    this.validBits = validBits;
+                }
+                break;
+            }
+        }
+
+        transparency = Transparency.OPAQUE;
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            colorMap[i] = cmap[start];
+            alpha = cmap[start] & alphaMask;
+
+            if (alpha == alphaMask) {
+                continue;
+            }
+            if (alpha == 0) {
+                if (transparentIndex < 0) {
+                    transparentIndex = i;
+                }
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+            } else if (alpha != alphaMask && transparency != Transparency.TRANSLUCENT) {
+                transparency = Transparency.TRANSLUCENT;
+            }
+
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param cmap
+     *            the array that gives the color mapping.
+     * @param start
+     *            the start index of the color mapping data within the cmap
+     *            array.
+     * @param hasalpha
+     *            whether this color model uses alpha.
+     * @param trans
+     *            the transparency supported, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start, boolean hasalpha, int trans,
+            int transferType) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
+                .getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
+                Transparency.OPAQUE, validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+            transparency = Transparency.BITMASK;
+        } else {
+            transparentIndex = -1;
+            transparency = Transparency.OPAQUE;
+        }
+
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            if (transparentIndex == i) {
+                colorMap[i] = cmap[start] & 0x00ffffff;
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start] & alphaMask;
+                colorMap[i] = cmap[start];
+
+                if (alpha == alphaMask) {
+                    continue;
+                }
+                if (alpha == 0) {
+                    if (trans < 0) {
+                        trans = i;
+                    }
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                } else if (alpha != 0 && transparency != Transparency.TRANSLUCENT) {
+                    transparency = Transparency.TRANSLUCENT;
+                }
+            } else {
+                colorMap[i] = alphaMask | cmap[start];
+            }
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map from
+     * arrays of red, green, blue, and alpha values.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param r
+     *            the array giving the red components of the entries in the
+     *            color map.
+     * @param g
+     *            the array giving the green components of the entries in the
+     *            color map.
+     * @param b
+     *            the array giving the blue components of the entries in the
+     *            color map.
+     * @param a
+     *            the array giving the alpha components of the entries in the
+     *            color map.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of one of the component arrays is less than the
+     *             size of the color map.
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], byte a[]) {
+
+        super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                true, false, Transparency.OPAQUE, validateTransferType(ColorModel
+                        .getTransferType(bits)));
+
+        createColorMap(size, r, g, b, a, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map from
+     * arrays of red, green, and blue values.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param r
+     *            the array giving the red components of the entries in the
+     *            color map.
+     * @param g
+     *            the array giving the green components of the entries in the
+     *            color map.
+     * @param b
+     *            the array giving the blue components of the entries in the
+     *            color map.
+     * @param trans
+     *            the transparency supported, @see java.awt.Transparency.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of one of the component arrays is less than the
+     *             size of the color map.
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], int trans) {
+
+        super(bits, IndexColorModel.createBits((trans >= 0)), ColorSpace
+                .getInstance(ColorSpace.CS_sRGB), (trans >= 0), false, Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, trans);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map from
+     * arrays of red, green, and blue values.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param r
+     *            the array giving the red components of the entries in the
+     *            color map.
+     * @param g
+     *            the array giving the green components of the entries in the
+     *            color map.
+     * @param b
+     *            the array giving the blue components of the entries in the
+     *            color map.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     * @throws ArrayIndexOutOfBoundsException
+     *             if the size of one of the component arrays is less than the
+     *             size of the color map.
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
+        super(bits, IndexColorModel.createBits(false), ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                false, false, Transparency.OPAQUE, validateTransferType(ColorModel
+                        .getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param cmap
+     *            the array that gives the color mapping.
+     * @param start
+     *            the start index of the color mapping data within the cmap
+     *            array.
+     * @param hasalpha
+     *            whether this color model uses alpha.
+     * @param trans
+     *            the transparency supported, @see java.awt.Transparency.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha, int trans) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
+                .getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
+                Transparency.OPAQUE, validateTransferType(ColorModel.getTransferType(bits)));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        transparency = Transparency.OPAQUE;
+        int alpha = 0xff000000;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = (cmap[start++] & 0xff) << 16 | (cmap[start++] & 0xff) << 8
+                    | (cmap[start++] & 0xff);
+            if (trans == i) {
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+                if (hasalpha) {
+                    start++;
+                }
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start++] & 0xff;
+                if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                        if (trans < 0) {
+                            trans = i;
+                        }
+                    }
+                } else {
+                    if (alpha != 0xff && transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+                alpha <<= 24;
+            }
+            colorMap[i] |= alpha;
+        }
+
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits
+     *            the array of component masks.
+     * @param size
+     *            the size of the color map.
+     * @param cmap
+     *            the array that gives the color mapping.
+     * @param start
+     *            the start index of the color mapping data within the cmap
+     *            array.
+     * @param hasalpha
+     *            whether this color model uses alpha.
+     * @throws IllegalArgumentException
+     *             if the size of the color map is less than one.
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha) {
+
+        this(bits, size, cmap, start, hasalpha, -1);
+    }
+
+    @Override
+    public Object getDataElements(int[] components, int offset, Object pixel) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
+                | components[offset + 2];
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+        return getDataElements(rgb, pixel);
+    }
+
+    @Override
+    public synchronized Object getDataElements(int rgb, Object pixel) {
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = rgb >>> 24;
+        int pixIdx = 0;
+
+        for (int i = 0; i < totalInserted; i++) {
+            int idx = i * 2;
+            if (rgb == cachetable[idx]) {
+                return createDataObject(cachetable[idx + 1], pixel);
+            }
+        }
+
+        if (!hasAlpha && grayPalette) {
+            int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
+            int minError = 255;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                error = Math.abs((colorMap[i] & 0xff) - grey);
+                if (error < minError) {
+                    pixIdx = i;
+                    if (error == 0) {
+                        break;
+                    }
+                    minError = error;
+                }
+            }
+        } else if (alpha == 0 && transparentIndex > -1) {
+            pixIdx = transparentIndex;
+        } else {
+            int minAlphaError = 255;
+            int minError = 195075; // 255^2 + 255^2 + 255^2
+            int alphaError;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                int pix = colorMap[i];
+                if (rgb == pix) {
+                    pixIdx = i;
+                    break;
+                }
+                alphaError = Math.abs(alpha - (pix >>> 24));
+                if (alphaError <= minAlphaError) {
+                    minAlphaError = alphaError;
+
+                    int buf = ((pix >> 16) & 0xff) - red;
+                    error = buf * buf;
+
+                    if (error < minError) {
+                        buf = ((pix >> 8) & 0xff) - green;
+                        error += buf * buf;
+
+                        if (error < minError) {
+                            buf = (pix & 0xff) - blue;
+                            error += buf * buf;
+
+                            if (error < minError) {
+                                pixIdx = i;
+                                minError = error;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        cachetable[nextInsertIdx] = rgb;
+        cachetable[nextInsertIdx + 1] = pixIdx;
+
+        nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
+        if (totalInserted < CACHESIZE) {
+            totalInserted++;
+        }
+
+        return createDataObject(pixIdx, pixel);
+    }
+
+    /**
+     * Converts an image from indexed to RGB format.
+     * 
+     * @param raster
+     *            the raster containing the source image.
+     * @param forceARGB
+     *            whether to use the default RGB color model.
+     * @return the buffered image.
+     * @throws IllegalArgumentException
+     *             if the raster is not compatible with this color model.
+     */
+    public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB) {
+
+        if (!isCompatibleRaster(raster)) {
+            // awt.265=The raster argument is not compatible with this
+            // IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
+        }
+
+        ColorModel model;
+        if (forceARGB || transparency == Transparency.TRANSLUCENT) {
+            model = ColorModel.getRGBdefault();
+        } else if (transparency == Transparency.BITMASK) {
+            model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x01000000);
+        } else {
+            model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
+        }
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        Object obj = null;
+        int pixels[] = null;
+
+        for (int i = 0; i < h; i++, minY++) {
+            obj = raster.getDataElements(minX, minY, w, 1, obj);
+            if (obj instanceof byte[]) {
+                byte ba[] = (byte[])obj;
+                if (pixels == null) {
+                    pixels = new int[ba.length];
+                }
+                for (int j = 0; j < ba.length; j++) {
+                    pixels[j] = colorMap[ba[j] & 0xff];
+                }
+            } else if (obj instanceof short[]) {
+                short sa[] = (short[])obj;
+                if (pixels == null) {
+                    pixels = new int[sa.length];
+                }
+                for (int j = 0; j < sa.length; j++) {
+                    pixels[j] = colorMap[sa[j] & 0xffff];
+                }
+            }
+            if (obj instanceof int[]) {
+                int ia[] = (int[])obj;
+                if (pixels == null) {
+                    pixels = new int[ia.length];
+                }
+                for (int j = 0; j < ia.length; j++) {
+                    pixels[j] = colorMap[ia[j]];
+                }
+            }
+
+            distRaster.setDataElements(0, i, w, 1, pixels);
+        }
+
+        return new BufferedImage(model, distRaster, false, null);
+    }
+
+    /**
+     * Gets the valid pixels.
+     * 
+     * @return the valid pixels.
+     */
+    public BigInteger getValidPixels() {
+        return validBits;
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour.
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1,
+        // BufferedImage.TYPE_BYTE_INDEXED);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
+                " numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
+                " transparency = "; //$NON-NLS-1$
+
+        if (transparency == Transparency.OPAQUE) {
+            str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
+        } else if (transparency == Transparency.BITMASK) {
+            str = str + "Transparency.BITMASK"; //$NON-NLS-1$
+        } else {
+            str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
+        }
+
+        str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
+                hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int components[], int offset) {
+        int pixIdx = -1;
+        if (pixel instanceof byte[]) {
+            byte ba[] = (byte[])pixel;
+            pixIdx = ba[0] & 0xff;
+        } else if (pixel instanceof short[]) {
+            short sa[] = (short[])pixel;
+            pixIdx = sa[0] & 0xffff;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[])pixel;
+            pixIdx = ia[0];
+        } else {
+            // awt.219=This transferType is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+        }
+
+        return getComponents(pixIdx, components, offset);
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        WritableRaster raster;
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1, pixel_bits, null);
+        } else if (pixel_bits <= 8) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, 1, null);
+        } else if (pixel_bits <= 16) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w, h, 1, null);
+        } else {
+            // awt.266=The number of bits in a pixel is greater than 16
+            throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
+        }
+
+        return raster;
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+
+        if (!(sm instanceof MultiPixelPackedSampleModel) && !(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getTransferType() != transferType) {
+            return false;
+        }
+        if (sm.getNumBands() != 1) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, pixel_bits);
+        }
+        int bandOffsets[] = new int[1];
+        bandOffsets[0] = 0;
+        return new ComponentSampleModel(transferType, w, h, 1, w, bandOffsets);
+
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        int sampleSize = raster.getSampleModel().getSampleSize(0);
+        return (raster.getTransferType() == transferType && raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
+                | components[offset + 2];
+
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+
+        int pixel;
+
+        switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte ba[] = (byte[])getDataElements(rgb, null);
+                pixel = ba[0] & 0xff;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short sa[] = (short[])getDataElements(rgb, null);
+                pixel = sa[0] & 0xffff;
+                break;
+            default:
+                // awt.267=The transferType is invalid
+                throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Gets the color map.
+     * 
+     * @param rgb
+     *            the destination array where the color map is written.
+     */
+    public final void getRGBs(int rgb[]) {
+        System.arraycopy(colorMap, 0, rgb, 0, mapSize);
+    }
+
+    /**
+     * Gets the red component of the color map.
+     * 
+     * @param r
+     *            the destination array.
+     */
+    public final void getReds(byte r[]) {
+        for (int i = 0; i < mapSize; i++) {
+            r[i] = (byte)(colorMap[i] >> 16);
+        }
+    }
+
+    /**
+     * Gets the green component of the color map.
+     * 
+     * @param g
+     *            the destination array.
+     */
+    public final void getGreens(byte g[]) {
+        for (int i = 0; i < mapSize; i++) {
+            g[i] = (byte)(colorMap[i] >> 8);
+        }
+    }
+
+    /**
+     * Gets the blue component of the color map.
+     * 
+     * @param b
+     *            the destination array.
+     */
+    public final void getBlues(byte b[]) {
+        for (int i = 0; i < mapSize; i++) {
+            b[i] = (byte)colorMap[i];
+        }
+    }
+
+    /**
+     * Gets the alpha component of the color map.
+     * 
+     * @param a
+     *            the destination array.
+     */
+    public final void getAlphas(byte a[]) {
+        for (int i = 0; i < mapSize; i++) {
+            a[i] = (byte)(colorMap[i] >> 24);
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[offset + numComponents];
+        }
+
+        components[offset + 0] = getRed(pixel);
+        components[offset + 1] = getGreen(pixel);
+        components[offset + 2] = getBlue(pixel);
+        if (hasAlpha && (components.length - offset) > 3) {
+            components[offset + 3] = getAlpha(pixel);
+        }
+
+        return components;
+    }
+
+    /**
+     * Checks if the specified pixel is valid for this color model.
+     * 
+     * @param pixel
+     *            the pixel.
+     * @return true, if the pixel is valid.
+     */
+    public boolean isValid(int pixel) {
+        if (validBits == null) {
+            return (pixel >= 0 && pixel < mapSize);
+        }
+        return (pixel < mapSize && validBits.testBit(pixel));
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        return (colorMap[pixel] >> 16) & 0xff;
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return colorMap[pixel];
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        return (colorMap[pixel] >> 8) & 0xff;
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        return colorMap[pixel] & 0xff;
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        return (colorMap[pixel] >> 24) & 0xff;
+    }
+
+    @Override
+    public int[] getComponentSize() {
+        return bits.clone();
+    }
+
+    /**
+     * Checks if this color model validates pixels.
+     * 
+     * @return true, if all pixels are valid, otherwise false.
+     */
+    public boolean isValid() {
+        return (validBits == null);
+    }
+
+    @Override
+    public void finalize() {
+        // TODO: implement
+        return;
+    }
+
+    /**
+     * Gets the index that represents the transparent pixel.
+     * 
+     * @return the index that represents the transparent pixel.
+     */
+    public final int getTransparentPixel() {
+        return transparentIndex;
+    }
+
+    @Override
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the size of the color map.
+     * 
+     * @return the map size.
+     */
+    public final int getMapSize() {
+        return mapSize;
+    }
+
+    /**
+     * Creates the color map.
+     * 
+     * @param size
+     *            the size.
+     * @param r
+     *            the r.
+     * @param g
+     *            the g.
+     * @param b
+     *            the b.
+     * @param a
+     *            the a.
+     * @param trans
+     *            the trans.
+     */
+    private void createColorMap(int size, byte r[], byte g[], byte b[], byte a[], int trans) {
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparency = Transparency.BITMASK;
+            transparentIndex = trans;
+        } else {
+            transparency = Transparency.OPAQUE;
+            transparentIndex = -1;
+        }
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) | (b[i] & 0xff);
+
+            if (trans == i) {
+                continue;
+            }
+
+            if (a == null) {
+                colorMap[i] |= 0xff000000;
+            } else {
+                alpha = a[i] & 0xff;
+                if (alpha == 0xff) {
+                    colorMap[i] |= 0xff000000;
+                } else if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                    if (transparentIndex < 0) {
+                        transparentIndex = i;
+                    }
+                } else {
+                    colorMap[i] |= (a[i] & 0xff) << 24;
+                    if (transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * This method checking, if Color Map has Gray palette.
+     */
+    private void checkPalette() {
+        grayPalette = false;
+        if (transparency > Transparency.OPAQUE) {
+            return;
+        }
+        int rgb = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            rgb = colorMap[i];
+            if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) || ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
+                return;
+            }
+        }
+        grayPalette = true;
+    }
+
+    /**
+     * Construction an array pixel representation.
+     * 
+     * @param colorMapIdx
+     *            the index into Color Map.
+     * @param pixel
+     *            the pixel
+     * @return the pixel representation array.
+     */
+    private Object createDataObject(int colorMapIdx, Object pixel) {
+        if (pixel == null) {
+            switch (transferType) {
+                case DataBuffer.TYPE_BYTE:
+                    byte[] ba = new byte[1];
+                    ba[0] = (byte)colorMapIdx;
+                    pixel = ba;
+                    break;
+                case DataBuffer.TYPE_USHORT:
+                    short[] sa = new short[1];
+                    sa[0] = (short)colorMapIdx;
+                    pixel = sa;
+                    break;
+                default:
+                    // awt.267=The transferType is invalid
+                    throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+            }
+        } else if (pixel instanceof byte[] && transferType == DataBuffer.TYPE_BYTE) {
+            byte ba[] = (byte[])pixel;
+            ba[0] = (byte)colorMapIdx;
+            pixel = ba;
+        } else if (pixel instanceof short[] && transferType == DataBuffer.TYPE_USHORT) {
+            short[] sa = (short[])pixel;
+            sa[0] = (short)colorMapIdx;
+            pixel = sa;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[])pixel;
+            ia[0] = colorMapIdx;
+            pixel = ia;
+        } else {
+            // awt.268=The pixel is not a primitive array of type transferType
+            throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
+        }
+        return pixel;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param hasAlpha
+     *            the has alpha.
+     * @return the int[].
+     */
+    private static int[] createBits(boolean hasAlpha) {
+
+        int numChannels;
+        if (hasAlpha) {
+            numChannels = 4;
+        } else {
+            numChannels = 3;
+        }
+
+        int bits[] = new int[numChannels];
+        for (int i = 0; i < numChannels; i++) {
+            bits[i] = 8;
+        }
+
+        return bits;
+
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType
+     *            the transfer type.
+     * @return the int.
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT) {
+            // awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or
+            // DataBuffer.TYPE_USHORT
+            throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
+        }
+        return transferType;
+    }
+
+    /**
+     * Checks if is gray palette.
+     * 
+     * @return true, if is gray palette.
+     */
+    boolean isGrayPallete() {
+        return grayPalette;
+    }
+
+}
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
new file mode 100644
index 0000000..a59d27a
--- /dev/null
+++ b/awt/java/awt/image/Kernel.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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 28, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Kernel class provides a matrix. This matrix is stored as a float array
+ * which describes how a specified pixel affects the value calculated for the
+ * pixel's position in the output image of a filtering operation. The X, Y
+ * origins indicate the kernel matrix element which corresponds to the pixel
+ * position for which an output value is being calculated.
+ * 
+ * @since Android 1.0
+ */
+public class Kernel implements Cloneable {
+
+    /**
+     * The x origin.
+     */
+    private final int xOrigin;
+
+    /**
+     * The y origin.
+     */
+    private final int yOrigin;
+
+    /**
+     * The width.
+     */
+    private int width;
+
+    /**
+     * The height.
+     */
+    private int height;
+
+    /**
+     * The data.
+     */
+    float data[];
+
+    /**
+     * Instantiates a new Kernel with the specified float array. The
+     * width*height elements of the data array are copied.
+     * 
+     * @param width
+     *            the width of the Kernel.
+     * @param height
+     *            the height of the Kernel.
+     * @param data
+     *            the data of Kernel.
+     */
+    public Kernel(int width, int height, float[] data) {
+        int dataLength = width * height;
+        if (data.length < dataLength) {
+            // awt.22B=Length of data should not be less than width*height
+            throw new IllegalArgumentException(Messages.getString("awt.22B")); //$NON-NLS-1$
+        }
+
+        this.width = width;
+        this.height = height;
+
+        this.data = new float[dataLength];
+        System.arraycopy(data, 0, this.data, 0, dataLength);
+
+        xOrigin = (width - 1) / 2;
+        yOrigin = (height - 1) / 2;
+    }
+
+    /**
+     * Gets the width of this Kernel.
+     * 
+     * @return the width of this Kernel.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the height of this Kernel.
+     * 
+     * @return the height of this Kernel.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the float data array of this Kernel.
+     * 
+     * @param data
+     *            the float array where the resulted data will be stored.
+     * @return the float data array of this Kernel.
+     */
+    public final float[] getKernelData(float[] data) {
+        if (data == null) {
+            data = new float[this.data.length];
+        }
+        System.arraycopy(this.data, 0, data, 0, this.data.length);
+
+        return data;
+    }
+
+    /**
+     * Gets the X origin of this Kernel.
+     * 
+     * @return the X origin of this Kernel.
+     */
+    public final int getXOrigin() {
+        return xOrigin;
+    }
+
+    /**
+     * Gets the Y origin of this Kernel.
+     * 
+     * @return the Y origin of this Kernel.
+     */
+    public final int getYOrigin() {
+        return yOrigin;
+    }
+
+    /**
+     * Returns a copy of this Kernel object.
+     * 
+     * @return the copy of this Kernel object.
+     */
+    @Override
+    public Object clone() {
+        return new Kernel(width, height, data);
+    }
+}
diff --git a/awt/java/awt/image/LookupOp.java b/awt/java/awt/image/LookupOp.java
new file mode 100644
index 0000000..3362c5c
--- /dev/null
+++ b/awt/java/awt/image/LookupOp.java
@@ -0,0 +1,661 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The LookupOp class performs a lookup operation which transforms a source
+ * image by filtering each band using a table of data. The table may contain a
+ * single array or it may contain a different data array for each band of the
+ * image.
+ * 
+ * @since Android 1.0
+ */
+public class LookupOp implements BufferedImageOp, RasterOp {
+
+    /**
+     * The lut.
+     */
+    private final LookupTable lut;
+
+    /**
+     * The hints.
+     */
+    private RenderingHints hints;
+
+    // TODO remove when this field is used
+    /**
+     * The can use ipp.
+     */
+    @SuppressWarnings("unused")
+    private final boolean canUseIpp;
+
+    // We don't create levels/values when it is possible to reuse old
+    /**
+     * The cached levels.
+     */
+    private int cachedLevels[];
+
+    /**
+     * The cached values.
+     */
+    private int cachedValues[];
+
+    // Number of channels for which cache is valid.
+    // If negative number of channels is same as positive but skipAlpha was
+    // specified
+    /**
+     * The valid for channels.
+     */
+    private int validForChannels;
+
+    /**
+     * The level initializer.
+     */
+    static int levelInitializer[] = new int[0x10000];
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+
+        for (int i = 1; i <= 0x10000; i++) {
+            levelInitializer[i - 1] = i;
+        }
+    }
+
+    /**
+     * Instantiates a new LookupOp object from the specified LookupTable object
+     * and a RenderingHints object.
+     * 
+     * @param lookup
+     *            the specified LookupTable object.
+     * @param hints
+     *            the RenderingHints object or null.
+     */
+    public LookupOp(LookupTable lookup, RenderingHints hints) {
+        if (lookup == null) {
+            throw new NullPointerException(Messages.getString("awt.01", "lookup")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        lut = lookup;
+        this.hints = hints;
+        canUseIpp = lut instanceof ByteLookupTable || lut instanceof ShortLookupTable;
+    }
+
+    /**
+     * Gets the LookupTable of the specified Object.
+     * 
+     * @return the LookupTable of the specified Object.
+     */
+    public final LookupTable getTable() {
+        return lut;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+
+            // Sync transfer type with LUT for component color model
+            if (dstCM instanceof ComponentColorModel) {
+                int transferType = dstCM.getTransferType();
+                if (lut instanceof ByteLookupTable) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                } else if (lut instanceof ShortLookupTable) {
+                    transferType = DataBuffer.TYPE_SHORT;
+                }
+
+                dstCM = new ComponentColorModel(dstCM.cs, dstCM.hasAlpha(),
+                        dstCM.isAlphaPremultiplied, dstCM.transparency, transferType);
+            }
+        }
+
+        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                throw new IllegalArgumentException(Messages.getString("awt.237")); //$NON-NLS-1$            }
+            }
+            if (src.getWidth() != dst.getWidth()) {
+                throw new IllegalArgumentException(Messages.getString("awt.28F")); //$NON-NLS-1$            }
+            }
+            if (src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.290")); //$NON-NLS-1$            }
+            }
+        }
+
+        if (lut.getNumComponents() != 1 && lut.getNumComponents() != src.getNumBands()) {
+            // awt.238=The number of arrays in the LookupTable does not meet the
+            // restrictions
+            throw new IllegalArgumentException(Messages.getString("awt.238")); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (!canUseIpp || ippFilter(src, dst, BufferedImage.TYPE_CUSTOM,
+        // false) != 0)
+        if (slowFilter(src, dst, false) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        int nLUTComponents = lut.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (nLUTComponents == 1 || nLUTComponents == nComponents - 1) {
+                skipAlpha = true;
+            } else if (nLUTComponents == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.229=Number of components in the LUT does not match the
+                // number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+            }
+        } else if (nLUTComponents == 1 || nLUTComponents == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.229=Number of components in the LUT does not match the number
+            // of bands
+            throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, null);
+        } else {
+            if (src.getWidth() != dst.getWidth()) {
+                throw new IllegalArgumentException(Messages.getString("awt.291")); //$NON-NLS-1$
+            }
+
+            if (src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.292")); //$NON-NLS-1$
+            }
+
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, null);
+                }
+            }
+        }
+
+        // TODO
+        // if (!canUseIpp || ippFilter(src.getRaster(), dst.getRaster(),
+        // src.getType(), skipAlpha) != 0)
+        if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @return the int.
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        int minSrcX = src.getMinX();
+        int minDstX = dst.getMinX();
+        int minSrcY = src.getMinY();
+        int minDstY = dst.getMinY();
+
+        int skippingChannels = skipAlpha ? 1 : 0;
+        int numBands2Process = src.getNumBands() - skippingChannels;
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int[] pixels = null;
+        int offset = lut.getOffset();
+
+        if (lut instanceof ByteLookupTable) {
+            byte[][] byteData = ((ByteLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1) {
+                for (int i = 0; i < pixels.length; i += numBands) {
+                    for (int b = 0; b < numBands2Process; b++) {
+                        pixels[i + b] = byteData[b][pixels[i + b] - offset] & 0xFF;
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length; i += numBands) {
+                    for (int b = 0; b < numBands2Process; b++) {
+                        pixels[i + b] = byteData[0][pixels[i + b] - offset] & 0xFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else if (lut instanceof ShortLookupTable) {
+            short[][] shortData = ((ShortLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1) {
+                for (int i = 0; i < pixels.length; i += numBands) {
+                    for (int b = 0; b < numBands2Process; b++) {
+                        pixels[i + b] = shortData[b][pixels[i + b] - offset] & 0xFFFF;
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length; i += numBands) {
+                    for (int b = 0; b < numBands2Process; b++) {
+                        pixels[i + b] = shortData[0][pixels[i + b] - offset] & 0xFFFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else {
+            int pixel[] = new int[src.getNumBands()];
+            int maxY = minSrcY + srcHeight;
+            int maxX = minSrcX + srcWidth;
+            for (int srcY = minSrcY, dstY = minDstY; srcY < maxY; srcY++, dstY++) {
+                for (int srcX = minSrcX, dstX = minDstX; srcX < maxX; srcX++, dstX++) {
+                    src.getPixel(srcX, srcY, pixel);
+                    lut.lookupPixel(pixel, pixel);
+                    dst.setPixel(dstX, dstY, pixel);
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Creates the byte levels.
+     * 
+     * @param channels
+     *            the channels.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @param levels
+     *            the levels.
+     * @param values
+     *            the values.
+     * @param channelsOrder
+     *            the channels order.
+     */
+    private final void createByteLevels(int channels, boolean skipAlpha, int levels[],
+            int values[], int channelsOrder[]) {
+        byte data[][] = ((ByteLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch < channels; dataIdx += dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+            int channelBase = nLevels * channelOffset;
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels - 1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from = 0, to = channelBase; from < nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFF;
+            }
+        }
+    }
+
+    /**
+     * Creates the short levels.
+     * 
+     * @param channels
+     *            the channels.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @param levels
+     *            the levels.
+     * @param values
+     *            the values.
+     * @param channelsOrder
+     *            the channels order.
+     */
+    private final void createShortLevels(int channels, boolean skipAlpha, int levels[],
+            int values[], int channelsOrder[]) {
+        short data[][] = ((ShortLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch < channels; dataIdx += dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels - 1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            int channelBase = nLevels * channelOffset;
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from = 0, to = channelBase; from < nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFFFF;
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param imageType
+     *            the image type.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @return the int.
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(Raster src, WritableRaster dst, int imageType, boolean skipAlpha) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                channelsOrder = new int[] {
+                        2, 1, 0, 3
+                };
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth() * 3;
+                dstStride = dst.getWidth() * 3;
+                channelsOrder = new int[] {
+                        2, 1, 0
+                };
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (srcSM instanceof PixelInterleavedSampleModel
+                        && dstSM instanceof PixelInterleavedSampleModel) {
+                    // Check PixelInterleavedSampleModel
+                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
+                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Have IPP functions for 1, 3 and 4 channels
+                    channels = srcSM.getNumBands();
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel)srcSM).getBandOffsets();
+                } else if (srcSM instanceof SinglePixelPackedSampleModel
+                        && dstSM instanceof SinglePixelPackedSampleModel) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                    // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
+                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
+                            || !(channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
+                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i = 0; i < channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i = 0; i < channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be
+                        // optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                            || dst.getSampleModelTranslateX() != 0
+                            || dst.getSampleModelTranslateY() != 0) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = null, values[] = null;
+        int channelMultiplier = skipAlpha ? -1 : 1;
+        if (channelMultiplier * channels == validForChannels) { // use existing
+            // levels/values
+            levels = cachedLevels;
+            values = cachedValues;
+        } else { // create new levels/values
+            if (lut instanceof ByteLookupTable) {
+                byte data[][] = ((ByteLookupTable)lut).getTable();
+                levels = new int[channels * data[0].length];
+                values = new int[channels * data[0].length];
+                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
+            } else if (lut instanceof ShortLookupTable) {
+                short data[][] = ((ShortLookupTable)lut).getTable();
+                levels = new int[channels * data[0].length];
+                values = new int[channels * data[0].length];
+                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
+            }
+
+            // cache levels/values
+            validForChannels = channelMultiplier * channels;
+            cachedLevels = levels;
+            cachedValues = values;
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = ippLUT(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst.getWidth(),
+                dst.getHeight(), dstStride, levels, values, channels, offsets, false);
+
+        return res;
+    }
+
+    /**
+     * Ipp lut.
+     * 
+     * @param src
+     *            the src.
+     * @param srcWidth
+     *            the src width.
+     * @param srcHeight
+     *            the src height.
+     * @param srcStride
+     *            the src stride.
+     * @param dst
+     *            the dst.
+     * @param dstWidth
+     *            the dst width.
+     * @param dstHeight
+     *            the dst height.
+     * @param dstStride
+     *            the dst stride.
+     * @param levels
+     *            the levels.
+     * @param values
+     *            the values.
+     * @param channels
+     *            the channels.
+     * @param offsets
+     *            the offsets.
+     * @param linear
+     *            the linear.
+     * @return the int.
+     */
+    final static native int ippLUT(Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride, int levels[], int values[],
+            int channels, int offsets[], boolean linear);
+}
diff --git a/awt/java/awt/image/LookupTable.java b/awt/java/awt/image/LookupTable.java
new file mode 100644
index 0000000..e465a54
--- /dev/null
+++ b/awt/java/awt/image/LookupTable.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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This abstract LookupTable class represents lookup table which is defined with
+ * the number of components and offset value. ByteLookupTable and
+ * ShortLookupTable classes are subclasses of LookupTable which contains byte
+ * and short data tables as an input arrays for bands or components of image.
+ * 
+ * @since Android 1.0
+ */
+public abstract class LookupTable {
+
+    /**
+     * The offset.
+     */
+    private int offset;
+
+    /**
+     * The num components.
+     */
+    private int numComponents;
+
+    /**
+     * Instantiates a new LookupTable with the specified offset value and number
+     * of components.
+     * 
+     * @param offset
+     *            the offset value.
+     * @param numComponents
+     *            the number of components.
+     */
+    protected LookupTable(int offset, int numComponents) {
+        if (offset < 0) {
+            // awt.232=Offset should be not less than zero
+            throw new IllegalArgumentException(Messages.getString("awt.232")); //$NON-NLS-1$
+        }
+        if (numComponents < 1) {
+            // awt.233=Number of components should be positive
+            throw new IllegalArgumentException(Messages.getString("awt.233")); //$NON-NLS-1$
+        }
+
+        this.offset = offset;
+        this.numComponents = numComponents;
+    }
+
+    /**
+     * Gets the offset value of this Lookup table.
+     * 
+     * @return the offset value of this Lookup table.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of components of this Lookup table.
+     * 
+     * @return the number components of this Lookup table.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Returns an integer array which contains samples of the specified pixel which
+     * is translated with the lookup table of this LookupTable. The resulted
+     * array is stored to the dst array.
+     * 
+     * @param src
+     *            the source array.
+     * @param dst
+     *            the destination array where the result can be stored.
+     * @return the integer array of translated samples of a pixel.
+     */
+    public abstract int[] lookupPixel(int[] src, int[] dst);
+}
diff --git a/awt/java/awt/image/MemoryImageSource.java b/awt/java/awt/image/MemoryImageSource.java
new file mode 100644
index 0000000..644fd40f
--- /dev/null
+++ b/awt/java/awt/image/MemoryImageSource.java
@@ -0,0 +1,603 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MemoryImageSource class is used to produces pixels of an image from an
+ * array. This class can manage a memory image which contains an animation or
+ * custom rendering.
+ * 
+ * @since Android 1.0
+ */
+public class MemoryImageSource implements ImageProducer {
+
+    /**
+     * The width.
+     */
+    int width;
+
+    /**
+     * The height.
+     */
+    int height;
+
+    /**
+     * The cm.
+     */
+    ColorModel cm;
+
+    /**
+     * The b data.
+     */
+    byte bData[];
+
+    /**
+     * The i data.
+     */
+    int iData[];
+
+    /**
+     * The offset.
+     */
+    int offset;
+
+    /**
+     * The scanline.
+     */
+    int scanline;
+
+    /**
+     * The properties.
+     */
+    Hashtable<?, ?> properties;
+
+    /**
+     * The consumers.
+     */
+    Vector<ImageConsumer> consumers;
+
+    /**
+     * The animated.
+     */
+    boolean animated;
+
+    /**
+     * The fullbuffers.
+     */
+    boolean fullbuffers;
+
+    /**
+     * The data type.
+     */
+    int dataType;
+
+    /**
+     * The Constant DATA_TYPE_BYTE.
+     */
+    static final int DATA_TYPE_BYTE = 0;
+
+    /**
+     * The Constant DATA_TYPE_INT.
+     */
+    static final int DATA_TYPE_INT = 1;
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param cm
+     *            the specified ColorModel.
+     * @param pix
+     *            the pixel array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     * @param props
+     *            the set of properties to be used for image processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan,
+            Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param cm
+     *            the specified ColorModel.
+     * @param pix
+     *            the pixel array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     * @param props
+     *            the set of properties to be used for image processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[], int off, int scan,
+            Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters and
+     * default RGB ColorModel.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param pix
+     *            the pixel array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     * @param props
+     *            the set of properties to be used for image processing.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param cm
+     *            the specified ColorModel.
+     * @param pix
+     *            the pixel array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param cm
+     *            the specified ColorModel.
+     * @param pix
+     *            the pixel array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[], int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified parameters and
+     * default RGB ColorModel.
+     * 
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param pix
+     *            the pixels array.
+     * @param off
+     *            the offset in the pixel array.
+     * @param scan
+     *            the distance from one pixel's row to the next in the pixel
+     *            array.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        if (!isConsumer(ic) && ic != null) {
+            consumers.addElement(ic);
+        }
+        try {
+            setHeader(ic);
+            setPixels(ic, 0, 0, width, height);
+            if (animated) {
+                ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+            } else {
+                ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+                if (isConsumer(ic)) {
+                    removeConsumer(ic);
+                }
+            }
+        } catch (Exception e) {
+            if (isConsumer(ic)) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+            if (isConsumer(ic)) {
+                removeConsumer(ic);
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        consumers.removeElement(ic);
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (ic == null || consumers.contains(ic)) {
+            return;
+        }
+        consumers.addElement(ic);
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding the pixels for
+     * this image. If an animation flag is set to true value by the
+     * setAnimated() method, the new pixels will be immediately delivered to the
+     * ImageConsumers.
+     * 
+     * @param newpix
+     *            the new pixel array.
+     * @param newmodel
+     *            the new ColorModel.
+     * @param offset
+     *            the offset in the array.
+     * @param scansize
+     *            the distance from one row of pixels to the next row in the
+     *            pixel array.
+     */
+    public synchronized void newPixels(int newpix[], ColorModel newmodel, int offset, int scansize) {
+        this.dataType = DATA_TYPE_INT;
+        this.iData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding the pixels for
+     * this image. If an animation flag is set to true value by the
+     * setAnimated() method, the new pixels will be immediately delivered to the
+     * ImageConsumers.
+     * 
+     * @param newpix
+     *            the new pixel array.
+     * @param newmodel
+     *            the new ColorModel.
+     * @param offset
+     *            the offset in the array.
+     * @param scansize
+     *            the distance from one row of pixels to the next row in the
+     *            pixel array.
+     */
+    public synchronized void newPixels(byte newpix[], ColorModel newmodel, int offset, int scansize) {
+        this.dataType = DATA_TYPE_BYTE;
+        this.bData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Sets the full buffer updates flag to true. If this is an animated image,
+     * the image consumers hints are updated accordingly.
+     * 
+     * @param fullbuffers
+     *            the true if the pixel buffer should be sent always.
+     */
+    public synchronized void setFullBufferUpdates(boolean fullbuffers) {
+        if (this.fullbuffers == fullbuffers) {
+            return;
+        }
+        this.fullbuffers = fullbuffers;
+        if (animated) {
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try {
+                    if (fullbuffers) {
+                        con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT
+                                | ImageConsumer.COMPLETESCANLINES);
+                    } else {
+                        con.setHints(ImageConsumer.RANDOMPIXELORDER);
+                    }
+                } catch (Exception e) {
+                    if (isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if (isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the flag that tells whether this memory image has more than one
+     * frame (for animation): true for multiple frames, false if this class
+     * represents a single frame image.
+     * 
+     * @param animated
+     *            whether this image represents an animation.
+     */
+    public synchronized void setAnimated(boolean animated) {
+        if (this.animated == animated) {
+            return;
+        }
+        Object consAr[] = consumers.toArray();
+        for (Object element : consAr) {
+            ImageConsumer con = (ImageConsumer)element;
+            try {
+                con.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            } catch (Exception e) {
+                if (isConsumer(con)) {
+                    con.imageComplete(ImageConsumer.IMAGEERROR);
+                }
+            }
+            if (isConsumer(con)) {
+                removeConsumer(con);
+            }
+        }
+        this.animated = animated;
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to ImageConsumers and
+     * notifies them that an animation frame is completed only if the {@code
+     * framenotify} parameter is true. That works only if the animated flag has
+     * been set to true by the setAnimated() method. If the full buffer update
+     * flag has been set to true by the setFullBufferUpdates() method, then the
+     * entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular area.
+     * @param y
+     *            the Y coordinate of the rectangular area.
+     * @param w
+     *            the width of the rectangular area.
+     * @param h
+     *            the height of the rectangular area.
+     * @param framenotify
+     *            true if a SINGLEFRAMEDONE notification should be sent to the
+     *            registered consumers, false otherwise.
+     */
+    public synchronized void newPixels(int x, int y, int w, int h, boolean framenotify) {
+        if (animated) {
+            if (fullbuffers) {
+                x = 0;
+                y = 0;
+                w = width;
+                h = height;
+            } else {
+                if (x < 0) {
+                    w += x;
+                    x = 0;
+                }
+                if (w > width) {
+                    w = width - x;
+                }
+                if (y < 0) {
+                    h += y;
+                    y = 0;
+                }
+            }
+            if (h > height) {
+                h = height - y;
+            }
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try {
+                    if (w > 0 && h > 0) {
+                        setPixels(con, x, y, w, h);
+                    }
+                    if (framenotify) {
+                        con.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+                    }
+                } catch (Exception ex) {
+                    if (isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if (isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to the ImageConsumers
+     * and notifies them that an animation frame is completed if the animated
+     * flag has been set to true by the setAnimated() method. If the full buffer
+     * update flag has been set to true by the setFullBufferUpdates() method,
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular area.
+     * @param y
+     *            the Y coordinate of the rectangular area.
+     * @param w
+     *            the width of the rectangular area.
+     * @param h
+     *            the height of the rectangular area.
+     */
+    public synchronized void newPixels(int x, int y, int w, int h) {
+        newPixels(x, y, w, h, true);
+    }
+
+    /**
+     * Sends a new buffer of pixels to the ImageConsumers and notifies them that
+     * an animation frame is completed if the animated flag has been set to true
+     * by the setAnimated() method.
+     */
+    public void newPixels() {
+        newPixels(0, 0, width, height, true);
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     * @param model
+     *            the model.
+     * @param pixels
+     *            the pixels.
+     * @param off
+     *            the off.
+     * @param scan
+     *            the scan.
+     * @param prop
+     *            the prop.
+     */
+    private void init(int width, int height, ColorModel model, byte pixels[], int off, int scan,
+            Hashtable<?, ?> prop) {
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.bData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_BYTE;
+        this.consumers = new Vector<ImageConsumer>();
+
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width
+     *            the width.
+     * @param height
+     *            the height.
+     * @param model
+     *            the model.
+     * @param pixels
+     *            the pixels.
+     * @param off
+     *            the off.
+     * @param scan
+     *            the scan.
+     * @param prop
+     *            the prop.
+     */
+    private void init(int width, int height, ColorModel model, int pixels[], int off, int scan,
+            Hashtable<?, ?> prop) {
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.iData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_INT;
+        this.consumers = new Vector<ImageConsumer>();
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param con
+     *            the con.
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     * @param w
+     *            the w.
+     * @param h
+     *            the h.
+     */
+    private void setPixels(ImageConsumer con, int x, int y, int w, int h) {
+        int pixelOff = scanline * y + offset + x;
+
+        switch (dataType) {
+            case DATA_TYPE_BYTE:
+                con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
+                break;
+            case DATA_TYPE_INT:
+                con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
+                break;
+            default:
+                // awt.22A=Wrong type of pixels array
+                throw new IllegalArgumentException(Messages.getString("awt.22A")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Sets the header.
+     * 
+     * @param con
+     *            the new header.
+     */
+    private synchronized void setHeader(ImageConsumer con) {
+        con.setDimensions(width, height);
+        con.setProperties(properties);
+        con.setColorModel(cm);
+        con
+                .setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES)
+                        : ImageConsumer.RANDOMPIXELORDER)
+                        : (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
+                                | ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
+    }
+
+}
diff --git a/awt/java/awt/image/MultiPixelPackedSampleModel.java b/awt/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 0000000..3dc13d8
--- /dev/null
+++ b/awt/java/awt/image/MultiPixelPackedSampleModel.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MultiPixelPackedSampleModel class represents image data with one band.
+ * This class packs multiple pixels with one sample in one data element and
+ * supports the following data types: DataBuffer.TYPE_BYTE,
+ * DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT.
+ * 
+ * @since Android 1.0
+ */
+public class MultiPixelPackedSampleModel extends SampleModel {
+
+    /**
+     * The pixel bit stride.
+     */
+    private int pixelBitStride;
+
+    /**
+     * The scanline stride.
+     */
+    private int scanlineStride;
+
+    /**
+     * The data bit offset.
+     */
+    private int dataBitOffset;
+
+    /**
+     * The bit mask.
+     */
+    private int bitMask;
+
+    /**
+     * The data element size.
+     */
+    private int dataElementSize;
+
+    /**
+     * The pixels per data element.
+     */
+    private int pixelsPerDataElement;
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType
+     *            the data type of the samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param numberOfBits
+     *            the number of bits per pixel.
+     * @param scanlineStride
+     *            the scanline stride of the of the image data.
+     * @param dataBitOffset
+     *            the array of the band offsets.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits,
+            int scanlineStride, int dataBitOffset) {
+
+        super(dataType, w, h, 1);
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        if (numberOfBits == 0) {
+            // awt.20C=Number of Bits equals to zero
+            throw new RasterFormatException(Messages.getString("awt.20C")); //$NON-NLS-1$
+        }
+        this.pixelBitStride = numberOfBits;
+        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
+        if (dataElementSize % pixelBitStride != 0) {
+            // awt.20D=The number of bits per pixel is not a power of 2 or
+            // pixels span data element boundaries
+            throw new RasterFormatException(Messages.getString("awt.20D")); //$NON-NLS-1$
+        }
+
+        if (dataBitOffset % numberOfBits != 0) {
+            // awt.20E=Data Bit offset is not a multiple of pixel bit stride
+            throw new RasterFormatException(Messages.getString("awt.20E")); //$NON-NLS-1$
+        }
+        this.dataBitOffset = dataBitOffset;
+
+        this.pixelsPerDataElement = dataElementSize / pixelBitStride;
+        this.bitMask = (1 << numberOfBits) - 1;
+    }
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType
+     *            the data type of the samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param numberOfBits
+     *            the number of bits per pixel.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h, int numberOfBits) {
+
+        this(dataType, w, h, numberOfBits,
+                (numberOfBits * w + DataBuffer.getDataTypeSize(dataType) - 1)
+                        / DataBuffer.getDataTypeSize(dataType), 0);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                byte bdata[];
+                if (obj == null) {
+                    bdata = new byte[1];
+                } else {
+                    bdata = (byte[])obj;
+                }
+                bdata[0] = (byte)getSample(x, y, 0, data);
+                obj = bdata;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short sdata[];
+                if (obj == null) {
+                    sdata = new short[1];
+                } else {
+                    sdata = (short[])obj;
+                }
+                sdata[0] = (short)getSample(x, y, 0, data);
+                obj = sdata;
+                break;
+            case DataBuffer.TYPE_INT:
+                int idata[];
+                if (obj == null) {
+                    idata = new int[1];
+                } else {
+                    idata = (int[])obj;
+                }
+                idata[0] = getSample(x, y, 0, data);
+                obj = idata;
+                break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        setSample(x, y, obj, data, 1, 0);
+    }
+
+    /**
+     * Compares this MultiPixelPackedSampleModel object with the specified
+     * object.
+     * 
+     * @param o
+     *            the Object to be compared.
+     * @return true, if the object is a MultiPixelPackedSampleModel with the
+     *         same data parameter values as this MultiPixelPackedSampleModel,
+     *         false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
+            return false;
+        }
+
+        MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel)o;
+        return this.width == model.width && this.height == model.height
+                && this.numBands == model.numBands && this.dataType == model.dataType
+                && this.pixelBitStride == model.pixelBitStride && this.bitMask == model.bitMask
+                && this.pixelsPerDataElement == model.pixelsPerDataElement
+                && this.dataElementSize == model.dataElementSize
+                && this.dataBitOffset == model.dataBitOffset
+                && this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands != null && bands.length != 1) {
+            // awt.20F=Number of bands must be only 1
+            throw new RasterFormatException(Messages.getString("awt.20F")); //$NON-NLS-1$
+        }
+        return createCompatibleSampleModel(width, height);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        pixel[0] = getSample(x, y, 0, data);
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        setSample(x, y, iArray, data, 2, 0);
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height || b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int elem = data.getElem(y * scanlineStride + bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize - 1)) - pixelBitStride;
+
+        return (elem >> shift) & bitMask;
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        setSample(x, y, null, data, 3, s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
+                break;
+            case DataBuffer.TYPE_INT:
+                dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
+                break;
+        }
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x
+     *            the X coordinate of the specified pixel.
+     * @param y
+     *            the Y coordinate of the specified pixel.
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + (x * pixelBitStride + dataBitOffset) / dataElementSize;
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return pixelBitStride;
+    }
+
+    /**
+     * Gets the bit offset in the data element which is stored for the specified
+     * pixel of a scanline.
+     * 
+     * @param x
+     *            the pixel.
+     * @return the bit offset of the pixel in the data element.
+     */
+    public int getBitOffset(int x) {
+        return (x * pixelBitStride + dataBitOffset) % dataElementSize;
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        int sampleSizes[] = {
+            pixelBitStride
+        };
+        return sampleSizes;
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= scanlineStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelBitStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataBitOffset;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= bitMask;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataElementSize;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelsPerDataElement;
+        return hash;
+    }
+
+    @Override
+    public int getTransferType() {
+        if (pixelBitStride > 16) {
+            return DataBuffer.TYPE_INT;
+        } else if (pixelBitStride > 8) {
+            return DataBuffer.TYPE_USHORT;
+        } else {
+            return DataBuffer.TYPE_BYTE;
+        }
+    }
+
+    /**
+     * Gets the scanline stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the scanline stride of this MultiPixelPackedSampleModel.
+     */
+    public int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel bit stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the pixel bit stride of this MultiPixelPackedSampleModel.
+     */
+    public int getPixelBitStride() {
+        return pixelBitStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Gets the data bit offset.
+     * 
+     * @return the data bit offset.
+     */
+    public int getDataBitOffset() {
+        return dataBitOffset;
+    }
+
+    /**
+     * This method is used by other methods of this class. The behavior of this
+     * method depends on the method which has been invoke this one. The argument
+     * methodId is used to choose valid behavior in a particular case. If
+     * methodId is equal to 1 it means that this method has been invoked by the
+     * setDataElements() method, 2 - means setPixel(), and setSample() in any
+     * other cases.
+     * 
+     * @param x
+     *            the x.
+     * @param y
+     *            the y.
+     * @param obj
+     *            the obj.
+     * @param data
+     *            the data.
+     * @param methodId
+     *            the method id.
+     * @param s
+     *            the s.
+     */
+    private void setSample(final int x, final int y, final Object obj, final DataBuffer data,
+            final int methodId, int s) {
+        if ((x < 0) || (y < 0) || (x >= this.width) || (y >= this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        final int bitnum = dataBitOffset + x * pixelBitStride;
+        final int idx = y * scanlineStride + bitnum / dataElementSize;
+        final int shift = dataElementSize - (bitnum & (dataElementSize - 1)) - pixelBitStride;
+        final int mask = ~(bitMask << shift);
+        int elem = data.getElem(idx);
+
+        switch (methodId) {
+            case 1: { // Invoked from setDataElements()
+                switch (getTransferType()) {
+                    case DataBuffer.TYPE_BYTE:
+                        s = ((byte[])obj)[0] & 0xff;
+                        break;
+                    case DataBuffer.TYPE_USHORT:
+                        s = ((short[])obj)[0] & 0xffff;
+                        break;
+                    case DataBuffer.TYPE_INT:
+                        s = ((int[])obj)[0];
+                        break;
+                }
+                break;
+            }
+            case 2: { // Invoked from setPixel()
+                s = ((int[])obj)[0];
+                break;
+            }
+        }
+
+        elem &= mask;
+        elem |= (s & bitMask) << shift;
+        data.setElem(idx, elem);
+    }
+}
diff --git a/awt/java/awt/image/PackedColorModel.java b/awt/java/awt/image/PackedColorModel.java
new file mode 100644
index 0000000..4d1c2e5
--- /dev/null
+++ b/awt/java/awt/image/PackedColorModel.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class PackedColorModel represents a color model where the components are
+ * just the red, green, and blue bands, plus an alpha band if alpha is
+ * supported.
+ * 
+ * @since Android 1.0
+ */
+public abstract class PackedColorModel extends ColorModel {
+
+    /**
+     * The component masks.
+     */
+    int componentMasks[];
+
+    /**
+     * The offsets.
+     */
+    int offsets[];
+
+    /**
+     * The scales.
+     */
+    float scales[];
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space
+     *            the color space.
+     * @param bits
+     *            the array of component masks.
+     * @param colorMaskArray
+     *            the array that gives the bitmask corresponding to each color
+     *            band (red, green, and blue).
+     * @param alphaMask
+     *            the bitmask corresponding to the alpha band.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied in this color model.
+     * @param trans
+     *            the transparency strategy, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     * @throws IllegalArgumentException
+     *             if the number of bits in the combined bitmasks for the color
+     *             bands is less than one or greater than 32.
+     */
+    public PackedColorModel(ColorSpace space, int bits, int colorMaskArray[], int alphaMask,
+            boolean isAlphaPremultiplied, int trans, int transferType) {
+
+        super(bits, createBits(colorMaskArray, alphaMask), space, (alphaMask == 0 ? false : true),
+                isAlphaPremultiplied, trans, validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        componentMasks = new int[numComponents];
+        for (int i = 0; i < numColorComponents; i++) {
+            componentMasks[i] = colorMaskArray[i];
+        }
+
+        if (hasAlpha) {
+            componentMasks[numColorComponents] = alphaMask;
+            if (this.bits[numColorComponents] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space
+     *            the color space.
+     * @param bits
+     *            the array of component masks.
+     * @param rmask
+     *            the bitmask corresponding to the red band.
+     * @param gmask
+     *            the bitmask corresponding to the green band.
+     * @param bmask
+     *            the bitmask corresponding to the blue band.
+     * @param amask
+     *            the bitmask corresponding to the alpha band.
+     * @param isAlphaPremultiplied
+     *            whether the alpha is pre-multiplied in this color model.
+     * @param trans
+     *            the transparency strategy, @see java.awt.Transparency.
+     * @param transferType
+     *            the transfer type (primitive java type to use for the
+     *            components).
+     * @throws IllegalArgumentException
+     *             if the number of bits in the combined bitmasks for the color
+     *             bands is less than one or greater than 32.
+     */
+    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask,
+            boolean isAlphaPremultiplied, int trans, int transferType) {
+
+        super(bits, createBits(rmask, gmask, bmask, amask), space, (amask == 0 ? false : true),
+                isAlphaPremultiplied, trans, validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        if (cs.getType() != ColorSpace.TYPE_RGB) {
+            // awt.239=The space is not a TYPE_RGB space
+            throw new IllegalArgumentException(Messages.getString("awt.239")); //$NON-NLS-1$
+        }
+
+        for (int i = 0; i < numColorComponents; i++) {
+            if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                // awt.23A=The min/max normalized component values are not
+                // 0.0/1.0
+                throw new IllegalArgumentException(Messages.getString("awt.23A")); //$NON-NLS-1$
+            }
+        }
+        componentMasks = new int[numComponents];
+        componentMasks[0] = rmask;
+        componentMasks[1] = gmask;
+        componentMasks[2] = bmask;
+
+        if (hasAlpha) {
+            componentMasks[3] = amask;
+            if (this.bits[3] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if (!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int band[] = new int[1];
+        band[0] = raster.getNumBands() - 1;
+        return raster.createWritableChild(x, y, w, h, x, y, band);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof PackedColorModel)) {
+            return false;
+        }
+        PackedColorModel cm = (PackedColorModel)obj;
+
+        return (pixel_bits == cm.getPixelSize() && transferType == cm.getTransferType()
+                && cs.getType() == cm.getColorSpace().getType() && hasAlpha == cm.hasAlpha()
+                && isAlphaPremultiplied == cm.isAlphaPremultiplied()
+                && transparency == cm.getTransparency()
+                && numColorComponents == cm.getNumColorComponents()
+                && numComponents == cm.getNumComponents()
+                && Arrays.equals(bits, cm.getComponentSize()) && Arrays.equals(componentMasks, cm
+                .getMasks()));
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+        SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel)sm;
+
+        return ((esm.getNumBands() == numComponents) && (esm.getTransferType() == transferType) && Arrays
+                .equals(esm.getBitMasks(), componentMasks));
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(transferType, w, h, componentMasks);
+    }
+
+    /**
+     * Gets the bitmask corresponding to the specified color component.
+     * 
+     * @param index
+     *            the index of the desired color.
+     * @return the mask.
+     */
+    public final int getMask(int index) {
+        return componentMasks[index];
+    }
+
+    /**
+     * Gets the bitmasks of the components.
+     * 
+     * @return the masks.
+     */
+    public final int[] getMasks() {
+        return (componentMasks.clone());
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param colorMaskArray
+     *            the color mask array.
+     * @param alphaMask
+     *            the alpha mask.
+     * @return the int[].
+     */
+    private static int[] createBits(int colorMaskArray[], int alphaMask) {
+        int bits[];
+        int numComp;
+        if (alphaMask == 0) {
+            numComp = colorMaskArray.length;
+        } else {
+            numComp = colorMaskArray.length + 1;
+        }
+
+        bits = new int[numComp];
+        int i = 0;
+        for (; i < colorMaskArray.length; i++) {
+            bits[i] = countCompBits(colorMaskArray[i]);
+            if (bits[i] < 0) {
+                // awt.23B=The mask of the {0} component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23B", i)); //$NON-NLS-1$
+            }
+        }
+
+        if (i < numComp) {
+            bits[i] = countCompBits(alphaMask);
+
+            if (bits[i] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param rmask
+     *            the rmask.
+     * @param gmask
+     *            the gmask.
+     * @param bmask
+     *            the bmask.
+     * @param amask
+     *            the amask.
+     * @return the int[].
+     */
+    private static int[] createBits(int rmask, int gmask, int bmask, int amask) {
+
+        int numComp;
+        if (amask == 0) {
+            numComp = 3;
+        } else {
+            numComp = 4;
+        }
+        int bits[] = new int[numComp];
+
+        bits[0] = countCompBits(rmask);
+        if (bits[0] < 0) {
+            // awt.23D=The mask of the red component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23D")); //$NON-NLS-1$
+        }
+
+        bits[1] = countCompBits(gmask);
+        if (bits[1] < 0) {
+            // awt.23E=The mask of the green component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23E")); //$NON-NLS-1$
+        }
+
+        bits[2] = countCompBits(bmask);
+        if (bits[2] < 0) {
+            // awt.23F=The mask of the blue component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23F")); //$NON-NLS-1$
+        }
+
+        if (amask != 0) {
+            bits[3] = countCompBits(amask);
+            if (bits[3] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Count comp bits.
+     * 
+     * @param compMask
+     *            the comp mask.
+     * @return the int.
+     */
+    private static int countCompBits(int compMask) {
+        int bits = 0;
+        if (compMask != 0) {
+            // Deleting final zeros
+            while ((compMask & 1) == 0) {
+                compMask >>>= 1;
+            }
+            // Counting component bits
+            while ((compMask & 1) == 1) {
+                compMask >>>= 1;
+                bits++;
+            }
+        }
+
+        if (compMask != 0) {
+            return -1;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType
+     *            the transfer type.
+     * @return the int.
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT
+                && transferType != DataBuffer.TYPE_INT) {
+            // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
+            // DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+            throw new IllegalArgumentException(Messages.getString("awt.240")); //$NON-NLS-1$
+        }
+        return transferType;
+    }
+
+    /**
+     * Parses the components.
+     */
+    private void parseComponents() {
+        offsets = new int[numComponents];
+        scales = new float[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            int off = 0;
+            int mask = componentMasks[i];
+            while ((mask & 1) == 0) {
+                mask >>>= 1;
+                off++;
+            }
+            offsets[i] = off;
+            if (bits[i] == 0) {
+                scales[i] = 256.0f; // May be any value different from zero,
+                // because will dividing by zero
+            } else {
+                scales[i] = 255.0f / maxValues[i];
+            }
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
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..8e646f8
--- /dev/null
+++ b/awt/java/awt/image/PixelInterleavedSampleModel.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The PixelInterleavedSampleModel class represents image data as represented as
+ * interleaved pixels and for which each sample of a pixel takes one data
+ * element of the DataBuffer.
+ * 
+ * @since Android 1.0
+ */
+public class PixelInterleavedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Instantiates a new PixelInterleavedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType
+     *            the data type of the samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param pixelStride
+     *            the pixel stride of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the of the image data.
+     * @param bandOffsets
+     *            the array of the band offsets.
+     */
+    public PixelInterleavedSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
+
+        int maxOffset = bandOffsets[0];
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        maxOffset -= minOffset;
+
+        if (maxOffset > scanlineStride) {
+            // awt.241=Any offset between bands is greater than the Scanline
+            // stride
+            throw new IllegalArgumentException(Messages.getString("awt.241")); //$NON-NLS-1$
+        }
+
+        if (maxOffset > pixelStride) {
+            // awt.242=Pixel stride is less than any offset between bands
+            throw new IllegalArgumentException(Messages.getString("awt.242")); //$NON-NLS-1$
+        }
+
+        if (pixelStride * w > scanlineStride) {
+            // awt.243=Product of Pixel stride and w is greater than Scanline
+            // stride
+            throw new IllegalArgumentException(Messages.getString("awt.243")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        int newOffsets[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            newOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new PixelInterleavedSampleModel(dataType, width, height, pixelStride,
+                scanlineStride, newOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int newOffsets[];
+        int minOffset = bandOffsets[0];
+
+        for (int i = 1; i < numBands; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        if (minOffset > 0) {
+            newOffsets = new int[numBands];
+            for (int i = 0; i < numBands; i++) {
+                newOffsets[i] = bandOffsets[i] - minOffset;
+            }
+        } else {
+            newOffsets = bandOffsets;
+        }
+
+        return new PixelInterleavedSampleModel(dataType, w, h, pixelStride, pixelStride * w,
+                newOffsets);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x66;
+    }
+
+}
diff --git a/awt/java/awt/image/RGBImageFilter.java b/awt/java/awt/image/RGBImageFilter.java
new file mode 100644
index 0000000..f5fe5d9
--- /dev/null
+++ b/awt/java/awt/image/RGBImageFilter.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+/**
+ * The RGBImageFilter class represents a filter which modifies pixels of an
+ * image in the default RGB ColorModel.
+ * 
+ * @since Android 1.0
+ */
+public abstract class RGBImageFilter extends ImageFilter {
+
+    /**
+     * The original model is the ColorModel to be replaced by the new model when
+     * substituteColorModel is called.
+     */
+    protected ColorModel origmodel;
+
+    /**
+     * The new model is the ColorModel with which to replace the original model
+     * when substituteColorModel is called.
+     */
+    protected ColorModel newmodel;
+
+    /**
+     * The canFilterIndexColorModel indicates if it is acceptable to apply the
+     * color filtering of the filterRGB method to the color table entries of an
+     * IndexColorModel object.
+     */
+    protected boolean canFilterIndexColorModel;
+
+    /**
+     * Instantiates a new RGBImageFilter.
+     */
+    public RGBImageFilter() {
+    }
+
+    /**
+     * Filters an IndexColorModel object by calling filterRGB function for each
+     * entry of IndexColorModel.
+     * 
+     * @param icm
+     *            the IndexColorModel to be filtered.
+     * @return the IndexColorModel.
+     */
+    public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
+        int transferType = icm.getTransferType();
+        int bits = icm.getPixelSize();
+        int mapSize = icm.getMapSize();
+        int colorMap[] = new int[mapSize];
+        int filteredColorMap[] = new int[mapSize];
+        icm.getRGBs(colorMap);
+        int trans = -1;
+        boolean hasAlpha = false;
+        for (int i = 0; i < mapSize; i++) {
+            filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]);
+            int alpha = filteredColorMap[i] >>> 24;
+            if (alpha != 0xff) {
+                if (!hasAlpha) {
+                    hasAlpha = true;
+                }
+                if (alpha == 0 && trans < 0) {
+                    trans = i;
+                }
+            }
+        }
+
+        return new IndexColorModel(bits, mapSize, filteredColorMap, 0, hasAlpha, trans,
+                transferType);
+    }
+
+    /**
+     * Replaces the original color model and the new one.
+     * 
+     * @param oldcm
+     *            the old ColorModel.
+     * @param newcm
+     *            the new ColorModel.
+     */
+    public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
+        origmodel = oldcm;
+        newmodel = newcm;
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if (model instanceof IndexColorModel && canFilterIndexColorModel) {
+            IndexColorModel icm = (IndexColorModel)model;
+            ColorModel filteredModel = filterIndexColorModel(icm);
+            substituteColorModel(model, filteredModel);
+            consumer.setColorModel(filteredModel);
+        } else {
+            consumer.setColorModel(ColorModel.getRGBdefault());
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+
+        if (model == null || model == origmodel) {
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        } else {
+            int rgbPixels[] = new int[w];
+            for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) {
+
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+
+        if (model == null || model == origmodel) {
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        } else {
+            int rgbPixels[] = new int[w];
+            for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) {
+
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx] & 0xff);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    /**
+     * Filters a region of pixels in the default RGB ColorModel by calling the
+     * filterRGB method for them.
+     * 
+     * @param x
+     *            the X coordinate of region.
+     * @param y
+     *            the Y coordinate of region.
+     * @param w
+     *            the width of region.
+     * @param h
+     *            the height of region.
+     * @param pixels
+     *            the pixels array.
+     * @param off
+     *            the offset of array.
+     * @param scansize
+     *            the distance between rows of pixels in the array.
+     */
+    public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, int off, int scansize) {
+
+        for (int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize) {
+            for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                pixels[lineOff + idx] = filterRGB(sx, sy, pixels[lineOff + idx]);
+            }
+        }
+        consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, off, scansize);
+    }
+
+    /**
+     * Converts a single input pixel in the default RGB ColorModel to a single
+     * output pixel.
+     * 
+     * @param x
+     *            the X pixel's coordinate.
+     * @param y
+     *            the Y pixel's coordinate.
+     * @param rgb
+     *            a pixel in the default RGB color model.
+     * @return a filtered pixel in the default RGB color model.
+     */
+    public abstract int filterRGB(int x, int y, int rgb);
+
+}
diff --git a/awt/java/awt/image/Raster.java b/awt/java/awt/image/Raster.java
new file mode 100644
index 0000000..6749fde
--- /dev/null
+++ b/awt/java/awt/image/Raster.java
@@ -0,0 +1,1515 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.image.OrdinaryWritableRaster;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Raster class represents a rectangular area of pixels. This class is
+ * defined by DataBuffer and SampleModel objects. The DataBuffer object stores
+ * sample values and DSampleModel defines the location of sample in this
+ * DataBuffer.
+ * 
+ * @since Android 1.0
+ */
+public class Raster {
+
+    /**
+     * The DataBuffer of this Raster.
+     */
+    protected DataBuffer dataBuffer;
+
+    /**
+     * The height of this Raster.
+     */
+    protected int height;
+
+    /**
+     * The X coordinate of the upper left pixel in this Raster.
+     */
+    protected int minX;
+
+    /**
+     * The Y coordinate of the upper left pixel in this Raster.
+     */
+    protected int minY;
+
+    /**
+     * The number of bands in this Raster.
+     */
+    protected int numBands;
+
+    /**
+     * The number of data elements.
+     */
+    protected int numDataElements;
+
+    /**
+     * The parent of this Raster.
+     */
+    protected Raster parent;
+
+    /**
+     * The SampleModel of this Raster.
+     */
+    protected SampleModel sampleModel;
+
+    /**
+     * The X translation from the coordinate space of the SampleModel of this
+     * Raster.
+     */
+    protected int sampleModelTranslateX;
+
+    /**
+     * The Y translation from the coordinate space of the SampleModel of this
+     * Raster.
+     */
+    protected int sampleModelTranslateY;
+
+    /**
+     * The width of this Raster.
+     */
+    protected int width;
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * DataBuffer. The number of bands is defined by the length of bandOffsets
+     * or bankIndices arrays.
+     * 
+     * @param dataBuffer
+     *            the specified DataBuffer.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bankIndices
+     *            the bank indices of bands.
+     * @param bandOffsets
+     *            the band offsets of bands.
+     * @param location
+     *            the location which defines the upper left corner of Raster.
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(DataBuffer dataBuffer, int w, int h,
+            int scanlineStride, int bankIndices[], int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        BandedSampleModel sampleModel = new BandedSampleModel(dataType, w, h, scanlineStride,
+                bankIndices, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified data
+     * type. The Data type can be one of the following values: TYPE_BYTE,
+     * TYPE_USHORT, or TYPE_INT.
+     * 
+     * @param dataType
+     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
+     *            TYPE_INT.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bankIndices
+     *            the bank indices of bands.
+     * @param bandOffsets
+     *            the band offsets of bands.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h, int scanlineStride,
+            int bankIndices[], int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int maxOffset = bandOffsets[0];
+        int maxBank = bankIndices[0];
+
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+
+        int numBanks = maxBank + 1;
+        int dataSize = scanlineStride * (h - 1) + w + maxOffset;
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(dataSize, numBanks);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(dataSize, numBanks);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(dataSize, numBanks);
+                break;
+        }
+        return createBandedRaster(data, w, h, scanlineStride, bankIndices, bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified data
+     * type. The Data type can be one of the following values: TYPE_BYTE,
+     * TYPE_USHORT, or TYPE_INT.
+     * 
+     * @param dataType
+     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
+     *            TYPE_INT.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param bands
+     *            the number of bands.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h, int bands,
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1) {
+            // awt.279=bands is less than 1
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.279")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        int bankIndices[] = new int[bands];
+
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = 0;
+            bankIndices[i] = i;
+        }
+        return createBandedRaster(dataType, w, h, w, bankIndices, bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel and the
+     * specified DataBuffer.
+     * 
+     * @param dataBuffer
+     *            the DataBuffer.
+     * @param w
+     *            the width of image data.
+     * @param h
+     *            the height of image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param pixelStride
+     *            the pixel stride of image data.
+     * @param bandOffsets
+     *            the band offsets of bands.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
+            int scanlineStride, int pixelStride, int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        PixelInterleavedSampleModel sampleModel = new PixelInterleavedSampleModel(dataType, w, h,
+                pixelStride, scanlineStride, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel and the
+     * specified data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
+     * 
+     * @param dataType
+     *            the data type of the samples: TYPE_BYTE, TYPE_USHORT, or
+     *            TYPE_INT.
+     * @param w
+     *            the width of image data.
+     * @param h
+     *            the height of image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param pixelStride
+     *            the pixel stride of image data.
+     * @param bandOffsets
+     *            the band offsets of bands.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w, int h,
+            int scanlineStride, int pixelStride, int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+        int size = (h - 1) * scanlineStride + w * pixelStride + minOffset;
+        DataBuffer data = null;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(size);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(size);
+                break;
+        }
+
+        return createInterleavedRaster(data, w, h, scanlineStride, pixelStride, bandOffsets,
+                location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel and the
+     * specified data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
+     * 
+     * @param dataType
+     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
+     * @param w
+     *            the width of image data.
+     * @param h
+     *            the height of image data.
+     * @param bands
+     *            the number of bands.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w, int h, int bands,
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = i;
+        }
+
+        return createInterleavedRaster(dataType, w, h, w * bands, bands, bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel and the
+     * specified DataBuffer.
+     * 
+     * @param dataBuffer
+     *            the DataBuffer.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bandMasks
+     *            the band masks.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int w, int h,
+            int scanlineStride, int bandMasks[], Point location) {
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new RasterFormatException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        SinglePixelPackedSampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
+                scanlineStride, bandMasks);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel and the
+     * specified DataBuffer.
+     * 
+     * @param dataBuffer
+     *            the DataBuffer.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param bitsPerPixel
+     *            the number of bits per pixel.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer, int w, int h,
+            int bitsPerPixel, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        MultiPixelPackedSampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, w, h,
+                bitsPerPixel);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel and the
+     * specified DataBuffer.
+     * 
+     * @param dataType
+     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param bands
+     *            the number of bands.
+     * @param bitsPerBand
+     *            the number of bits per band.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h, int bands,
+            int bitsPerBand, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1 || bitsPerBand < 1) {
+            // awt.27D=bitsPerBand or bands is not greater than zero
+            throw new IllegalArgumentException(Messages.getString("awt.27D")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bitsPerBand * bands > DataBuffer.getDataTypeSize(dataType)) {
+            // awt.27E=The product of bitsPerBand and bands is greater than the
+            // number of bits held by dataType
+            throw new IllegalArgumentException(Messages.getString("awt.27E")); //$NON-NLS-1$
+        }
+
+        if (bands > 1) {
+
+            int bandMasks[] = new int[bands];
+            int mask = (1 << bitsPerBand) - 1;
+
+            for (int i = 0; i < bands; i++) {
+                bandMasks[i] = mask << (bitsPerBand * (bands - 1 - i));
+            }
+
+            return createPackedRaster(dataType, w, h, bandMasks, location);
+        }
+        DataBuffer data = null;
+        int size = ((bitsPerBand * w + DataBuffer.getDataTypeSize(dataType) - 1) / DataBuffer
+                .getDataTypeSize(dataType))
+                * h;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(size);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(size);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(size);
+                break;
+        }
+        return createPackedRaster(data, w, h, bitsPerBand, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel and the
+     * specified DataBuffer.
+     * 
+     * @param dataType
+     *            the data type of samples: TYPE_BYTE, TYPE_USHORT, or TYPE_INT.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param bandMasks
+     *            the band masks.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h, int bandMasks[],
+            Point location) {
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long)location.x + w > Integer.MAX_VALUE || (long)location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer
+            // overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new NullPointerException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(w * h);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(w * h);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(w * h);
+                break;
+        }
+
+        return createPackedRaster(data, w, h, w, bandMasks, location);
+    }
+
+    /**
+     * Creates a Raster object with the specified DataBuffer and SampleModel.
+     * 
+     * @param sm
+     *            the specified SampleModel.
+     * @param db
+     *            the specified DataBuffer.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the Raster.
+     */
+    public static Raster createRaster(SampleModel sm, DataBuffer db, Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new Raster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel and DataBuffer.
+     * 
+     * @param sm
+     *            the specified SampleModel.
+     * @param db
+     *            the specified DataBuffer.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm, DataBuffer db, Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new OrdinaryWritableRaster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel.
+     * 
+     * @param sm
+     *            the specified SampleModel.
+     * @param location
+     *            the location which defines the upper left corner of the
+     *            Raster.
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm, Point location) {
+
+        if (sm == null) {
+            // awt.280=SampleModel is null
+            throw new NullPointerException(Messages.getString("awt.280")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return createWritableRaster(sm, sm.createDataBuffer(), location);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel and
+     * DataBuffer.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param dataBuffer
+     *            the specified DataBuffer.
+     * @param origin
+     *            the specified origin.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
+
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.getWidth(),
+                sampleModel.getHeight()), origin, null);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel,
+     * DataBuffer, rectangular region and parent Raster.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param dataBuffer
+     *            the specified DataBuffer.
+     * @param aRegion
+     *            the a rectangular region which defines the new image bounds.
+     * @param sampleModelTranslate
+     *            this point defines the translation point from the SampleModel
+     *            coordinates to the new Raster coordinates.
+     * @param parent
+     *            the parent of this Raster.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion,
+            Point sampleModelTranslate, Raster parent) {
+
+        if (sampleModel == null || dataBuffer == null || aRegion == null
+                || sampleModelTranslate == null) {
+            // awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate
+            // is null
+            throw new NullPointerException(Messages.getString("awt.281")); //$NON-NLS-1$
+        }
+
+        if (aRegion.width <= 0 || aRegion.height <= 0) {
+            // awt.282=aRegion has width or height less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.282")); //$NON-NLS-1$
+        }
+
+        if ((long)aRegion.x + (long)aRegion.width > Integer.MAX_VALUE) {
+            // awt.283=Overflow X coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.283")); //$NON-NLS-1$
+        }
+
+        if ((long)aRegion.y + (long)aRegion.height > Integer.MAX_VALUE) {
+            // awt.284=Overflow Y coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
+        }
+
+        if (sampleModel instanceof ComponentSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((ComponentSampleModel)sampleModel).getScanlineStride());
+        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((MultiPixelPackedSampleModel)sampleModel).getScanlineStride());
+        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((SinglePixelPackedSampleModel)sampleModel).getScanlineStride());
+        }
+
+        this.sampleModel = sampleModel;
+        this.dataBuffer = dataBuffer;
+        this.minX = aRegion.x;
+        this.minY = aRegion.y;
+        this.width = aRegion.width;
+        this.height = aRegion.height;
+        this.sampleModelTranslateX = sampleModelTranslate.x;
+        this.sampleModelTranslateY = sampleModelTranslate.y;
+        this.parent = parent;
+        this.numBands = sampleModel.getNumBands();
+        this.numDataElements = sampleModel.getNumDataElements();
+
+    }
+
+    /**
+     * Instantiates a new Raster with the specified SampleModel.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param origin
+     *            the origin.
+     */
+    protected Raster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(origin.x, origin.y,
+                sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
+    }
+
+    /**
+     * Creates the child of this Raster by sharing the specified rectangular
+     * area in this raster. The parentX, parentY, width and height parameters
+     * specify the rectangular area to be shared.
+     * 
+     * @param parentX
+     *            the X coordinate of the upper left corner of this Raster.
+     * @param parentY
+     *            the Y coordinate of the upper left corner of this Raster.
+     * @param width
+     *            the width of the child area.
+     * @param height
+     *            the height of the child area.
+     * @param childMinX
+     *            the X coordinate of child area mapped to the parentX
+     *            coordinate.
+     * @param childMinY
+     *            the Y coordinate of child area mapped to the parentY
+     *            coordinate.
+     * @param bandList
+     *            the array of band indices.
+     * @return the Raster.
+     */
+    public Raster createChild(int parentX, int parentY, int width, int height, int childMinX,
+            int childMinY, int bandList[]) {
+        if (width <= 0 || height <= 0) {
+            // awt.285=Width or Height of child Raster is less than or equal to
+            // zero
+            throw new RasterFormatException(Messages.getString("awt.285")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + width > this.minX + this.width) {
+            // awt.286=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.286")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + height > this.minY + this.height) {
+            // awt.287=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.287")); //$NON-NLS-1$
+        }
+
+        if ((long)parentX + width > Integer.MAX_VALUE) {
+            // awt.288=parentX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.288")); //$NON-NLS-1$
+        }
+
+        if ((long)parentY + height > Integer.MAX_VALUE) {
+            // awt.289=parentY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.289")); //$NON-NLS-1$
+        }
+
+        if ((long)childMinX + width > Integer.MAX_VALUE) {
+            // awt.28A=childMinX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28A")); //$NON-NLS-1$
+        }
+
+        if ((long)childMinY + height > Integer.MAX_VALUE) {
+            // awt.28B=childMinY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28B")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new Raster(childModel, dataBuffer,
+                new Rectangle(childMinX, childMinY, width, height), new Point(childTranslateX
+                        + sampleModelTranslateX, childTranslateY + sampleModelTranslateY), this);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters as this
+     * Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster() {
+        return new OrdinaryWritableRaster(sampleModel, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters as this
+     * Raster and the specified size.
+     * 
+     * @param w
+     *            the width of the new WritableRaster.
+     * @param h
+     *            the height of the new WritableRaster.
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
+
+        return new OrdinaryWritableRaster(sm, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters as this
+     * Raster and the specified size and location.
+     * 
+     * @param x
+     *            the X coordinate of the new WritableRaster.
+     * @param y
+     *            the Y coordinate of the new WritableRaster.
+     * @param w
+     *            the width of the new WritableRaster.
+     * @param h
+     *            the height of the new WritableRaster.
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int x, int y, int w, int h) {
+
+        WritableRaster raster = createCompatibleWritableRaster(w, h);
+
+        return raster.createWritableChild(0, 0, w, h, x, y, null);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters as this
+     * Raster and the specified rectangle which determines new WritableRaster's
+     * location and size.
+     * 
+     * @param rect
+     *            the specified Rectangle.
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
+        if (rect == null) {
+            // awt.28C=Rect is null
+            throw new NullPointerException(Messages.getString("awt.28C")); //$NON-NLS-1$
+        }
+
+        return createCompatibleWritableRaster(rect.x, rect.y, rect.width, rect.height);
+    }
+
+    /**
+     * Creates the translated child of this Raster. The New Raster object is a
+     * reference to the this Raster with a different location.
+     * 
+     * @param childMinX
+     *            the X coordinate of the new Raster.
+     * @param childMinY
+     *            the Y coordinate of the new Raster.
+     * @return the Raster.
+     */
+    public Raster createTranslatedChild(int childMinX, int childMinY) {
+        return createChild(minX, minY, width, height, childMinX, childMinY, null);
+    }
+
+    /**
+     * Gets the bounds of this Raster as a rectangle.
+     * 
+     * @return the bounds of this Raster.
+     */
+    public Rectangle getBounds() {
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the DataBuffer associated with this Raster.
+     * 
+     * @return the DataBuffer associated with this Raster.
+     */
+    public DataBuffer getDataBuffer() {
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the data elements which represent the pixel data of the specified
+     * rectangle area as a primitive array. The following image data types are
+     * supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+     * DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param outData
+     *            the resulting array.
+     * @return the data elements of the specified area of this Raster.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, w,
+                h, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the data elements which represent the specified pixel of this Raster
+     * as a primitive array. The following image data types are supported:
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param outData
+     *            the resulting data.
+     * @return the data elements of the specified pixel of this Raster.
+     */
+    public Object getDataElements(int x, int y, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY,
+                outData, dataBuffer);
+    }
+
+    /**
+     * Gets the height of this Raster.
+     * 
+     * @return the height of this Raster.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the minimum X coordinate of this Raster.
+     * 
+     * @return the minimum X coordinate of this Raster.
+     */
+    public final int getMinX() {
+        return minX;
+    }
+
+    /**
+     * Gets the minimum Y coordinate of this Raster.
+     * 
+     * @return the minimum Y coordinate of this Raster.
+     */
+    public final int getMinY() {
+        return minY;
+    }
+
+    /**
+     * Gets the number of bands in this Raster.
+     * 
+     * @return the number of bands in this Raster.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the number of data elements for one pixel.
+     * 
+     * @return the number of data elements for one pixel.
+     */
+    public final int getNumDataElements() {
+        return numDataElements;
+    }
+
+    /**
+     * Gets the parent Raster for this Raster object.
+     * 
+     * @return the parent Raster for this Raster object.
+     */
+    public Raster getParent() {
+        return parent;
+    }
+
+    /**
+     * Gets a double array of samples for the specified pixel in this Raster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param dArray
+     *            the double array where result array will be stored.
+     * @return the double array of samples for the specified pixel in this
+     *         Raster.
+     */
+    public double[] getPixel(int x, int y, double dArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, dArray,
+                dataBuffer);
+    }
+
+    /**
+     * Gets a float array of samples for the specified pixel in this Raster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param fArray
+     *            the float array where the result array will be stored.
+     * @return the float array of samples for the specified pixel in this
+     *         Raster.
+     */
+    public float[] getPixel(int x, int y, float fArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, fArray,
+                dataBuffer);
+    }
+
+    /**
+     * Gets an integer array of samples for the specified pixel in this Raster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param iArray
+     *            the integer array where the result array will be stored.
+     * @return the integer array of samples for the specified pixel in this
+     *         Raster.
+     */
+    public int[] getPixel(int x, int y, int iArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, iArray,
+                dataBuffer);
+    }
+
+    /**
+     * Gets an double array of samples for the specified rectangular area of
+     * pixels in this Raster.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param dArray
+     *            the resulting array.
+     * @return the double array of samples for the specified rectangular area of
+     *         pixels in this Raster.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                dArray, dataBuffer);
+    }
+
+    /**
+     * Gets an float array of samples for the specified rectangular area of
+     * pixels in this Raster.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param fArray
+     *            the resulting array.
+     * @return the float array of samples for the specified rectangular area of
+     *         pixels in this Raster.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an integer array of samples for the specified rectangular area of
+     * pixels in this raster.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of pixel's the area of pixels.
+     * @param h
+     *            the height of pixel's the area of pixels.
+     * @param iArray
+     *            the resulting array.
+     * @return the integer array of samples for the specified rectangular area
+     *         of pixels in this Raster.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified pixel as an
+     * integer.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the band.
+     * @return the sample for the specified band of the specified pixel as an
+     *         integer.
+     */
+    public int getSample(int x, int y, int b) {
+        return sampleModel.getSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
+                dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified pixel as a
+     * double.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the band.
+     * @return the sample for the specified band of the specified pixel as a
+     *         double.
+     */
+    public double getSampleDouble(int x, int y, int b) {
+        return sampleModel.getSampleDouble(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
+                dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified pixel as a float.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the band.
+     * @return the sample for the specified band of the specified pixel as a
+     *         float.
+     */
+    public float getSampleFloat(int x, int y, int b) {
+        return sampleModel.getSampleFloat(x - sampleModelTranslateX, y - sampleModelTranslateY, b,
+                dataBuffer);
+    }
+
+    /**
+     * Gets the SampleModel associated with this Raster.
+     * 
+     * @return the SampleModel associated with this Raster.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets the translation of the X coordinate from the SampleModel coordinate
+     * system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the X coordinate from the
+     *         SampleModel coordinate system to the Rasters's coordinate system.
+     */
+    public final int getSampleModelTranslateX() {
+        return sampleModelTranslateX;
+    }
+
+    /**
+     * Gets the translation of the Y coordinate from the SampleModel coordinate
+     * system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the Y coordinate from the
+     *         SampleModel coordinate system to the Rasters's coordinate system.
+     */
+    public final int getSampleModelTranslateY() {
+        return sampleModelTranslateY;
+    }
+
+    /**
+     * Gets the double array of samples for the specified band of the specified
+     * rectangular area of pixels in this Raster as a double array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular area of pixels.
+     * @param y
+     *            the Y coordinate of the rectangular area of pixels.
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param b
+     *            the band.
+     * @param dArray
+     *            the resulting double array.
+     * @return the double array of samples for the specified band of the
+     *         specified rectangular area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b, double dArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                b, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets the float array of samples for the specified band of the specified
+     * rectangular area of pixels in this Raster as a float array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular area of pixels.
+     * @param y
+     *            the Y coordinate of the rectangular area of pixels.
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param b
+     *            the band.
+     * @param fArray
+     *            the resulting float array.
+     * @return the float array of samples for the specified band of the
+     *         specified rectangular area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                b, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets the integer array of samples for the specified band of the specified
+     * rectangular area of pixels in this Raster as a integer array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular area of pixels.
+     * @param y
+     *            the Y coordinate of the rectangular area of pixels.
+     * @param w
+     *            the width of the rectangular area of pixels.
+     * @param h
+     *            the height of the rectangular area of pixels.
+     * @param b
+     *            the band.
+     * @param iArray
+     *            the resulting integer array.
+     * @return the integer array of samples for the specified band of the
+     *         specified rectangular area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                b, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the transfer type for pixels of this Raster.
+     * 
+     * @see SampleModel#getTransferType()
+     * @return the transfer type for pixels of this Raster.
+     */
+    public final int getTransferType() {
+        return sampleModel.getTransferType();
+    }
+
+    /**
+     * Gets the width of this Raster.
+     * 
+     * @return the width of this Raster.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Validate data buffer.
+     * 
+     * @param dataBuffer
+     *            the data buffer.
+     * @param w
+     *            the w.
+     * @param h
+     *            the h.
+     * @param scanlineStride
+     *            the scanline stride.
+     */
+    private static void validateDataBuffer(final DataBuffer dataBuffer, final int w, final int h,
+            final int scanlineStride) {
+        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
+            // awt.298=dataBuffer is too small
+            throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
+        }
+    }
+}
diff --git a/awt/java/awt/image/RasterFormatException.java b/awt/java/awt/image/RasterFormatException.java
new file mode 100644
index 0000000..c667141
--- /dev/null
+++ b/awt/java/awt/image/RasterFormatException.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$
+ */
+
+package java.awt.image;
+
+/**
+ * The RasterFormatException class represents the exception that is thrown when
+ * there's an invalid layout in the Raster.
+ * 
+ * @since Android 1.0
+ */
+public class RasterFormatException extends RuntimeException {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = 96598996116164315L;
+
+    /**
+     * Instantiates a new RasterFormatException with the specified detail
+     * message.
+     * 
+     * @param s
+     *            the detail message.
+     */
+    public RasterFormatException(String s) {
+        super(s);
+    }
+
+}
diff --git a/awt/java/awt/image/RasterOp.java b/awt/java/awt/image/RasterOp.java
new file mode 100644
index 0000000..19a84c9
--- /dev/null
+++ b/awt/java/awt/image/RasterOp.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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The RasterOp interface provides methods for performing transformations from
+ * source data to destination data for Raster objects. The source and
+ * destination objects should contain the appropriate number of bands for the
+ * particular classes which implement this interface.
+ * 
+ * @since Android 1.0
+ */
+public interface RasterOp {
+
+    /**
+     * Creates a destination WritableRaster with the specified Raster; this
+     * destination image data is empty and has the correct size and number of
+     * bands.
+     * 
+     * @param src
+     *            the source Raster.
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleDestRaster(Raster src);
+
+    /**
+     * Performs a filter operation on the source Raster and stores the resulting
+     * image data to the destination WritableRaster.
+     * 
+     * @param src
+     *            the source Raster.
+     * @param dst
+     *            the destination WritableRaster, where the result is stored.
+     * @return the filtered WritableRaster.
+     */
+    public WritableRaster filter(Raster src, WritableRaster dst);
+
+    /**
+     * Gets the bounds of the filtered Raster.
+     * 
+     * @param src
+     *            the source Raster to be filtered.
+     * @return the rectangle bounds of the filtered Raster.
+     */
+    public Rectangle2D getBounds2D(Raster src);
+
+    /**
+     * Gets the point of the destination image which corresponds to the
+     * specified point in the source raster.
+     * 
+     * @param srcPoint
+     *            the point of the source raster.
+     * @param dstPoint
+     *            the point where the result will be stored.
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint);
+
+    /**
+     * Gets the RenderingHints of the RasterOp.
+     * 
+     * @return the RenderingHints of the RasterOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/RenderedImage.java b/awt/java/awt/image/RenderedImage.java
new file mode 100644
index 0000000..5eafa64
--- /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.
+ * 
+ * @since Android 1.0
+ */
+public interface RenderedImage {
+
+    /**
+     * Gets the property with the specified name from the property set of this
+     * RenderedImage.
+     * 
+     * @param name
+     *            the property's name.
+     * @return the property value corresponded to this property's name.
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Copies the region of this RenderedImage to the specified WritableRaster.
+     * The bounds of the region are the bounds of the WritableRaster.
+     * 
+     * @param raster
+     *            the WritableRaster.
+     * @return the created WritableRaster.
+     */
+    public WritableRaster copyData(WritableRaster raster);
+
+    /**
+     * Gets the image data of the image's region as one tile.
+     * 
+     * @param rect
+     *            the rectangular region of RenderedImage.
+     * @return the image data of the image's region as one tile.
+     */
+    public Raster getData(Rectangle rect);
+
+    /**
+     * Gets all RenderedImage objects which are the source of this RenderedImage
+     * object.
+     * 
+     * @return a Vector of RenderedImage objects which are the source of this
+     *         RenderedImage object or null, if there is no information about
+     *         them.
+     */
+    public Vector<RenderedImage> getSources();
+
+    /**
+     * Gets the set of all property names for this RenderedImage.
+     * 
+     * @return the array of all property names for this RenderedImage.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Gets the SampleModel of this RenderedImage.
+     * 
+     * @return the SampleModel of this RenderedImage.
+     */
+    public SampleModel getSampleModel();
+
+    /**
+     * Gets the tile corresponded to the specified indices in the tile array.
+     * 
+     * @param tileX
+     *            the X index of the tile.
+     * @param tileY
+     *            the Y index of the tile.
+     * @return the tile corresponded to the specified indices in the tile array.
+     */
+    public Raster getTile(int tileX, int tileY);
+
+    /**
+     * Gets the image data of this image as one tile.
+     * 
+     * @return the image data of this image as one tile.
+     */
+    public Raster getData();
+
+    /**
+     * Gets the ColorModel of this RenderedImage.
+     * 
+     * @return the ColorModel of this RenderedImage.
+     */
+    public ColorModel getColorModel();
+
+    /**
+     * Gets the width of the RenderedImage.
+     * 
+     * @return the width of the RenderedImage.
+     */
+    public int getWidth();
+
+    /**
+     * Gets the tile width.
+     * 
+     * @return the tile width in pixels.
+     */
+    public int getTileWidth();
+
+    /**
+     * Gets the tile height.
+     * 
+     * @return the tile height in pixels.
+     */
+    public int getTileHeight();
+
+    /**
+     * Gets the Y offset of the tile grid.
+     * 
+     * @return the Y offset of the tile grid.
+     */
+    public int getTileGridYOffset();
+
+    /**
+     * Gets the X offset of the tile grid.
+     * 
+     * @return the X offset of the tile grid.
+     */
+    public int getTileGridXOffset();
+
+    /**
+     * Gets the number of tiles along Y direction.
+     * 
+     * @return the number of tiles along Y direction.
+     */
+    public int getNumYTiles();
+
+    /**
+     * Gets the number of tiles along X direction.
+     * 
+     * @return the number of tiles along X direction.
+     */
+    public int getNumXTiles();
+
+    /**
+     * Gets the minimum Y coordinate of this RenderedImage.
+     * 
+     * @return the minimum Y coordinate of this RenderedImage.
+     */
+    public int getMinY();
+
+    /**
+     * Gets the minimum X coordinate of this RenderedImage.
+     * 
+     * @return the minimum X coordinate of this RenderedImage.
+     */
+    public int getMinX();
+
+    /**
+     * Gets the minimum tile's index along the Y direction.
+     * 
+     * @return the minimum tile's index along the Y direction.
+     */
+    public int getMinTileY();
+
+    /**
+     * Gets the minimum tile's index along the X direction.
+     * 
+     * @return the minimum tile's index along the X direction.
+     */
+    public int getMinTileX();
+
+    /**
+     * Gets the height of the RenderedImage.
+     * 
+     * @return the height of the RenderedImage.
+     */
+    public int getHeight();
+
+}
diff --git a/awt/java/awt/image/ReplicateScaleFilter.java b/awt/java/awt/image/ReplicateScaleFilter.java
new file mode 100644
index 0000000..51c0f49
--- /dev/null
+++ b/awt/java/awt/image/ReplicateScaleFilter.java
@@ -0,0 +1,225 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ReplicateScaleFilter class scales an source image by replicating rows and
+ * columns of pixels to scale up or omitting rows and columns of pixels to scale
+ * down.
+ * 
+ * @since Android 1.0
+ */
+public class ReplicateScaleFilter extends ImageFilter {
+
+    /**
+     * The width of a source image.
+     */
+    protected int srcWidth;
+
+    /**
+     * The height of a source image.
+     */
+    protected int srcHeight;
+
+    /**
+     * The width of a destination image.
+     */
+    protected int destWidth;
+
+    /**
+     * The height of a destination image.
+     */
+    protected int destHeight;
+
+    /**
+     * The integer array of source rows.
+     */
+    protected int[] srcrows;
+
+    /**
+     * The integer array of source columns.
+     */
+    protected int[] srccols;
+
+    /**
+     * An Object (byte array with a destination width) provides a row of pixel
+     * data to the ImageConsumer.
+     */
+    protected Object outpixbuf;
+
+    /**
+     * Instantiates a new ReplicateScaleFilter that filters the image with the
+     * specified width and height.
+     * 
+     * @param width
+     *            the width of scaled image.
+     * @param height
+     *            the height of scaled image.
+     */
+    public ReplicateScaleFilter(int width, int height) {
+        if (width == 0 || height == 0) {
+            // awt.234=Width or Height equals zero
+            throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$
+        }
+
+        this.destWidth = width;
+        this.destHeight = height;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>)props.clone();
+        }
+        String propName = "Rescale Filters"; //$NON-NLS-1$
+        String prop = "destWidth=" + destWidth + "; " + //$NON-NLS-1$ //$NON-NLS-2$
+                "destHeight=" + destHeight; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    // setPixels methods produce pixels according to Java API Spacification
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+
+        if (srccols == null) {
+            initArrays();
+        }
+        int buff[];
+        if (outpixbuf == null || !(outpixbuf instanceof int[])) {
+            buff = new int[destWidth];
+            outpixbuf = buff;
+        } else {
+            buff = (int[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while ((dy < destHeight) && ((sy = srcrows[dy]) < y + h)) {
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while ((dx < destWidth) && ((sx = srccols[dx]) < x + w)) {
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+
+        if (srccols == null) {
+            initArrays();
+        }
+        byte buff[];
+        if (outpixbuf == null || !(outpixbuf instanceof byte[])) {
+            buff = new byte[destWidth];
+            outpixbuf = buff;
+        } else {
+            buff = (byte[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while ((dy < destHeight) && ((sy = srcrows[dy]) < y + h)) {
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while ((dx < destWidth) && ((sx = srccols[dx]) < x + w)) {
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        srcWidth = w;
+        srcHeight = h;
+
+        if (destWidth < 0 && destHeight < 0) {
+            destWidth = srcWidth;
+            destHeight = srcHeight;
+        } else if (destWidth < 0) {
+            destWidth = destHeight * srcWidth / srcHeight;
+        } else if (destHeight < 0) {
+            destHeight = destWidth * srcHeight / srcWidth;
+        }
+        consumer.setDimensions(destWidth, destHeight);
+    }
+
+    /**
+     * Initialization of srccols and srcrows arrays.
+     */
+    private void initArrays() {
+        if ((destWidth < 0) || (destHeight < 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        srccols = new int[destWidth];
+        int ca = srcWidth >>> 1;
+        for (int i = 0; i < destWidth; i++) {
+            srccols[i] = (i * srcWidth + ca) / destWidth;
+        }
+
+        srcrows = new int[destHeight];
+        int ra = srcHeight >>> 1;
+        for (int i = 0; i < destHeight; i++) {
+            srcrows[i] = (i * srcHeight + ra) / destHeight;
+        }
+    }
+
+}
diff --git a/awt/java/awt/image/RescaleOp.java b/awt/java/awt/image/RescaleOp.java
new file mode 100644
index 0000000..d7e2bd7
--- /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.
+ * 
+ * @since Android 1.0
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp {
+
+    /**
+     * The scale factors.
+     */
+    private float scaleFactors[];
+
+    /**
+     * The offsets.
+     */
+    private float offsets[];
+
+    /**
+     * The hints.
+     */
+    private RenderingHints hints;
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified scale factors and
+     * offsets.
+     * 
+     * @param scaleFactors
+     *            the array of scale factor values.
+     * @param offsets
+     *            the array of offset values.
+     * @param hints
+     *            the RenderingHints or null.
+     */
+    public RescaleOp(float[] scaleFactors, float[] offsets, RenderingHints hints) {
+        int numFactors = Math.min(scaleFactors.length, offsets.length);
+
+        this.scaleFactors = new float[numFactors];
+        this.offsets = new float[numFactors];
+
+        System.arraycopy(scaleFactors, 0, this.scaleFactors, 0, numFactors);
+        System.arraycopy(offsets, 0, this.offsets, 0, numFactors);
+
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified scale factor and
+     * offset.
+     * 
+     * @param scaleFactor
+     *            the scale factor.
+     * @param offset
+     *            the offset.
+     * @param hints
+     *            the RenderingHints or null.
+     */
+    public RescaleOp(float scaleFactor, float offset, RenderingHints hints) {
+        scaleFactors = new float[1];
+        offsets = new float[1];
+
+        scaleFactors[0] = scaleFactor;
+        offsets[0] = offset;
+
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the number of scaling factors.
+     * 
+     * @return the number of scaling factors.
+     */
+    public final int getNumFactors() {
+        return scaleFactors.length;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    /**
+     * Gets the scale factors of this RescaleOp.
+     * 
+     * @param scaleFactors
+     *            the desired scale factors array will be copied to this array.
+     * @return the scale factors array.
+     */
+    public final float[] getScaleFactors(float[] scaleFactors) {
+        if (scaleFactors == null) {
+            scaleFactors = new float[this.scaleFactors.length];
+        }
+
+        int minLength = Math.min(scaleFactors.length, this.scaleFactors.length);
+        System.arraycopy(this.scaleFactors, 0, scaleFactors, 0, minLength);
+        return scaleFactors;
+    }
+
+    /**
+     * Gets the offsets array of this RescaleOp.
+     * 
+     * @param offsets
+     *            the desired offsets array will be copied to this array.
+     * @return the offsets array of this RescaleOp.
+     */
+    public final float[] getOffsets(float[] offsets) {
+        if (offsets == null) {
+            offsets = new float[this.offsets.length];
+        }
+
+        int minLength = Math.min(offsets.length, this.offsets.length);
+        System.arraycopy(this.offsets, 0, offsets, 0, minLength);
+        return offsets;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r = dstCM.isCompatibleSampleModel(src.getSampleModel()) ? src.getRaster()
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight()) : dstCM
+                .createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(dstCM, r, dstCM.isAlphaPremultiplied(), null);
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                // awt.21D=Number of src bands ({0}) does not match number of
+                // dst bands ({1})
+                throw new IllegalArgumentException(Messages.getString("awt.21D", //$NON-NLS-1$
+                        src.getNumBands(), dst.getNumBands()));
+            }
+        }
+
+        if (this.scaleFactors.length != 1 && this.scaleFactors.length != src.getNumBands()) {
+            // awt.21E=Number of scaling constants is not equal to the number of
+            // bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+        if (slowFilter(src, dst, false) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @return the int.
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        SampleModel sm = src.getSampleModel();
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int srcMinX = src.getMinX();
+        int srcMinY = src.getMinY();
+        int dstMinX = dst.getMinX();
+        int dstMinY = dst.getMinY();
+
+        int[] maxValues = new int[numBands];
+        int[] masks = new int[numBands];
+        int[] sampleSizes = sm.getSampleSize();
+
+        for (int i = 0; i < numBands; i++) {
+            maxValues[i] = (1 << sampleSizes[i]) - 1;
+            masks[i] = ~(maxValues[i]);
+        }
+
+        // Processing bounds
+        float[] pixels = null;
+        pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+
+        // Cycle over pixels to be calculated
+        if (skipAlpha) { // Always suppose that alpha channel is the last band
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length;) {
+                    for (int bandIdx = 0; bandIdx < numBands - 1; bandIdx++, i++) {
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            } else {
+                for (int i = 0; i < pixels.length;) {
+                    for (int bandIdx = 0; bandIdx < numBands - 1; bandIdx++, i++) {
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            }
+        } else {
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length;) {
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++) {
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length;) {
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++) {
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, pixels);
+
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (scaleFactors.length == 1 || scaleFactors.length == nComponents - 1) {
+                skipAlpha = true;
+            } else if (scaleFactors.length == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.21E=Number of scaling constants is not equal to the
+                // number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+            }
+        } else if (scaleFactors.length == 1 || scaleFactors.length == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.21E=Number of scaling constants is not equal to the number of
+            // bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, srcCM);
+        } else if (!srcCM.equals(dst.getColorModel())) {
+            // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB
+            // as same
+            if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src.getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                    .getType() == BufferedImage.TYPE_INT_RGB || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
+                finalDst = dst;
+                dst = createCompatibleDestImage(src, srcCM);
+            }
+        }
+
+        // TODO
+        // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType(),
+        // skipAlpha) != 0)
+        if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // Don't forget to pass allocated arrays for levels and values, size should
+    // be numBands*4
+    /**
+     * Creates the levels.
+     * 
+     * @param sm
+     *            the sm.
+     * @param numBands
+     *            the num bands.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @param levels
+     *            the levels.
+     * @param values
+     *            the values.
+     * @param channelsOrder
+     *            the channels order.
+     */
+    private final void createLevels(SampleModel sm, int numBands, boolean skipAlpha, int levels[],
+            int values[], int channelsOrder[]) {
+        // Suppose same sample size for all channels, otherwise use slow filter
+        int maxValue = (1 << sm.getSampleSize(0)) - 1;
+
+        // For simplicity introduce these arrays
+        float extScaleFactors[] = new float[numBands];
+        float extOffsets[] = new float[numBands];
+
+        if (scaleFactors.length != 1) {
+            System.arraycopy(scaleFactors, 0, extScaleFactors, 0, scaleFactors.length);
+            System.arraycopy(offsets, 0, extOffsets, 0, scaleFactors.length);
+        } else {
+            for (int i = 0; i < numBands; i++) {
+                extScaleFactors[i] = scaleFactors[0];
+                extOffsets[i] = offsets[0];
+            }
+        }
+
+        if (skipAlpha) {
+            extScaleFactors[numBands - 1] = 1;
+            extOffsets[numBands - 1] = 0;
+        }
+
+        // Create a levels
+        for (int i = 0; i < numBands; i++) {
+            if (extScaleFactors[i] == 0) {
+                levels[i * 4] = 0;
+                levels[i * 4 + 1] = 0;
+                levels[i * 4 + 2] = maxValue + 1;
+                levels[i * 4 + 3] = maxValue + 1;
+            }
+
+            float minLevel = -extOffsets[i] / extScaleFactors[i];
+            float maxLevel = (maxValue - extOffsets[i]) / extScaleFactors[i];
+
+            if (minLevel < 0) {
+                minLevel = 0;
+            } else if (minLevel > maxValue) {
+                minLevel = maxValue;
+            }
+
+            if (maxLevel < 0) {
+                maxLevel = 0;
+            } else if (maxLevel > maxValue) {
+                maxLevel = maxValue;
+            }
+
+            levels[i * 4] = 0;
+            if (minLevel > maxLevel) {
+                levels[i * 4 + 1] = (int)maxLevel;
+                levels[i * 4 + 2] = (int)minLevel;
+            } else {
+                levels[i * 4 + 1] = (int)minLevel;
+                levels[i * 4 + 2] = (int)maxLevel;
+            }
+            levels[i * 4 + 3] = maxValue + 1;
+
+            // Fill values
+            for (int k = 0; k < 4; k++) {
+                int idx = i * 4 + k;
+                values[idx] = (int)(extScaleFactors[i] * levels[idx] + extOffsets[i]);
+                if (values[idx] < 0) {
+                    values[idx] = 0;
+                } else if (values[idx] > maxValue) {
+                    values[idx] = maxValue;
+                }
+            }
+        }
+
+        // Reorder data if channels are stored in different order
+        if (channelsOrder != null) {
+            int len = numBands * 4;
+            int savedLevels[] = new int[len];
+            int savedValues[] = new int[len];
+            System.arraycopy(levels, 0, savedLevels, 0, len);
+            System.arraycopy(values, 0, savedValues, 0, len);
+            for (int i = 0; i < channelsOrder.length; i++) {
+                System.arraycopy(savedLevels, i * 4, levels, channelsOrder[i] * 4, 4);
+                System.arraycopy(savedValues, i * 4, values, channelsOrder[i] * 4, 4);
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src
+     *            the src.
+     * @param dst
+     *            the dst.
+     * @param imageType
+     *            the image type.
+     * @param skipAlpha
+     *            the skip alpha.
+     * @return the int.
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(Raster src, WritableRaster dst, int imageType, boolean skipAlpha) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                channelsOrder = new int[] {
+                        2, 1, 0, 3
+                };
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth() * 4;
+                dstStride = dst.getWidth() * 4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth() * 3;
+                dstStride = dst.getWidth() * 3;
+                channelsOrder = new int[] {
+                        2, 1, 0
+                };
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (srcSM instanceof PixelInterleavedSampleModel
+                        && dstSM instanceof PixelInterleavedSampleModel) {
+                    // Check PixelInterleavedSampleModel
+                    if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
+                            || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1,
+                    // 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel)srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel)dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel)srcSM).getBandOffsets();
+                } else if (srcSM instanceof SinglePixelPackedSampleModel
+                        && dstSM instanceof SinglePixelPackedSampleModel) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel)srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel)dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                    // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (sppsm1.getDataType() != DataBuffer.TYPE_INT
+                            || sppsm2.getDataType() != DataBuffer.TYPE_INT
+                            || !(channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (!Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
+                            || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i = 0; i < channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i = 0; i < channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be
+                        // optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0
+                            || dst.getSampleModelTranslateX() != 0
+                            || dst.getSampleModelTranslateY() != 0) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = new int[4 * channels];
+        int values[] = new int[4 * channels];
+
+        createLevels(src.getSampleModel(), channels, skipAlpha, levels, values, channelsOrder);
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = LookupOp.ippLUT(srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst
+                .getWidth(), dst.getHeight(), dstStride, levels, values, channels, offsets, true);
+
+        return res;
+    }
+}
diff --git a/awt/java/awt/image/SampleModel.java b/awt/java/awt/image/SampleModel.java
new file mode 100644
index 0000000..c967fa6
--- /dev/null
+++ b/awt/java/awt/image/SampleModel.java
@@ -0,0 +1,1166 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SampleModel class is abstract class for retrieving pixel's samples in the
+ * data of an image. Each pixel contains several samples. A sample is the set of
+ * values of the bands for single pixel. For example, each pixel in the RGB
+ * model contains three samples and there are three corresponding bands in the
+ * image data of such pixels representing red, green and blue components.
+ * <p>
+ * The image data is represented as a Raster with a DataBuffer and a
+ * SampleModel. The SampleModel allows access to the samples in the DataBuffer.
+ * 
+ * @since Android 1.0
+ */
+public abstract class SampleModel {
+
+    /**
+     * The width of the image data which this SampleModel describes.
+     */
+    protected int width;
+
+    /**
+     * The height of the image data which this SampleModel describes.
+     */
+    protected int height;
+
+    /**
+     * The number of bands of image data which this SampleModel describes.
+     */
+    protected int numBands;
+
+    /**
+     * The data type of the image data which this SampleModel describes.
+     */
+    protected int dataType;
+
+    /**
+     * Instantiates a new SampleModel with the specified data type, width,
+     * height and number of bands.
+     * 
+     * @param dataType
+     *            the data type of the image data.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param numBands
+     *            the number of bands of the image data.
+     */
+    public SampleModel(int dataType, int w, int h, int numBands) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        double squre = ((double)w) * ((double)h);
+        if (squre >= Integer.MAX_VALUE) {
+            // awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+            throw new IllegalArgumentException(Messages.getString("awt.22F")); //$NON-NLS-1$
+        }
+
+        if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_DOUBLE
+                && dataType != DataBuffer.TYPE_UNDEFINED) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (numBands < 1) {
+            // awt.231=Number of bands must be more then 0
+            throw new IllegalArgumentException(Messages.getString("awt.231")); //$NON-NLS-1$
+        }
+
+        this.dataType = dataType;
+        this.width = w;
+        this.height = h;
+        this.numBands = numBands;
+
+    }
+
+    /**
+     * Gets the data array for the specified pixel of the specified DataBuffer
+     * with one of the following types: DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param obj
+     *            the Object is a data where the result will be stored.
+     * @param data
+     *            the image data.
+     * @return the data array for the specified pixel of the specified
+     *         DataBuffer.
+     */
+    public abstract Object getDataElements(int x, int y, Object obj, DataBuffer data);
+
+    /**
+     * Gets the array of pixel data for the specified rectangular area of pixels
+     * of the specified DataBuffer with one of the following types:
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the rectangular pixel area.
+     * @param y
+     *            the Y coordinate of the rectangular pixel area.
+     * @param w
+     *            the width of the rectangular pixel area.
+     * @param h
+     *            the height of the rectangular pixel area.
+     * @param obj
+     *            the Object is an array with the primitive type, where the
+     *            result array will be stored.
+     * @param data
+     *            the image data.
+     * @return the array of pixel data for the specified rectangular area of
+     *         pixels of the specified DataBuffer object.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                byte bdata[];
+                byte bbuf[] = null;
+
+                if (obj == null) {
+                    bdata = new byte[numDataElements * w * h];
+                } else {
+                    bdata = (byte[])obj;
+                }
+
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        bbuf = (byte[])getDataElements(j, i, bbuf, data);
+                        for (int n = 0; n < numDataElements; n++) {
+                            bdata[idx++] = bbuf[n];
+                        }
+                    }
+                }
+                obj = bdata;
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                short sdata[];
+                short sbuf[] = null;
+
+                if (obj == null) {
+                    sdata = new short[numDataElements * w * h];
+                } else {
+                    sdata = (short[])obj;
+                }
+
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        sbuf = (short[])getDataElements(j, i, sbuf, data);
+                        for (int n = 0; n < numDataElements; n++) {
+                            sdata[idx++] = sbuf[n];
+                        }
+                    }
+                }
+                obj = sdata;
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int idata[];
+                int ibuf[] = null;
+
+                if (obj == null) {
+                    idata = new int[numDataElements * w * h];
+                } else {
+                    idata = (int[])obj;
+                }
+
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        ibuf = (int[])getDataElements(j, i, ibuf, data);
+                        for (int n = 0; n < numDataElements; n++) {
+                            idata[idx++] = ibuf[n];
+                        }
+                    }
+                }
+                obj = idata;
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fdata[];
+                float fbuf[] = null;
+
+                if (obj == null) {
+                    fdata = new float[numDataElements * w * h];
+                } else {
+                    fdata = (float[])obj;
+                }
+
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        fbuf = (float[])getDataElements(j, i, fbuf, data);
+                        for (int n = 0; n < numDataElements; n++) {
+                            fdata[idx++] = fbuf[n];
+                        }
+                    }
+                }
+                obj = fdata;
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double ddata[];
+                double dbuf[] = null;
+
+                if (obj == null) {
+                    ddata = new double[numDataElements * w * h];
+                } else {
+                    ddata = (double[])obj;
+                }
+
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        dbuf = (double[])getDataElements(j, i, dbuf, data);
+                        for (int n = 0; n < numDataElements; n++) {
+                            ddata[idx++] = dbuf[n];
+                        }
+                    }
+                }
+                obj = ddata;
+                break;
+
+        }
+
+        return obj;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer from a
+     * primitive array with one of the following types: DataBuffer.TYPE_BYTE,
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param obj
+     *            the Object - the array of primitive pixel data to be set.
+     * @param data
+     *            the image data.
+     */
+    public abstract void setDataElements(int x, int y, Object obj, DataBuffer data);
+
+    /**
+     * Sets the data elements for a rectangular area of pixels in the specified
+     * DataBuffer from a primitive array with one of the following types:
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+     * DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the specified rectangular area.
+     * @param y
+     *            the Y coordinate of the specified rectangular area.
+     * @param w
+     *            the width of rectangle.
+     * @param h
+     *            the height of rectangle.
+     * @param obj
+     *            the Object - the array of primitive pixel data to be set.
+     * @param data
+     *            the image data.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object obj, DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                byte bbuf[] = new byte[numDataElements];
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        for (int n = 0; n < numDataElements; n++) {
+                            bbuf[n] = ((byte[])obj)[idx++];
+                        }
+                        setDataElements(j, i, bbuf, data);
+                    }
+                }
+
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                short sbuf[] = new short[numDataElements];
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        for (int n = 0; n < numDataElements; n++) {
+                            sbuf[n] = ((short[])obj)[idx++];
+                        }
+                        setDataElements(j, i, sbuf, data);
+                    }
+                }
+                break;
+
+            case DataBuffer.TYPE_INT:
+                int ibuf[] = new int[numDataElements];
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        for (int n = 0; n < numDataElements; n++) {
+                            ibuf[n] = ((int[])obj)[idx++];
+                        }
+                        setDataElements(j, i, ibuf, data);
+                    }
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fbuf[] = new float[numDataElements];
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        for (int n = 0; n < numDataElements; n++) {
+                            fbuf[n] = ((float[])obj)[idx++];
+                        }
+                        setDataElements(j, i, fbuf, data);
+                    }
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dbuf[] = new double[numDataElements];
+                for (int i = y; i < y + h; i++) {
+                    for (int j = x; j < x + w; j++) {
+                        for (int n = 0; n < numDataElements; n++) {
+                            dbuf[n] = ((double[])obj)[idx++];
+                        }
+                        setDataElements(j, i, dbuf, data);
+                    }
+                }
+                break;
+
+        }
+    }
+
+    /**
+     * Creates a new SampleModel with the specified bands of this SampleModel.
+     * 
+     * @param bands
+     *            the array of bands from this SampleModel.
+     * @return the SampleModel with the specified bands of this SampleModel.
+     */
+    public abstract SampleModel createSubsetSampleModel(int bands[]);
+
+    /**
+     * Creates the SampleModel which has the same data as in this SampleModel
+     * with a different width and height.
+     * 
+     * @param a0
+     *            the width of the image data.
+     * @param a1
+     *            the height of the image data.
+     * @return the SampleModel which has the same data as in this SampleModel
+     *         with a different width and height.
+     */
+    public abstract SampleModel createCompatibleSampleModel(int a0, int a1);
+
+    /**
+     * Gets the samples of the specified pixel as an integer array.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param iArray
+     *            the integer array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the integer array with the samples of the specified pixel.
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a integer array of samples.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param iArray
+     *            the integer array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a float array.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param fArray
+     *            the float array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the float array with the samples of the specified pixel.
+     */
+    public float[] getPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixel[];
+
+        if (fArray == null) {
+            pixel = new float[numBands];
+        } else {
+            pixel = fArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleFloat(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a float array of samples.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param fArray
+     *            the float array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, fArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a double array.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param dArray
+     *            the double array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the double array with the samples of the specified pixel.
+     */
+    public double[] getPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixel[];
+
+        if (dArray == null) {
+            pixel = new double[numBands];
+        } else {
+            pixel = dArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleDouble(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a double array of samples.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param dArray
+     *            the double array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, dArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel as an
+     * integer.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param b
+     *            the specified band.
+     * @param data
+     *            the image data.
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+    /**
+     * Gets the sample of a specified band for the specified pixel as a float.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param b
+     *            the specified band.
+     * @param data
+     *            the image data.
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel as a double.
+     * 
+     * @param x
+     *            the X coordinate of pixel.
+     * @param y
+     *            the Y coordinate of pixel.
+     * @param b
+     *            the specified band.
+     * @param data
+     *            the image data.
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels as an
+     * integer array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param iArray
+     *            the integer array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the integer array with the samples of the specified rectangular
+     *         area of pixels.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[];
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the
+     * DataBuffer from an integer array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param iArray
+     *            the integer array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels as a float
+     * array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param fArray
+     *            the float array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the float array with the samples of the specified rectangular
+     *         area of pixels.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixels[];
+        int idx = 0;
+
+        if (fArray == null) {
+            pixels = new float[w * h * numBands];
+        } else {
+            pixels = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleFloat(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the
+     * DataBuffer from a float array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param fArray
+     *            the float array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, fArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels as a double
+     * array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param dArray
+     *            the double array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the double array with the samples of the specified rectangular
+     *         area of pixels.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixels[];
+        int idx = 0;
+
+        if (dArray == null) {
+            pixels = new double[w * h * numBands];
+        } else {
+            pixels = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleDouble(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the
+     * DataBuffer from a double array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param dArray
+     *            the double array.
+     * @param data
+     *            the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, dArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel in the
+     * DataBuffer as integer value.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample as an integer value.
+     * @param data
+     *            the image data.
+     */
+    public abstract void setSample(int x, int y, int b, int s, DataBuffer data);
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular area of
+     * pixels as a integer array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param iArray
+     *            the integer array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the samples of a specified band for a specified rectangular area
+     *         of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an integer array in the specified band for the
+     * specified rectangle of pixels.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param iArray
+     *            the integer array.
+     * @param data
+     *            the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular area of
+     * pixels as a float array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param fArray
+     *            the float array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the samples of a specified band for a specified rectangular area
+     *         of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[], DataBuffer data) {
+        float samples[];
+        int idx = 0;
+
+        if (fArray == null) {
+            samples = new float[w * h];
+        } else {
+            samples = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleFloat(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an float array in the specified band for the
+     * specified rectangle of pixels.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param fArray
+     *            the float array.
+     * @param data
+     *            the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[], DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, fArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular area of
+     * pixels as a double array.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param dArray
+     *            the double array where result will be stored.
+     * @param data
+     *            the image data.
+     * @return the samples of a specified band for a specified rectangular area
+     *         of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b, double dArray[], DataBuffer data) {
+        double samples[];
+        int idx = 0;
+
+        if (dArray == null) {
+            samples = new double[w * h];
+        } else {
+            samples = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleDouble(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an double array in the specified band for the
+     * specified rectangle of pixels.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle.
+     * @param y
+     *            the Y coordinate of the rectangle.
+     * @param w
+     *            the width of the rectangle.
+     * @param h
+     *            the height of the rectangle.
+     * @param b
+     *            the specified band.
+     * @param dArray
+     *            the double array.
+     * @param data
+     *            the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[], DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, dArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel in the
+     * DataBuffer as float value.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample as float value.
+     * @param data
+     *            the image data.
+     */
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        setSample(x, y, b, (int)s, data);
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel in the
+     * DataBuffer as double value.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample as double value.
+     * @param data
+     *            the image data.
+     */
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        setSample(x, y, b, (int)s, data);
+    }
+
+    /**
+     * Creates a DataBuffer object which corresponds to the SampleModel.
+     * 
+     * @return the DataBuffer object which corresponds to the SampleModel.
+     */
+    public abstract DataBuffer createDataBuffer();
+
+    /**
+     * Gets the sample size in bits for the specified band.
+     * 
+     * @param band
+     *            the specified band.
+     * @return the sample size in bits for the specified band.
+     */
+    public abstract int getSampleSize(int band);
+
+    /**
+     * Gets an array of the sample size in bits for all bands.
+     * 
+     * @return an array of the sample size in bits for all bands.
+     */
+    public abstract int[] getSampleSize();
+
+    /**
+     * Gets the width of the image data of this SampleModel object.
+     * 
+     * @return the width of the image data of this SampleModel object.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the transfer type used to transfer pixels via the getDataElements
+     * and setDataElements methods. Transfer type value can be one of the
+     * predefined type from DataBuffer class or not.
+     * 
+     * @return the transfer type.
+     */
+    public int getTransferType() {
+        return dataType;
+    }
+
+    /**
+     * Returns the number of data elements for pixel transferring via the
+     * getDataElements and setDataElements methods.
+     * 
+     * @return the number of data elements for pixel transferring via the
+     *         getDataElements and setDataElements methods.
+     */
+    public abstract int getNumDataElements();
+
+    /**
+     * Gets the number of bands in the image data of this SampleModel object.
+     * 
+     * @return the number of bands in the image data of this SampleModel object.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the height of the image data of this SampleModel object.
+     * 
+     * @return the height of the image data of this SampleModel object.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the data type of image data of this SampleModel object.
+     * 
+     * @return the data type of image data of this SampleModel object.
+     */
+    public final int getDataType() {
+        return dataType;
+    }
+
+}
diff --git a/awt/java/awt/image/ShortLookupTable.java b/awt/java/awt/image/ShortLookupTable.java
new file mode 100644
index 0000000..4319d58
--- /dev/null
+++ b/awt/java/awt/image/ShortLookupTable.java
@@ -0,0 +1,137 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ShortLookupTable class provides provides functionality for lookup
+ * operations, and is defined by an input short array for bands or components of
+ * image and an offset value. The offset value will be subtracted from the input
+ * values before indexing the input arrays. The output of a lookup operation is
+ * represented as an unsigned short array.
+ * 
+ * @since Android 1.0
+ */
+public class ShortLookupTable extends LookupTable {
+
+    /**
+     * The data.
+     */
+    private short data[][];
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value and
+     * the specified short array which represents lookup table for all bands.
+     * 
+     * @param offset
+     *            the offset value.
+     * @param data
+     *            the data array.
+     */
+    public ShortLookupTable(int offset, short[] data) {
+        super(offset, 1);
+        this.data = new short[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value and
+     * the specified short array of arrays which represents lookup table for
+     * each band.
+     * 
+     * @param offset
+     *            the offset value.
+     * @param data
+     *            the data array of arrays for each band.
+     */
+    public ShortLookupTable(int offset, short[][] data) {
+        super(offset, data.length);
+        this.data = new short[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ShortLookupTable object. If this
+     * ShortLookupTable object has one short array for all bands, the returned
+     * array length is one.
+     * 
+     * @return the lookup table of this ShortLookupTable object.
+     */
+    public final short[][] getTable() {
+        return data;
+    }
+
+    /**
+     * Returns a short array which contains samples of the specified pixel which
+     * is translated with the lookup table of this ShortLookupTable object. The
+     * resulted array is stored to the dst array.
+     * 
+     * @param src
+     *            the source array.
+     * @param dst
+     *            the destination array where the result can be stored.
+     * @return the short array of translated samples of a pixel.
+     */
+    public short[] lookupPixel(short[] src, short[] dst) {
+        if (dst == null) {
+            dst = new short[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i] - offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i] - offset];
+            }
+        }
+
+        return dst;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i] - offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i] - offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/SinglePixelPackedSampleModel.java b/awt/java/awt/image/SinglePixelPackedSampleModel.java
new file mode 100644
index 0000000..69f3353
--- /dev/null
+++ b/awt/java/awt/image/SinglePixelPackedSampleModel.java
@@ -0,0 +1,519 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SinglePixelPackedSampleModel class represents pixel data where several
+ * samples combine to create a single pixel and are stored in a single data
+ * array element. This class supports TYPE_BYTE, TYPE_USHORT, TYPE_INT data
+ * types.
+ * 
+ * @since Android 1.0
+ */
+public class SinglePixelPackedSampleModel extends SampleModel {
+
+    /**
+     * The bit masks.
+     */
+    private int bitMasks[];
+
+    /**
+     * The bit offsets.
+     */
+    private int bitOffsets[];
+
+    /**
+     * The bit sizes.
+     */
+    private int bitSizes[];
+
+    /**
+     * The scanline stride.
+     */
+    private int scanlineStride;
+
+    /**
+     * The max bit size.
+     */
+    private int maxBitSize;
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType
+     *            the data type of samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param bitMasks
+     *            the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h, int bitMasks[]) {
+        this(dataType, w, h, w, bitMasks);
+    }
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType
+     *            the data type of the samples.
+     * @param w
+     *            the width of the image data.
+     * @param h
+     *            the height of the image data.
+     * @param scanlineStride
+     *            the scanline stride of the image data.
+     * @param bitMasks
+     *            the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h, int scanlineStride,
+            int bitMasks[]) {
+
+        super(dataType, w, h, bitMasks.length);
+
+        if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        this.bitMasks = bitMasks.clone();
+        this.bitOffsets = new int[this.numBands];
+        this.bitSizes = new int[this.numBands];
+
+        this.maxBitSize = 0;
+
+        for (int i = 0; i < this.numBands; i++) {
+            int offset = 0;
+            int size = 0;
+            int mask = bitMasks[i];
+
+            if (mask != 0) {
+                while ((mask & 1) == 0) {
+                    mask >>>= 1;
+                    offset++;
+                }
+
+                while ((mask & 1) == 1) {
+                    mask >>>= 1;
+                    size++;
+                }
+
+                if (mask != 0) {
+                    // awt.62=Wrong mask : {0}
+                    throw new IllegalArgumentException(Messages.getString("awt.62", bitMasks[i])); //$NON-NLS-1$
+                }
+            }
+
+            this.bitOffsets[i] = offset;
+            this.bitSizes[i] = size;
+
+            if (this.maxBitSize < size) {
+                this.maxBitSize = size;
+            }
+
+        }
+
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                byte bdata[];
+                if (obj == null) {
+                    bdata = new byte[1];
+                } else {
+                    bdata = (byte[])obj;
+                }
+
+                bdata[0] = (byte)data.getElem(y * scanlineStride + x);
+                obj = bdata;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short sdata[];
+                if (obj == null) {
+                    sdata = new short[1];
+                } else {
+                    sdata = (short[])obj;
+                }
+
+                sdata[0] = (short)data.getElem(y * scanlineStride + x);
+                obj = sdata;
+                break;
+            case DataBuffer.TYPE_INT:
+                int idata[];
+                if (obj == null) {
+                    idata = new int[1];
+                } else {
+                    idata = (int[])obj;
+                }
+
+                idata[0] = data.getElem(y * scanlineStride + x);
+                obj = idata;
+                break;
+        }
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                data.setElem(y * scanlineStride + x, ((byte[])obj)[0] & 0xff);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data.setElem(y * scanlineStride + x, ((short[])obj)[0] & 0xffff);
+                break;
+            case DataBuffer.TYPE_INT:
+                data.setElem(y * scanlineStride + x, ((int[])obj)[0]);
+                break;
+        }
+    }
+
+    /**
+     * Compares this SinglePixelPackedSampleModel object with the specified
+     * object.
+     * 
+     * @param o
+     *            the Object to be compared.
+     * @return true, if this SinglePixelPackedSampleModel object is equal to the
+     *         specified object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel)o;
+        return this.width == model.width && this.height == model.height
+                && this.numBands == model.numBands && this.dataType == model.dataType
+                && Arrays.equals(this.bitMasks, model.bitMasks)
+                && Arrays.equals(this.bitOffsets, model.bitOffsets)
+                && Arrays.equals(this.bitSizes, model.bitSizes)
+                && this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the
+            // number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int masks[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            masks[i] = this.bitMasks[bands[i]];
+        }
+        return new SinglePixelPackedSampleModel(this.dataType, this.width, this.height,
+                this.scanlineStride, masks);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(this.dataType, w, h, this.bitMasks);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[this.numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < this.numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < this.numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int sample = data.getElem(y * scanlineStride + x);
+        return ((sample & this.bitMasks[b]) >>> this.bitOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
+                || ((long)y + (long)h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int pixels[];
+
+        if (iArray == null) {
+            pixels = new int[w * h * this.numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
+                || ((long)y + (long)h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int tmp = data.getElem(y * scanlineStride + x);
+        tmp &= ~this.bitMasks[b];
+        tmp |= (s << this.bitOffsets[b]) & this.bitMasks[b];
+        data.setElem(y * scanlineStride + x, tmp);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
+                || ((long)y + (long)h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[], DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long)x + (long)w > this.width)
+                || ((long)y + (long)h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(x + j, y + i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = (this.height - 1) * scanlineStride + width;
+
+        switch (this.dataType) {
+            case DataBuffer.TYPE_BYTE:
+                data = new DataBufferByte(size);
+                break;
+            case DataBuffer.TYPE_USHORT:
+                data = new DataBufferUShort(size);
+                break;
+            case DataBuffer.TYPE_INT:
+                data = new DataBufferInt(size);
+                break;
+        }
+        return data;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x
+     *            the X coordinate of the specified pixel.
+     * @param y
+     *            the Y coordinate of the specified pixel.
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return (y * scanlineStride + x);
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return bitSizes[band];
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        return bitSizes.clone();
+    }
+
+    /**
+     * Gets an array of the bit offsets of the data array elements.
+     * 
+     * @return an array of the bit offsets.
+     */
+    public int[] getBitOffsets() {
+        return bitOffsets.clone();
+    }
+
+    /**
+     * Gets an array of the bit masks for all bands.
+     * 
+     * @return an array of the bit masks for all bands.
+     */
+    public int[] getBitMasks() {
+        return bitMasks.clone();
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bitMasks) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitSizes) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride.
+     * 
+     * @return the scanline stride
+     */
+    public int getScanlineStride() {
+        return this.scanlineStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+}
diff --git a/awt/java/awt/image/TileObserver.java b/awt/java/awt/image/TileObserver.java
new file mode 100644
index 0000000..7dd97e2
--- /dev/null
+++ b/awt/java/awt/image/TileObserver.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.image;
+
+/**
+ * An asynchronous update interface for receiving notifications about tile
+ * information when tiles of a WritableRenderedImage become modifiable or
+ * unmodifiable.
+ * 
+ * @since Android 1.0
+ */
+public interface TileObserver {
+
+    /**
+     * This method is called when information about a tile update is available.
+     * 
+     * @param source
+     *            the source image.
+     * @param tileX
+     *            the X index of the tile.
+     * @param tileY
+     *            the Y index of the tile.
+     * @param willBeWritable
+     *            parameter which indicates whether the tile will be grabbed for
+     *            writing or be released.
+     */
+    public void tileUpdate(WritableRenderedImage source, int tileX, int tileY,
+            boolean willBeWritable);
+
+}
diff --git a/awt/java/awt/image/VolatileImage.java b/awt/java/awt/image/VolatileImage.java
new file mode 100644
index 0000000..f24e866
--- /dev/null
+++ b/awt/java/awt/image/VolatileImage.java
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.ImageCapabilities;
+import java.awt.Transparency;
+
+/**
+ * The VolatileImage abstract class represents an image which can lose its
+ * contents at any point. VolatileImage objects are device specific. This class
+ * provides methods for checking if operation of this image are compatible for
+ * the GraphicsConfiguration.
+ * 
+ * @since Android 1.0
+ */
+public abstract class VolatileImage extends Image
+// Volatile image implements Transparency since 1.5
+        implements Transparency {
+
+    /**
+     * The Constant IMAGE_INCOMPATIBLE indicates that this VolatileImage is not
+     * applicable for the GraphicsConfiguration object.
+     */
+    public static final int IMAGE_INCOMPATIBLE = 2;
+
+    /**
+     * The Constant IMAGE_OK indicates that VolatileImage is ready for using.
+     */
+    public static final int IMAGE_OK = 0;
+
+    /**
+     * The Constant IMAGE_RESTORED indicates that VolatileImage will be ready to
+     * use after restoring.
+     */
+    public static final int IMAGE_RESTORED = 1;
+
+    /**
+     * The transparency value of this image.
+     */
+    protected int transparency = OPAQUE;
+
+    /**
+     * Instantiates a new VolatileImage object.
+     */
+    public VolatileImage() {
+        super();
+    }
+
+    /**
+     * Returns true if rendering data is lost during validating. This method
+     * should be called after rendering operation of image.
+     * 
+     * @return true, if contents lost during validating, false otherwise.
+     */
+
+    public abstract boolean contentsLost();
+
+    /**
+     * Creates a Graphics2D used to draw in this VolatileImage.
+     * 
+     * @return the Graphics2D object.
+     */
+    public abstract Graphics2D createGraphics();
+
+    /**
+     * Gets the ImageCapabilities of this VolatileImage.
+     * 
+     * @return the ImageCapabilities of this VolatileImage.
+     */
+    public abstract ImageCapabilities getCapabilities();
+
+    /**
+     * Gets the height of this VolatileImage.
+     * 
+     * @return the height of this VolatileImage.
+     */
+    public abstract int getHeight();
+
+    /**
+     * Gets a BufferedImage representation of current VolatileImage that won't
+     * be affected by any changes to this VolatileImage.
+     * 
+     * @return a BufferedImage representation of current VolatileImage.
+     */
+    public abstract BufferedImage getSnapshot();
+
+    /**
+     * Gets the width of this VolatileImage.
+     * 
+     * @return the width of this VolatileImage.
+     */
+    public abstract int getWidth();
+
+    /**
+     * Validates the drawing surface of the image if the surface had been lost
+     * and if the specified GraphicsConfiguration object is applicable to this
+     * image.
+     * 
+     * @param gc
+     *            the GraphicsConfiguration object.
+     * @return one of the image status constants: IMAGE_OK, IMAGE_RESTORED or
+     *         IMAGE_INCOMPATIBLE.
+     */
+    public abstract int validate(GraphicsConfiguration gc);
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return getSnapshot().getSource();
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+}
diff --git a/awt/java/awt/image/WritableRaster.java b/awt/java/awt/image/WritableRaster.java
new file mode 100644
index 0000000..51366ee
--- /dev/null
+++ b/awt/java/awt/image/WritableRaster.java
@@ -0,0 +1,592 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The WritableRaster class provides functionality for writing samples and pixel
+ * capabilities to the Raster.
+ * 
+ * @since Android 1.0
+ */
+public class WritableRaster extends Raster {
+
+    /**
+     * Instantiates a new WritableRaster object with the specified SampleModel,
+     * DataBuffer, rectangular region and parent WritableRaster.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param dataBuffer
+     *            the specified DataBuffer.
+     * @param aRegion
+     *            the rectangular region which defines the new image bounds.
+     * @param sampleModelTranslate
+     *            this point defines the translation point from the SampleModel
+     *            to the new WritableRaster coordinates.
+     * @param parent
+     *            the parent of this WritableRaster.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion,
+            Point sampleModelTranslate, WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    /**
+     * Instantiates a new WritableRaster object with the specified SampleModel
+     * which defines a layout of this WritableRaster and DataBuffer objects
+     * which defines the image data.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param dataBuffer
+     *            the specified DataBuffer.
+     * @param origin
+     *            the point of origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.width,
+                sampleModel.height), origin, null);
+    }
+
+    /**
+     * Instantiates a new WritableRaster with the specified SampleModel.
+     * 
+     * @param sampleModel
+     *            the specified SampleModel.
+     * @param origin
+     *            the origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(origin.x, origin.y,
+                sampleModel.width, sampleModel.height), origin, null);
+    }
+
+    /**
+     * Sets the data for a single pixel from an input Object which represents an
+     * array of primitive types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+     * DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param inData
+     *            the input data.
+     */
+    public void setDataElements(int x, int y, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, inData,
+                dataBuffer);
+    }
+
+    /**
+     * Sets the data elements which represent pixel data to the specified
+     * rectangle area as a primitive array. The following image data types are
+     * supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+     * DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x
+     *            the X coordinate of the rectangle of pixels.
+     * @param y
+     *            the Y coordinate of the rectangle of pixels.
+     * @param w
+     *            the width of the rectangle of pixels.
+     * @param h
+     *            the height of the rectangle of pixels.
+     * @param inData
+     *            the array of primitive type data to be set to the specified
+     *            area.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h,
+                inData, dataBuffer);
+    }
+
+    /**
+     * Creates the child of this WritableRaster by sharing the specified
+     * rectangular area in this WritableRaster. The parentX, parentY, width and
+     * height parameters specify rectangular area to be shared.
+     * 
+     * @param parentX
+     *            the X coordinate of the upper left corner of the shared
+     *            rectangle with respect to this WritableRaster' coordinates.
+     * @param parentY
+     *            the Y coordinate of the upper left corner of the shared
+     *            rectangle with respect to this WritableRaster' coordinates.
+     * @param w
+     *            the width of the child area.
+     * @param h
+     *            the height of the child area.
+     * @param childMinX
+     *            the X coordinate of child area mapped to the parentX
+     *            coordinate.
+     * @param childMinY
+     *            the Y coordinate of child area mapped to the parentY
+     *            coordinate.
+     * @param bandList
+     *            the array of band indices.
+     * @return the child WritableRaster.
+     */
+    public WritableRaster createWritableChild(int parentX, int parentY, int w, int h,
+            int childMinX, int childMinY, int bandList[]) {
+        if (w <= 0 || h <= 0) {
+            // awt.244=Width or Height of child Raster is less than or equal to
+            // zero
+            throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + w > this.minX + this.width) {
+            // awt.245=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + h > this.minY + this.height) {
+            // awt.246=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$
+        }
+
+        if ((long)parentX + w > Integer.MAX_VALUE) {
+            // awt.247=parentX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$
+        }
+
+        if ((long)parentY + h > Integer.MAX_VALUE) {
+            // awt.248=parentY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$
+        }
+
+        if ((long)childMinX + w > Integer.MAX_VALUE) {
+            // awt.249=childMinX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$
+        }
+
+        if ((long)childMinY + h > Integer.MAX_VALUE) {
+            // awt.24A=childMinY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new WritableRaster(childModel, dataBuffer,
+                new Rectangle(childMinX, childMinY, w, h), new Point(childTranslateX
+                        + sampleModelTranslateX, childTranslateY + sampleModelTranslateY), this);
+    }
+
+    /**
+     * Creates the translated child of this WritableRaster. New WritableRaster
+     * object is a reference to the this WritableRaster and with different
+     * location.
+     * 
+     * @param childMinX
+     *            the X coordinate of the new WritableRaster.
+     * @param childMinY
+     *            the Y coordinate of the new WritableRaster.
+     * @return the WritableRaster.
+     */
+    public WritableRaster createWritableTranslatedChild(int childMinX, int childMinY) {
+        return createWritableChild(minX, minY, width, height, childMinX, childMinY, null);
+    }
+
+    /**
+     * Gets the parent WritableRaster for this WritableRaster object.
+     * 
+     * @return the parent WritableRaster for this WritableRaster object.
+     */
+    public WritableRaster getWritableParent() {
+        return (WritableRaster)parent;
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this
+     * WritableRaster.
+     * 
+     * @param srcRaster
+     *            the source Raster.
+     */
+    public void setRect(Raster srcRaster) {
+        setRect(0, 0, srcRaster);
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this
+     * WritableRaster. Each pixel with (x, y) coordinates from the source Raster
+     * is copied to pixel with (x+dx, y+dy) coordinates in this WritableRaster.
+     * The pixels with (x+dx, y+dy) coordinates which are out the bounds of this
+     * raster are ignored.
+     * 
+     * @param dx
+     *            the distance the pixel's X coordinate in the source Raster is
+     *            translated when writtien to this WritableRaster.
+     * @param dy
+     *            the distance the pixel's Y coordinate in the source Raster is
+     *            translated when writtien to this WritableRaster.
+     * @param srcRaster
+     *            the source Raster.
+     */
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        int w = srcRaster.getWidth();
+        int h = srcRaster.getHeight();
+
+        int srcX = srcRaster.getMinX();
+        int srcY = srcRaster.getMinY();
+
+        int dstX = srcX + dx;
+        int dstY = srcY + dy;
+
+        if (dstX < this.minX) {
+            int minOffX = this.minX - dstX;
+            w -= minOffX;
+            dstX = this.minX;
+            srcX += minOffX;
+        }
+
+        if (dstY < this.minY) {
+            int minOffY = this.minY - dstY;
+            h -= minOffY;
+            dstY = this.minY;
+            srcY += minOffY;
+        }
+
+        if (dstX + w > this.minX + this.width) {
+            int maxOffX = (dstX + w) - (this.minX + this.width);
+            w -= maxOffX;
+        }
+
+        if (dstY + h > this.minY + this.height) {
+            int maxOffY = (dstY + h) - (this.minY + this.height);
+            h -= maxOffY;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        switch (sampleModel.getDataType()) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                int iPixelsLine[] = null;
+                for (int i = 0; i < h; i++) {
+                    iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, iPixelsLine);
+                    setPixels(dstX, dstY + i, w, 1, iPixelsLine);
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fPixelsLine[] = null;
+                for (int i = 0; i < h; i++) {
+                    fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, fPixelsLine);
+                    setPixels(dstX, dstY + i, w, 1, fPixelsLine);
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dPixelsLine[] = null;
+                for (int i = 0; i < h; i++) {
+                    dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, dPixelsLine);
+                    setPixels(dstX, dstY + i, w, 1, dPixelsLine);
+                }
+                break;
+        }
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from an input Raster to this
+     * WritableRaster.
+     * 
+     * @param x
+     *            the X coordinate of the point where the data of the input
+     *            Raster is to be written.
+     * @param y
+     *            the Y coordinate of the point where the data of the input
+     *            Raster is to be written.
+     * @param inRaster
+     *            the input Raster.
+     */
+    public void setDataElements(int x, int y, Raster inRaster) {
+        int dstX = x + inRaster.getMinX();
+        int dstY = y + inRaster.getMinY();
+
+        int w = inRaster.getWidth();
+        int h = inRaster.getHeight();
+
+        if (dstX < this.minX || dstX + w > this.minX + this.width || dstY < this.minY
+                || dstY + h > this.minY + this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int srcX = inRaster.getMinX();
+        int srcY = inRaster.getMinY();
+        Object line = null;
+
+        for (int i = 0; i < h; i++) {
+            line = inRaster.getDataElements(srcX, srcY + i, w, 1, line);
+            setDataElements(dstX, dstY + i, w, 1, line);
+        }
+    }
+
+    /**
+     * Sets an integer array of samples for the specified pixel in this
+     * WritableRaster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param iArray
+     *            the integer array of samples.
+     */
+    public void setPixel(int x, int y, int iArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, iArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified pixel in this
+     * WritableRaster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param fArray
+     *            the float array of samples.
+     */
+    public void setPixel(int x, int y, float fArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, fArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified pixel in this
+     * WritableRaster.
+     * 
+     * @param x
+     *            the pixel's X coordinate.
+     * @param y
+     *            the pixel's Y coordinate.
+     * @param dArray
+     *            the double array of samples.
+     */
+    public void setPixel(int x, int y, double dArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, dArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets a integer array of samples for the specified rectangular area of
+     * pixels in this WritableRaster.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     * @param iArray
+     *            the integer array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, iArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified rectangular area of
+     * pixels in this WritableRaster.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     * @param fArray
+     *            the float array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, fArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified rectangular area of
+     * pixels in this WritableRaster.
+     * 
+     * @param x
+     *            the X coordinate of rectangular area.
+     * @param y
+     *            the Y coordinate of rectangular area.
+     * @param w
+     *            the width of rectangular area.
+     * @param h
+     *            the height of rectangular area.
+     * @param dArray
+     *            the double array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, dArray,
+                dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified rectangular
+     * area of pixels with an integer array of samples.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param b
+     *            the specified band.
+     * @param iArray
+     *            the integer array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
+                iArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified rectangular
+     * area of pixels with a float array of samples.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param b
+     *            the specified band.
+     * @param fArray
+     *            the float array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
+                fArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified rectangular
+     * area of pixels with a double array of samples.
+     * 
+     * @param x
+     *            the X coordinate of the area of pixels.
+     * @param y
+     *            the Y coordinate of the area of pixels.
+     * @param w
+     *            the width of the area of pixels.
+     * @param h
+     *            the height of the area of pixels.
+     * @param b
+     *            the specified band.
+     * @param dArray
+     *            the double array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b,
+                dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified pixel with an
+     * integer sample.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample to be set.
+     */
+    public void setSample(int x, int y, int b, int s) {
+        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
+                dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified pixel with a
+     * float sample.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample to be set.
+     */
+    public void setSample(int x, int y, int b, float s) {
+        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
+                dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified pixel with an
+     * integer sample.
+     * 
+     * @param x
+     *            the X coordinate of the pixel.
+     * @param y
+     *            the Y coordinate of the pixel.
+     * @param b
+     *            the specified band.
+     * @param s
+     *            the sample to be set.
+     */
+    public void setSample(int x, int y, int b, double s) {
+        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s,
+                dataBuffer);
+    }
+
+}
diff --git a/awt/java/awt/image/WritableRenderedImage.java b/awt/java/awt/image/WritableRenderedImage.java
new file mode 100644
index 0000000..052353b
--- /dev/null
+++ b/awt/java/awt/image/WritableRenderedImage.java
@@ -0,0 +1,109 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The WriteableRenderedImage interface is interface for objects which contains
+ * Raster data of one or several tiles. This interface provides notification
+ * mechanism for obtaining tile's writing status.
+ * 
+ * @since Android 1.0
+ */
+public interface WritableRenderedImage extends RenderedImage {
+
+    /**
+     * Gets and checks out the writable tile for writing.
+     * 
+     * @param tileX
+     *            the X index of the tile.
+     * @param tileY
+     *            the Y index of the tile.
+     * @return the WritableRaster.
+     */
+    public WritableRaster getWritableTile(int tileX, int tileY);
+
+    /**
+     * Removes the registered TileObserver.
+     * 
+     * @param to
+     *            the TileObserver which is registered for this
+     *            WritableRenderedImage.
+     */
+    public void removeTileObserver(TileObserver to);
+
+    /**
+     * Adds the specified TileObserver to this WritableRenderedImage.
+     * 
+     * @param to
+     *            the TileObserver object to be added.
+     */
+    public void addTileObserver(TileObserver to);
+
+    /**
+     * Sets this image to the contents of the specified Raster.
+     * 
+     * @param r
+     *            the specified Raster.
+     */
+    public void setData(Raster r);
+
+    /**
+     * Gets the array of points which represent indices of tiles which are check
+     * out for writing.
+     * 
+     * @return the array of points.
+     */
+    public Point[] getWritableTileIndices();
+
+    /**
+     * Checks if the specified tile is writable or not.
+     * 
+     * @param tileX
+     *            the X index of tile.
+     * @param tileY
+     *            the Y index of tile.
+     * @return true, if the specified tile is writable, false otherwise.
+     */
+    public boolean isTileWritable(int tileX, int tileY);
+
+    /**
+     * Release the specified writable tile. This method removes the writer from
+     * the tile.
+     * 
+     * @param tileX
+     *            the X index of the tile.
+     * @param tileY
+     *            the Y index of the tile.
+     */
+    public void releaseWritableTile(int tileX, int tileY);
+
+    /**
+     * Checks if there is a tile which is checked out for writing.
+     * 
+     * @return true, if any tile is checked out for writing, false if there is
+     *         no such tile.
+     */
+    public boolean hasTileWriters();
+
+}
diff --git a/awt/java/awt/image/package.html b/awt/java/awt/image/package.html
new file mode 100644
index 0000000..b4d6ef0
--- /dev/null
+++ b/awt/java/awt/image/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes and interfaces that allow to modify existing images or to create a new image rather than loading it from a file.
+    </p>
+   @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
new file mode 100644
index 0000000..1881a0c
--- /dev/null
+++ b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating ContextualRenderedImage objects with utilities for
+ * manipulating the properties in the parameter block.
+ * 
+ * @since Android 1.0
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory {
+
+    /**
+     * Maps a render context to a parameter block and a renderable image.
+     * 
+     * @param a0
+     *            the index.
+     * @param a1
+     *            the RenderContext.
+     * @param a2
+     *            the ParameterBlock.
+     * @param a3
+     *            the RenderableImage.
+     * @return the render context.
+     */
+    public RenderContext mapRenderContext(int a0, RenderContext a1, ParameterBlock a2,
+            RenderableImage a3);
+
+    /**
+     * Gets the value of the property from the parameter block.
+     * 
+     * @param a0
+     *            the parameter block to examine to find the property.
+     * @param a1
+     *            the name of the property.
+     * @return the value of the property.
+     */
+    public Object getProperty(ParameterBlock a0, String a1);
+
+    /**
+     * Creates the rendered image determined by the render context and parameter
+     * block.
+     * 
+     * @param a0
+     *            the RenderContext.
+     * @param a1
+     *            the ParameterBlock.
+     * @return the rendered image.
+     */
+    public RenderedImage create(RenderContext a0, ParameterBlock a1);
+
+    /**
+     * Gets the bounding rectangle from the parameter block.
+     * 
+     * @param a0
+     *            the parameter block to read the bounds from.
+     * @return the bounding rectangle.
+     */
+    public Rectangle2D getBounds2D(ParameterBlock a0);
+
+    /**
+     * Gets the names of all of the supported properties.
+     * 
+     * @return the property names.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Checks if this image factory is dynamic.
+     * 
+     * @return true, if this image factory is dynamic.
+     */
+    public boolean isDynamic();
+
+}
diff --git a/awt/java/awt/image/renderable/ParameterBlock.java b/awt/java/awt/image/renderable/ParameterBlock.java
new file mode 100644
index 0000000..7dde73a
--- /dev/null
+++ b/awt/java/awt/image/renderable/ParameterBlock.java
@@ -0,0 +1,568 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.image.RenderedImage;
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ * The class ParameterBlock groups an indexed set of parameter data with a set
+ * of renderable (source) images. The mapping between the indexed parameters and
+ * their property names is provided by a {@link ContextualRenderedImageFactory}.
+ * 
+ * @since Android 1.0
+ */
+public class ParameterBlock implements Cloneable, Serializable {
+
+    /**
+     * The Constant serialVersionUID.
+     */
+    private static final long serialVersionUID = -7577115551785240750L;
+
+    /**
+     * The sources (renderable images).
+     */
+    protected Vector<Object> sources = new Vector<Object>();
+
+    /**
+     * The parameters.
+     */
+    protected Vector<Object> parameters = new Vector<Object>();
+
+    /**
+     * Instantiates a new parameter block.
+     * 
+     * @param sources
+     *            the vector of source images.
+     * @param parameters
+     *            the vector of parameters.
+     */
+    public ParameterBlock(Vector<Object> sources, Vector<Object> parameters) {
+        setSources(sources);
+        setParameters(parameters);
+    }
+
+    /**
+     * Instantiates a new parameter block with no parameters.
+     * 
+     * @param sources
+     *            the vector of source images.
+     */
+    public ParameterBlock(Vector<Object> sources) {
+        setSources(sources);
+    }
+
+    /**
+     * Instantiates a new parameter block with no image or parameter vectors.
+     */
+    public ParameterBlock() {
+    }
+
+    /**
+     * Sets the source image at the specified index.
+     * 
+     * @param source
+     *            the source image.
+     * @param index
+     *            the index where the source will be placed.
+     * @return this parameter block.
+     */
+    public ParameterBlock setSource(Object source, int index) {
+        if (sources.size() < index + 1) {
+            sources.setSize(index + 1);
+        }
+        sources.setElementAt(source, index);
+        return this;
+    }
+
+    /**
+     * Sets the parameter value object at the specified index.
+     * 
+     * @param obj
+     *            the parameter value to place at the desired index.
+     * @param index
+     *            the index where the object is to be placed in the vector of
+     *            parameters.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(Object obj, int index) {
+        if (parameters.size() < index + 1) {
+            parameters.setSize(index + 1);
+        }
+        parameters.setElementAt(obj, index);
+        return this;
+    }
+
+    /**
+     * Adds a source to the vector of sources.
+     * 
+     * @param source
+     *            the source to add.
+     * @return this parameter block.
+     */
+    public ParameterBlock addSource(Object source) {
+        sources.addElement(source);
+        return this;
+    }
+
+    /**
+     * Adds the object to the vector of parameter values
+     * 
+     * @param obj
+     *            the obj to add.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(Object obj) {
+        parameters.addElement(obj);
+        return this;
+    }
+
+    /**
+     * Sets the vector of sources, replacing the existing vector of sources, if
+     * any.
+     * 
+     * @param sources
+     *            the new sources.
+     */
+    public void setSources(Vector<Object> sources) {
+        this.sources = sources;
+    }
+
+    /**
+     * Sets the vector of parameters, replacing the existing vector of
+     * parameters, if any.
+     * 
+     * @param parameters
+     *            the new parameters.
+     */
+    public void setParameters(Vector<Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Gets the vector of sources.
+     * 
+     * @return the sources.
+     */
+    public Vector<Object> getSources() {
+        return sources;
+    }
+
+    /**
+     * Gets the vector of parameters.
+     * 
+     * @return the parameters.
+     */
+    public Vector<Object> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Gets the source at the specified index.
+     * 
+     * @param index
+     *            the index.
+     * @return the source object found at the specified index.
+     */
+    public Object getSource(int index) {
+        return sources.elementAt(index);
+    }
+
+    /**
+     * Gets the object parameter found at the specified index.
+     * 
+     * @param index
+     *            the index.
+     * @return the parameter object found at the specified index.
+     */
+    public Object getObjectParameter(int index) {
+        return parameters.elementAt(index);
+    }
+
+    /**
+     * Shallow clone (clones using the superclass clone method).
+     * 
+     * @return the clone of this object.
+     */
+    public Object shallowClone() {
+        try {
+            return super.clone();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns a copy of this ParameterBlock instance.
+     * 
+     * @return the identical copy of this instance.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        ParameterBlock replica;
+        try {
+            replica = (ParameterBlock)super.clone();
+        } catch (Exception e) {
+            return null;
+        }
+        if (sources != null) {
+            replica.setSources((Vector<Object>)(sources.clone()));
+        }
+        if (parameters != null) {
+            replica.setParameters((Vector<Object>)(parameters.clone()));
+        }
+        return replica;
+    }
+
+    /**
+     * Gets an array of classes corresponding to all of the parameter values
+     * found in the array of parameters, in order.
+     * 
+     * @return the parameter classes.
+     */
+    public Class[] getParamClasses() {
+        int count = parameters.size();
+        Class paramClasses[] = new Class[count];
+
+        for (int i = 0; i < count; i++) {
+            paramClasses[i] = parameters.elementAt(i).getClass();
+        }
+        return paramClasses;
+    }
+
+    /**
+     * Gets the renderable source image found at the specified index in the
+     * source array.
+     * 
+     * @param index
+     *            the index.
+     * @return the renderable source image.
+     */
+    public RenderableImage getRenderableSource(int index) {
+        return (RenderableImage)sources.elementAt(index);
+    }
+
+    /**
+     * Wraps the short value in a Short and places it in the parameter block at
+     * the specified index.
+     * 
+     * @param s
+     *            the short value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(short s, int index) {
+        return set(new Short(s), index);
+    }
+
+    /**
+     * Wraps the short value in a Short and adds it to the parameter block.
+     * 
+     * @param s
+     *            the short value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(short s) {
+        return add(new Short(s));
+    }
+
+    /**
+     * Wraps the long value in a Long and places it in the parameter block at
+     * the specified index.
+     * 
+     * @param l
+     *            the long value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(long l, int index) {
+        return set(new Long(l), index);
+    }
+
+    /**
+     * Wraps the long value in a Long and adds it to the parameter block.
+     * 
+     * @param l
+     *            the long value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(long l) {
+        return add(new Long(l));
+    }
+
+    /**
+     * Wraps the integer value in an Integer and places it in the parameter
+     * block at the specified index.
+     * 
+     * @param i
+     *            the integer value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(int i, int index) {
+        return set(new Integer(i), index);
+    }
+
+    /**
+     * Wraps the integer value in an Integer and adds it to the parameter block.
+     * 
+     * @param i
+     *            the integer value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(int i) {
+        return add(new Integer(i));
+    }
+
+    /**
+     * Wraps the float value in a Float and places it in the parameter block at
+     * the specified index.
+     * 
+     * @param f
+     *            the float value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(float f, int index) {
+        return set(new Float(f), index);
+    }
+
+    /**
+     * Wraps the float value in a Float and adds it to the parameter block.
+     * 
+     * @param f
+     *            the float value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(float f) {
+        return add(new Float(f));
+    }
+
+    /**
+     * Wraps the double value in a Double and places it in the parameter block
+     * at the specified index.
+     * 
+     * @param d
+     *            the double value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(double d, int index) {
+        return set(new Double(d), index);
+    }
+
+    /**
+     * Wraps the double value in a Double and adds it to the parameter block.
+     * 
+     * @param d
+     *            the double value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(double d) {
+        return add(new Double(d));
+    }
+
+    /**
+     * Wraps the char value in a Character and places it in the parameter block
+     * at the specified index.
+     * 
+     * @param c
+     *            the char value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(char c, int index) {
+        return set(new Character(c), index);
+    }
+
+    /**
+     * Wraps the char value in a Character and adds it to the parameter block.
+     * 
+     * @param c
+     *            the char value of the parameter.
+     * @return this parameter block.
+     */
+    public ParameterBlock add(char c) {
+        return add(new Character(c));
+    }
+
+    /**
+     * Wraps the byte value in a Byte and places it in the parameter block at
+     * the specified index.
+     * 
+     * @param b
+     *            the byte value of the parameter.
+     * @param index
+     *            the index.
+     * @return this parameter block.
+     */
+    public ParameterBlock set(byte b, int index) {
+        return set(new Byte(b), index);
+    }
+
+    /**
+     * Wraps the byte value in a Byte and adds it to the parameter block.
+     * 
+     * @param b
+     *            the byte value of the parameter.
+     * @return the parameter block.
+     */
+    public ParameterBlock add(byte b) {
+        return add(new Byte(b));
+    }
+
+    /**
+     * Gets the RenderedImage at the specified index from the vector of source
+     * images.
+     * 
+     * @param index
+     *            the index.
+     * @return the rendered image.
+     */
+    public RenderedImage getRenderedSource(int index) {
+        return (RenderedImage)sources.elementAt(index);
+    }
+
+    /**
+     * Gets the short-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the short parameter.
+     */
+    public short getShortParameter(int index) {
+        return ((Short)parameters.elementAt(index)).shortValue();
+    }
+
+    /**
+     * Gets the long-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the long parameter.
+     */
+    public long getLongParameter(int index) {
+        return ((Long)parameters.elementAt(index)).longValue();
+    }
+
+    /**
+     * Gets the integer-valued parameter found at the desired index in the
+     * vector of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the integer parameter.
+     */
+    public int getIntParameter(int index) {
+        return ((Integer)parameters.elementAt(index)).intValue();
+    }
+
+    /**
+     * Gets the float-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the float parameter.
+     */
+    public float getFloatParameter(int index) {
+        return ((Float)parameters.elementAt(index)).floatValue();
+    }
+
+    /**
+     * Gets the double-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the double parameter.
+     */
+    public double getDoubleParameter(int index) {
+        return ((Double)parameters.elementAt(index)).doubleValue();
+    }
+
+    /**
+     * Gets the char-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the char parameter.
+     */
+    public char getCharParameter(int index) {
+        return ((Character)parameters.elementAt(index)).charValue();
+    }
+
+    /**
+     * Gets the byte-valued parameter found at the desired index in the vector
+     * of parameter values.
+     * 
+     * @param index
+     *            the index.
+     * @return the byte parameter.
+     */
+    public byte getByteParameter(int index) {
+        return ((Byte)parameters.elementAt(index)).byteValue();
+    }
+
+    /**
+     * Clears the vector of sources.
+     */
+    public void removeSources() {
+        sources.removeAllElements();
+    }
+
+    /**
+     * Clears the vector of parameters.
+     */
+    public void removeParameters() {
+        parameters.removeAllElements();
+    }
+
+    /**
+     * Gets the number of elements in the vector of sources.
+     * 
+     * @return the number of elements in the vector of sources.
+     */
+    public int getNumSources() {
+        return sources.size();
+    }
+
+    /**
+     * Gets the number of elements in the vector of parameters.
+     * 
+     * @return the number of elements in the vector of parameters.
+     */
+    public int getNumParameters() {
+        return parameters.size();
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderContext.java b/awt/java/awt/image/renderable/RenderContext.java
new file mode 100644
index 0000000..0db512f
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderContext.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.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+/**
+ * The Class RenderContext stores data on how an image is to be rendered: the
+ * affine transform, the area of interest, and the rendering hints.
+ * 
+ * @since Android 1.0
+ */
+public class RenderContext implements Cloneable {
+
+    /**
+     * The affine transform.
+     */
+    AffineTransform transform;
+
+    /**
+     * The area of interest.
+     */
+    Shape aoi;
+
+    /**
+     * The rendering hints.
+     */
+    RenderingHints hints;
+
+    /**
+     * Instantiates a new render context.
+     * 
+     * @param usr2dev
+     *            the affine transform.
+     * @param aoi
+     *            the area of interest.
+     * @param hints
+     *            the rendering hints.
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi, RenderingHints hints) {
+        this.transform = (AffineTransform)usr2dev.clone();
+        this.aoi = aoi;
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new render context with no specified hints.
+     * 
+     * @param usr2dev
+     *            the affine transform.
+     * @param aoi
+     *            the area of interest.
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi) {
+        this(usr2dev, aoi, null);
+    }
+
+    /**
+     * Instantiates a new render context with no specified area of interest.
+     * 
+     * @param usr2dev
+     *            the affine transform.
+     * @param hints
+     *            the rendering hints.
+     */
+    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
+        this(usr2dev, null, hints);
+    }
+
+    /**
+     * Instantiates a new render context with no rendering hints or area of
+     * interest.
+     * 
+     * @param usr2dev
+     *            the affine transform.
+     */
+    public RenderContext(AffineTransform usr2dev) {
+        this(usr2dev, null, null);
+    }
+
+    @Override
+    public Object clone() {
+        return new RenderContext(transform, aoi, hints);
+    }
+
+    /**
+     * Sets the affine transform for this render context.
+     * 
+     * @param newTransform
+     *            the new affine transform.
+     */
+    public void setTransform(AffineTransform newTransform) {
+        transform = (AffineTransform)newTransform.clone();
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform (so they
+     * are applied with the specified transform acting first) and sets the
+     * resulting transform as the affine transform of this rendering context.
+     * 
+     * @param modTransform
+     *            the new transform which modifies the current transform.
+     * @deprecated use
+     *             {@link RenderContext#preConcatenateTransform(AffineTransform)}
+     *             .
+     */
+    @Deprecated
+    public void preConcetenateTransform(AffineTransform modTransform) {
+        preConcatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform (so they
+     * are applied with the specified transform acting first) and sets the
+     * resulting transform as the affine transform of this rendering context.
+     * 
+     * @param modTransform
+     *            the new transform which modifies the current transform.
+     */
+    public void preConcatenateTransform(AffineTransform modTransform) {
+        transform.preConcatenate(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform
+     *            the new transform which modifies the current transform.
+     * @deprecated use
+     *             {@link RenderContext#concatenateTransform(AffineTransform)}.
+     */
+    @Deprecated
+    public void concetenateTransform(AffineTransform modTransform) {
+        concatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform
+     *            the new transform which modifies the current transform.
+     */
+    public void concatenateTransform(AffineTransform modTransform) {
+        transform.concatenate(modTransform);
+    }
+
+    /**
+     * Gets the transform.
+     * 
+     * @return the transform.
+     */
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    /**
+     * Sets the area of interest.
+     * 
+     * @param newAoi
+     *            the new area of interest.
+     */
+    public void setAreaOfInterest(Shape newAoi) {
+        aoi = newAoi;
+    }
+
+    /**
+     * Gets the area of interest.
+     * 
+     * @return the area of interest.
+     */
+    public Shape getAreaOfInterest() {
+        return aoi;
+    }
+
+    /**
+     * Sets the rendering hints.
+     * 
+     * @param hints
+     *            the new rendering hints.
+     */
+    public void setRenderingHints(RenderingHints hints) {
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the rendering hints.
+     * 
+     * @return the rendering hints.
+     */
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderableImage.java b/awt/java/awt/image/renderable/RenderableImage.java
new file mode 100644
index 0000000..21332f7
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImage.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Interface RenderableImage is implemented by an object that collects all
+ * of the image-specific data that defines a single image that could be rendered
+ * to different rendering targets.
+ * 
+ * @since Android 1.0
+ */
+public interface RenderableImage {
+
+    /**
+     * The Constant HINTS_OBSERVED indicates that the rendering hints are
+     * applied rather than ignored.
+     */
+    public static final String HINTS_OBSERVED = "HINTS_OBSERVED"; //$NON-NLS-1$
+
+    /**
+     * Gets the property from the RenderableImage's parameter block.
+     * 
+     * @param name
+     *            the name of the property to get.
+     * @return the value of the property.
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Creates the rendered image based on the information contained in the
+     * parameters and the render context.
+     * 
+     * @param renderContext
+     *            the render context giving rendering specifications such as
+     *            transformations.
+     * @return the rendered image.
+     */
+    public RenderedImage createRendering(RenderContext renderContext);
+
+    /**
+     * Creates the scaled rendered image based on the information contained in
+     * the parameters and the render context.
+     * 
+     * @param w
+     *            the desired width after scaling or zero if the scaling should
+     *            be proportional, based on the height.
+     * @param h
+     *            the desired height after scaling or zero if the scaling should
+     *            be proportional, based on the width.
+     * @param hints
+     *            the rendering hints to use.
+     * @return the rendered image.
+     * @throws IllegalArgumentException
+     *             if both the height and width are zero.
+     */
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+
+    /**
+     * Gets the vector of sources from the parameter block.
+     * 
+     * @return the sources.
+     */
+    public Vector<RenderableImage> getSources();
+
+    /**
+     * Gets the names of all of the supported properties in the current context.
+     * 
+     * @return the property names.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Creates the default rendering (using the identity transform and default
+     * render context).
+     * 
+     * @return the rendered image.
+     */
+    public RenderedImage createDefaultRendering();
+
+    /**
+     * Checks if this context supports dynamic rendering.
+     * 
+     * @return true, if this context supports dynamic rendering.
+     */
+    public boolean isDynamic();
+
+    /**
+     * Gets the width of the image.
+     * 
+     * @return the width of the image.
+     */
+    public float getWidth();
+
+    /**
+     * Gets the y coordinate of the upper left corner.
+     * 
+     * @return the y coordinate of the upper left corner.
+     */
+    public float getMinY();
+
+    /**
+     * Gets the x coordinate of the upper left corner.
+     * 
+     * @return the x coordinate of the upper left corner.
+     */
+    public float getMinX();
+
+    /**
+     * Gets the height of the image.
+     * 
+     * @return the height of the image.
+     */
+    public float getHeight();
+
+}
diff --git a/awt/java/awt/image/renderable/RenderableImageOp.java b/awt/java/awt/image/renderable/RenderableImageOp.java
new file mode 100644
index 0000000..dc45372
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageOp.java
@@ -0,0 +1,191 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RenderableImageOp is a basic implementation of RenderableImage,
+ * with methods to access the parameter data and perform rendering operations.
+ * 
+ * @since Android 1.0
+ */
+public class RenderableImageOp implements RenderableImage {
+
+    /**
+     * The CRIF.
+     */
+    ContextualRenderedImageFactory CRIF;
+
+    /**
+     * The param block.
+     */
+    ParameterBlock paramBlock;
+
+    /**
+     * The height.
+     */
+    float minX, minY, width, height;
+
+    /**
+     * Instantiates a new renderable image op.
+     * 
+     * @param CRIF
+     *            the cRIF.
+     * @param paramBlock
+     *            the param block.
+     */
+    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
+        this.CRIF = CRIF;
+        this.paramBlock = (ParameterBlock)paramBlock.clone();
+        Rectangle2D r = CRIF.getBounds2D(paramBlock);
+        minX = (float)r.getMinX();
+        minY = (float)r.getMinY();
+        width = (float)r.getWidth();
+        height = (float)r.getHeight();
+    }
+
+    public Object getProperty(String name) {
+        return CRIF.getProperty(paramBlock, name);
+    }
+
+    /**
+     * Sets the parameter block.
+     * 
+     * @param paramBlock
+     *            the param block.
+     * @return the parameter block.
+     */
+    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
+        ParameterBlock oldParam = this.paramBlock;
+        this.paramBlock = (ParameterBlock)paramBlock.clone();
+        return oldParam;
+    }
+
+    public RenderedImage createRendering(RenderContext renderContext) {
+
+        Vector<RenderableImage> sources = getSources();
+        ParameterBlock rdParam = (ParameterBlock)paramBlock.clone();
+
+        if (sources != null) {
+            Vector<Object> rdSources = new Vector<Object>();
+            int i = 0;
+            while (i < sources.size()) {
+                RenderContext newContext = CRIF
+                        .mapRenderContext(i, renderContext, paramBlock, this);
+                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
+
+                if (rdim != null) {
+                    rdSources.addElement(rdim);
+                }
+                i++;
+            }
+            if (rdSources.size() > 0) {
+                rdParam.setSources(rdSources);
+            }
+        }
+        return CRIF.create(renderContext, rdParam);
+    }
+
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
+        if (w == 0 && h == 0) {
+            // awt.60=Width and Height mustn't be equal zero both
+            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
+        }
+        if (w == 0) {
+            w = Math.round(h * (getWidth() / getHeight()));
+        }
+
+        if (h == 0) {
+            h = Math.round(w * (getHeight() / getWidth()));
+        }
+
+        double sx = (double)w / getWidth();
+        double sy = (double)h / getHeight();
+
+        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
+        RenderContext context = new RenderContext(at, hints);
+        return createRendering(context);
+    }
+
+    public Vector<RenderableImage> getSources() {
+        if (paramBlock.getNumSources() == 0) {
+            return null;
+        }
+        Vector<RenderableImage> v = new Vector<RenderableImage>();
+        int i = 0;
+        while (i < paramBlock.getNumSources()) {
+            Object o = paramBlock.getSource(i);
+            if (o instanceof RenderableImage) {
+                v.addElement((RenderableImage)o);
+            }
+            i++;
+        }
+        return v;
+    }
+
+    public String[] getPropertyNames() {
+        return CRIF.getPropertyNames();
+    }
+
+    /**
+     * Gets the parameter block.
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock getParameterBlock() {
+        return paramBlock;
+    }
+
+    public RenderedImage createDefaultRendering() {
+        AffineTransform at = new AffineTransform();
+        RenderContext context = new RenderContext(at);
+        return createRendering(context);
+    }
+
+    public boolean isDynamic() {
+        return CRIF.isDynamic();
+    }
+
+    public float getWidth() {
+        return width;
+    }
+
+    public float getMinY() {
+        return minY;
+    }
+
+    public float getMinX() {
+        return minX;
+    }
+
+    public float getHeight() {
+        return height;
+    }
+
+}
diff --git a/awt/java/awt/image/renderable/RenderableImageProducer.java b/awt/java/awt/image/renderable/RenderableImageProducer.java
new file mode 100644
index 0000000..e83ebc7
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageProducer.java
@@ -0,0 +1,151 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Class RenderableImageProducer provides the implementation for the image
+ * rendering.
+ * 
+ * @since Android 1.0
+ */
+public class RenderableImageProducer implements ImageProducer, Runnable {
+
+    /**
+     * The rbl.
+     */
+    RenderableImage rbl;
+
+    /**
+     * The rc.
+     */
+    RenderContext rc;
+
+    /**
+     * The consumers.
+     */
+    Vector<ImageConsumer> consumers = new Vector<ImageConsumer>();
+
+    /**
+     * Instantiates a new renderable image producer.
+     * 
+     * @param rdblImage
+     *            the rdbl image.
+     * @param rc
+     *            the rc.
+     */
+    public RenderableImageProducer(RenderableImage rdblImage, RenderContext rc) {
+        this.rbl = rdblImage;
+        this.rc = rc;
+    }
+
+    /**
+     * Sets the render context.
+     * 
+     * @param rc
+     *            the new render context.
+     */
+    public synchronized void setRenderContext(RenderContext rc) {
+        this.rc = rc;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        Thread t = new Thread(this, "RenderableImageProducer thread"); //$NON-NLS-1$
+        t.start();
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if (ic != null) {
+            consumers.removeElement(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (ic != null && !consumers.contains(ic)) {
+            consumers.addElement(ic);
+        }
+    }
+
+    /**
+     * Creates the rendered image in a new thread.
+     */
+    public void run() {
+        if (rbl == null) {
+            return;
+        }
+
+        RenderedImage rd;
+        if (rc != null) {
+            rd = rbl.createRendering(rc);
+        } else {
+            rd = rbl.createDefaultRendering();
+        }
+
+        ColorModel cm = rd.getColorModel();
+        if (cm == null) {
+            cm = ColorModel.getRGBdefault();
+        }
+
+        Raster r = rd.getData();
+        int w = r.getWidth();
+        int h = r.getHeight();
+
+        for (ImageConsumer c : consumers) {
+            c.setDimensions(w, h);
+            c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
+                    | ImageConsumer.SINGLEFRAME | ImageConsumer.SINGLEPASS);
+        }
+
+        int scanLine[] = new int[w];
+        int pixel[] = null;
+
+        for (int y = 0; y < h; y++) {
+            for (int x = 0; x < w; x++) {
+                pixel = r.getPixel(x, y, pixel);
+                scanLine[x] = cm.getDataElement(pixel, 0);
+            }
+
+            for (ImageConsumer c : consumers) {
+                c.setPixels(0, y, w, 1, cm, scanLine, 0, w);
+            }
+        }
+
+        for (ImageConsumer c : consumers) {
+            c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }
+    }
+
+}
diff --git a/awt/java/awt/image/renderable/RenderedImageFactory.java b/awt/java/awt/image/renderable/RenderedImageFactory.java
new file mode 100644
index 0000000..881a40a
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderedImageFactory.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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating RenderedImage objects based on parameters and
+ * rendering hints.
+ * 
+ * @since Android 1.0
+ */
+public interface RenderedImageFactory {
+
+    /**
+     * Creates the rendered image.
+     * 
+     * @param a0
+     *            the ParameterBlock.
+     * @param a1
+     *            the RenderingHints.
+     * @return the rendered image.
+     */
+    public RenderedImage create(ParameterBlock a0, RenderingHints a1);
+
+}
diff --git a/awt/java/awt/image/renderable/package.html b/awt/java/awt/image/renderable/package.html
new file mode 100644
index 0000000..43aaabc
--- /dev/null
+++ b/awt/java/awt/image/renderable/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes to create images which are rendering-independent.
+    </p>
+    @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/package.html b/awt/java/awt/package.html
new file mode 100644
index 0000000..5a6f9f0
--- /dev/null
+++ b/awt/java/awt/package.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <p>
+      This package contains classes and interfaces for creating (graphical) user interfaces (GUI), painting 2D graphics and creating, manipulating and drawing images. 
+    </p>
+  @since Android 1.0
+  </body>
+</html>
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
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/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/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;
+    }
+}
