diff --git a/awt/java/awt/AWTEvent.java b/awt/java/awt/AWTEvent.java
new file mode 100644
index 0000000..1ed9a37
--- /dev/null
+++ b/awt/java/awt/AWTEvent.java
@@ -0,0 +1,618 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev, Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.EventObject;
+import java.util.Hashtable;
+import java.util.EventListener;
+
+import java.awt.event.*;
+
+/**
+ * The abstract AWT events is base class for all AWT events. 
+ * This class and its subclasses supercede the original java.awt.Event class.
+ */
+public abstract class AWTEvent extends EventObject {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1825314779160409405L;
+
+    /** The Constant COMPONENT_EVENT_MASK indicates the event relates to a component. */
+    public static final long COMPONENT_EVENT_MASK = 1;
+
+    /** The Constant CONTAINER_EVENT_MASK indicates the event relates to a container. */
+    public static final long CONTAINER_EVENT_MASK = 2;
+
+    /** The Constant FOCUS_EVENT_MASK indicates the event relates to the focus. */
+    public static final long FOCUS_EVENT_MASK = 4;
+
+    /** The Constant KEY_EVENT_MASK indicates the event relates to a key. */
+    public static final long KEY_EVENT_MASK = 8;
+
+    /** The Constant MOUSE_EVENT_MASK indicates the event relates to the mouse. */
+    public static final long MOUSE_EVENT_MASK = 16;
+
+    /** The Constant MOUSE_MOTION_EVENT_MASK indicates the event relates to a mouse motion. */
+    public static final long MOUSE_MOTION_EVENT_MASK = 32;
+
+    /** The Constant WINDOW_EVENT_MASK indicates the event relates to a window. */
+    public static final long WINDOW_EVENT_MASK = 64;
+
+    /** The Constant ACTION_EVENT_MASK indicates the event relates to an action. */
+    public static final long ACTION_EVENT_MASK = 128;
+
+    /** The Constant ADJUSTMENT_EVENT_MASK indicates the event relates to an adjustment. */
+    public static final long ADJUSTMENT_EVENT_MASK = 256;
+
+    /** The Constant ITEM_EVENT_MASK indicates the event relates to an item. */
+    public static final long ITEM_EVENT_MASK = 512;
+
+    /** The Constant TEXT_EVENT_MASK indicates the event relates to text. */
+    public static final long TEXT_EVENT_MASK = 1024;
+
+    /** The Constant INPUT_METHOD_EVENT_MASK indicates the event relates to an input method. */
+    public static final long INPUT_METHOD_EVENT_MASK = 2048;
+
+    /** The Constant PAINT_EVENT_MASK indicates the event relates to a paint method. */
+    public static final long PAINT_EVENT_MASK = 8192;
+
+    /** The Constant INVOCATION_EVENT_MASK indicates the event relates to a method invocation. */
+    public static final long INVOCATION_EVENT_MASK = 16384;
+
+    /** The Constant HIERARCHY_EVENT_MASK indicates the event relates to a hierarchy. */
+    public static final long HIERARCHY_EVENT_MASK = 32768;
+
+    /** 
+     * The Constant HIERARCHY_BOUNDS_EVENT_MASK indicates the event relates to hierarchy bounds.
+     */
+    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 65536;
+
+    /** The Constant MOUSE_WHEEL_EVENT_MASK indicates the event relates to the mouse wheel. */
+    public static final long MOUSE_WHEEL_EVENT_MASK = 131072;
+
+    /** The Constant WINDOW_STATE_EVENT_MASK indicates the event relates to a window state. */
+    public static final long WINDOW_STATE_EVENT_MASK = 262144;
+
+    /** The Constant WINDOW_FOCUS_EVENT_MASK indicates the event relates to a window focus. */
+    public static final long WINDOW_FOCUS_EVENT_MASK = 524288;
+
+    /** The Constant RESERVED_ID_MAX indicates the maximum value for reserved 
+     * AWT event IDs.
+     */
+    public static final int RESERVED_ID_MAX = 1999;
+
+    /** The Constant eventsMap. */
+    private static final Hashtable<Integer, EventDescriptor> eventsMap = new Hashtable<Integer, EventDescriptor>();
+
+    /** The converter. */
+    private static EventConverter converter;
+
+    /** The ID of the event. */
+    protected int id;
+
+    /** 
+     * The consumed indicates whether or not the event is sent back down to 
+     * the peer once the source has processed it (false means it's sent to the peer,
+     * true means it's not).
+     */ 
+    protected boolean consumed;
+
+    /** The dispatched by kfm. */
+    boolean dispatchedByKFM;
+    
+    /** The is posted. */
+    transient boolean isPosted;
+
+    static {
+        eventsMap.put(new Integer(KeyEvent.KEY_TYPED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_PRESSED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_RELEASED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_CLICKED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_PRESSED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_RELEASED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_MOVED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_ENTERED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_EXITED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_DRAGGED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_WHEEL),
+                new EventDescriptor(MOUSE_WHEEL_EVENT_MASK, MouseWheelListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_MOVED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_RESIZED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_SHOWN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_HIDDEN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_GAINED),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_LOST),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(PaintEvent.PAINT),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(PaintEvent.UPDATE),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_OPENED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSING),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_STATE_CHANGED),
+                new EventDescriptor(WINDOW_STATE_EVENT_MASK, WindowStateListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_LOST_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_GAINED_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.HIERARCHY_CHANGED),
+                new EventDescriptor(HIERARCHY_EVENT_MASK, HierarchyListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_MOVED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_RESIZED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_ADDED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_REMOVED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.CARET_POSITION_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InvocationEvent.INVOCATION_DEFAULT),
+                new EventDescriptor(INVOCATION_EVENT_MASK, null));
+        eventsMap.put(new Integer(ItemEvent.ITEM_STATE_CHANGED),
+                new EventDescriptor(ITEM_EVENT_MASK, ItemListener.class));
+        eventsMap.put(new Integer(TextEvent.TEXT_VALUE_CHANGED),
+                new EventDescriptor(TEXT_EVENT_MASK, TextListener.class));
+        eventsMap.put(new Integer(ActionEvent.ACTION_PERFORMED),
+                new EventDescriptor(ACTION_EVENT_MASK, ActionListener.class));
+        eventsMap.put(new Integer(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED),
+                new EventDescriptor(ADJUSTMENT_EVENT_MASK, AdjustmentListener.class));
+        converter = new EventConverter();
+    }
+    
+    /**
+     * Instantiates a new AWT event from the specified Event object.
+     * 
+     * @param event the Event object.
+     */
+    public AWTEvent(Event event) {
+        this(event.target, event.id);
+    }
+
+    /**
+     * Instantiates a new AWT event with the specified object and type.
+     * 
+     * @param source the source Object.
+     * @param id the event's type.
+     */
+    public AWTEvent(Object source, int id) {
+        super(source);
+        this.id = id;
+        consumed = false;
+    }
+
+    /**
+     * Gets the event's type.
+     * 
+     * @return the event type ID.
+     */
+    public int getID() {
+        return id;
+    }
+
+    /**
+     * Sets a new source for the AWTEvent.
+     * 
+     * @param newSource the new source Object for the AWTEvent.
+     */
+    public void setSource(Object newSource) {
+        source = newSource;
+    }
+
+    /**
+     * Returns a String representation of the AWTEvent.
+     * 
+     * @return the String representation of the AWTEvent.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AWTEvent event = new AWTEvent(new Component(){}, 1){};
+         * System.out.println(event);
+         */
+        String name = ""; //$NON-NLS-1$
+        
+        if (source instanceof Component && (source != null)) {
+            Component comp = (Component) getSource();
+            name = comp.getName();
+            if (name == null) {
+                name = ""; //$NON-NLS-1$
+            }
+        }
+        
+        return (getClass().getName() + "[" + paramString() + "]" //$NON-NLS-1$ //$NON-NLS-2$
+                + " on " + (name.length() > 0 ? name : source)); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns a string representation of the AWTEvent state. 
+     *  
+     * @return a string representation of the AWTEvent state.
+     */
+    public String paramString() {
+        //nothing to implement: all event types must override this method
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Checks whether or not this AWTEvent has been consumed.
+     * 
+     * @return true, if this AWTEvent has been consumed, false otherwise.
+     */
+    protected boolean isConsumed() {
+        return consumed;
+    }
+
+    /**
+     * Consumes the AWTEvent.
+     */
+    protected void consume() {
+       consumed = true;
+    }
+
+    /**
+     * Convert AWTEvent object to a corresponding (deprecated) Event object.
+     * 
+     * @return new Event object which is a converted AWTEvent object or null
+     * if the conversion is not possible
+     */
+    Event getEvent() {
+        
+        if (id == ActionEvent.ACTION_PERFORMED) {
+            ActionEvent ae = (ActionEvent) this;
+            return converter.convertActionEvent(ae);
+
+        } else if (id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) {
+            AdjustmentEvent ae = (AdjustmentEvent) this;
+            return converter.convertAdjustmentEvent(ae);
+
+//???AWT
+//        } else if (id == ComponentEvent.COMPONENT_MOVED
+//                && source instanceof Window) {
+//            //the only type of Component events is COMPONENT_MOVED on window
+//            ComponentEvent ce = (ComponentEvent) this;
+//            return converter.convertComponentEvent(ce);
+
+        } else if (id >= FocusEvent.FOCUS_FIRST && id <= FocusEvent.FOCUS_LAST) {
+            //nothing to convert
+
+//???AWT
+//        } else if (id == ItemEvent.ITEM_STATE_CHANGED) {
+//            ItemEvent ie = (ItemEvent) this;
+//            return converter.convertItemEvent(ie);
+
+        } else if (id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED) {
+            KeyEvent ke = (KeyEvent) this;
+            return converter.convertKeyEvent(ke);
+        } else if (id >= MouseEvent.MOUSE_FIRST && id <= MouseEvent.MOUSE_LAST) {
+            MouseEvent me = (MouseEvent) this;
+            return converter.convertMouseEvent(me);
+        } else if (id == WindowEvent.WINDOW_CLOSING
+                || id == WindowEvent.WINDOW_ICONIFIED
+                || id == WindowEvent.WINDOW_DEICONIFIED) {
+            //nothing to convert
+        } else {
+            return null;
+        }
+        return new Event(source, id, null);
+    }
+
+
+    /**
+     * The Class EventDescriptor.
+     */
+    static final class EventDescriptor {
+
+        /** The event mask. */
+        final long eventMask;
+
+        /** The listener type. */
+        final Class<? extends EventListener> listenerType;
+
+        /**
+         * Instantiates a new event descriptor.
+         * 
+         * @param eventMask the event mask
+         * @param listenerType the listener type
+         */
+        EventDescriptor(long eventMask, Class<? extends EventListener> listenerType) {
+            this.eventMask = eventMask;
+            this.listenerType = listenerType;
+        }
+
+    }
+    
+    /**
+     * The Class EventTypeLookup.
+     */
+    static final class EventTypeLookup {
+        
+        /** The last event. */
+        private AWTEvent lastEvent = null;
+        
+        /** The last event descriptor. */
+        private EventDescriptor lastEventDescriptor = null;
+
+        /**
+         * Gets the event descriptor.
+         * 
+         * @param event the event
+         * 
+         * @return the event descriptor
+         */
+        EventDescriptor getEventDescriptor(AWTEvent event) {
+            synchronized (this) {
+                if (event != lastEvent) {
+                    lastEvent = event;
+                    lastEventDescriptor = eventsMap.get(new Integer(event.id));
+                }
+
+                return lastEventDescriptor;
+            }
+        }
+
+        /**
+         * Gets the event mask.
+         * 
+         * @param event the event
+         * 
+         * @return the event mask
+         */
+        long getEventMask(AWTEvent event) {
+            final EventDescriptor ed = getEventDescriptor(event);
+            return ed == null ? -1 : ed.eventMask;
+        }
+    }
+
+    /**
+     * The Class EventConverter.
+     */
+    static final class EventConverter {
+        
+        /** The Constant OLD_MOD_MASK. */
+        static final int OLD_MOD_MASK = Event.ALT_MASK | Event.CTRL_MASK
+        | Event.META_MASK | Event.SHIFT_MASK;
+
+        /**
+         * Convert action event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertActionEvent(ActionEvent ae) {
+            Event evt = new Event(ae.getSource(), ae.getID(), ae.getActionCommand());
+            evt.when = ae.getWhen();
+            evt.modifiers = ae.getModifiers() & OLD_MOD_MASK;
+
+           /* if (source instanceof Button) {
+                arg = ((Button) source).getLabel();
+            } else if (source instanceof Checkbox) {
+                arg = new Boolean(((Checkbox) source).getState());
+            } else if (source instanceof CheckboxMenuItem) {
+                arg = ((CheckboxMenuItem) source).getLabel();
+            } else if (source instanceof Choice) {
+                arg = ((Choice) source).getSelectedItem();
+            } else if (source instanceof List) {
+                arg = ((List) source).getSelectedItem();
+            } else if (source instanceof MenuItem) {
+                arg = ((MenuItem) source).getLabel();
+            } else if (source instanceof TextField) {
+                arg = ((TextField) source).getText();
+            }
+*/
+            return evt;
+        }
+
+
+        /**
+         * Convert adjustment event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertAdjustmentEvent(AdjustmentEvent ae) {
+            //TODO: Event.SCROLL_BEGIN/SCROLL_END
+            return new Event(ae.source, ae.id + ae.getAdjustmentType() - 1,
+                    new Integer(ae.getValue()));
+        }
+
+        /**
+         * Convert component event.
+         * 
+         * @param ce the ce
+         * 
+         * @return the event
+         */
+        Event convertComponentEvent(ComponentEvent ce) {
+            Component comp = ce.getComponent();
+            Event evt = new Event(comp, Event.WINDOW_MOVED, null);
+            evt.x = comp.getX();
+            evt.y = comp.getY();
+            return evt;
+        }
+
+        //???AWT
+        /*
+        Event convertItemEvent(ItemEvent ie) {
+            int oldId = ie.id + ie.getStateChange() - 1;
+            Object source = ie.source;
+            int idx = -1;
+            if (source instanceof List) {
+                List list = (List) source;
+                idx = list.getSelectedIndex();
+            }
+            else if (source instanceof Choice) {
+                Choice choice = (Choice) source;
+                idx = choice.getSelectedIndex();
+            }
+            Object arg = idx >= 0 ? new Integer(idx) : null;
+            return new Event(source, oldId, arg);
+        }
+        */
+        
+        /**
+         * Convert key event.
+         * 
+         * @param ke the ke
+         * 
+         * @return the event
+         */
+        Event convertKeyEvent(KeyEvent ke) {
+            int oldId = ke.id;
+            //leave only old Event's modifiers
+
+            int mod = ke.getModifiers() & OLD_MOD_MASK;
+            Component comp = ke.getComponent();
+            char keyChar = ke.getKeyChar();
+            int keyCode = ke.getKeyCode();
+            int key = convertKey(keyChar, keyCode);
+            if (key >= Event.HOME && key <= Event.INSERT) {
+                oldId += 2; //non-ASCII key -> action key
+            }
+            return new Event(comp, ke.getWhen(), oldId, 0, 0, key, mod);
+        }
+
+        /**
+         * Convert mouse event.
+         * 
+         * @param me the me
+         * 
+         * @return the event
+         */
+        Event convertMouseEvent(MouseEvent me) {
+            int id = me.id;
+            if (id != MouseEvent.MOUSE_CLICKED) {
+                Event evt = new Event(me.source, id, null);
+                evt.x = me.getX();
+                evt.y = me.getY();
+                int mod = me.getModifiers();
+                //in Event modifiers mean button number for mouse events:
+                evt.modifiers = mod & (Event.ALT_MASK | Event.META_MASK);
+                if (id == MouseEvent.MOUSE_PRESSED) {
+                    evt.clickCount = me.getClickCount();
+                }
+                return evt;
+            }
+            return null;
+        }
+        
+        /**
+         * Convert key.
+         * 
+         * @param keyChar the key char
+         * @param keyCode the key code
+         * 
+         * @return the int
+         */
+        int convertKey(char keyChar, int keyCode) {
+            int key;
+            //F1 - F12
+            if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
+                key = Event.F1 + keyCode - KeyEvent.VK_F1;
+            } else {
+                switch (keyCode) {
+                default: //non-action key
+                    key = keyChar;
+                    break;
+                //action keys:
+                case KeyEvent.VK_HOME:
+                    key = Event.HOME;
+                    break;
+                case KeyEvent.VK_END:
+                    key = Event.END;
+                    break;
+                case KeyEvent.VK_PAGE_UP:
+                    key = Event.PGUP;
+                    break;
+                case KeyEvent.VK_PAGE_DOWN:
+                    key = Event.PGDN;
+                    break;
+                case KeyEvent.VK_UP:
+                    key = Event.UP;
+                    break;
+                case KeyEvent.VK_DOWN:
+                    key = Event.DOWN;
+                    break;
+                case KeyEvent.VK_LEFT:
+                    key = Event.LEFT;
+                    break;
+                case KeyEvent.VK_RIGHT:
+                    key = Event.RIGHT;
+                    break;
+                case KeyEvent.VK_PRINTSCREEN:
+                    key = Event.PRINT_SCREEN;
+                    break;
+                case KeyEvent.VK_SCROLL_LOCK:
+                    key = Event.SCROLL_LOCK;
+                    break;
+                case KeyEvent.VK_CAPS_LOCK:
+                    key = Event.CAPS_LOCK;
+                    break;
+                case KeyEvent.VK_NUM_LOCK:
+                    key = Event.NUM_LOCK;
+                    break;
+                case KeyEvent.VK_PAUSE:
+                    key = Event.PAUSE;
+                    break;
+                case KeyEvent.VK_INSERT:
+                    key = Event.INSERT;
+                    break;
+                }
+            }
+            return key;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/AWTException.java b/awt/java/awt/AWTException.java
new file mode 100644
index 0000000..70ce6e1
--- /dev/null
+++ b/awt/java/awt/AWTException.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The AWTException class is used to provide notification and information
+ * about AWT errors.
+ */
+public class AWTException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1900414231151323879L;
+
+    /**
+     * Instantiates a new AWT exception with the specified message.
+     * 
+     * @param msg the specific message for current exception.
+     */
+    public AWTException(String msg) {
+        super(msg);
+    }
+
+}
+
diff --git a/awt/java/awt/AWTKeyStroke.java b/awt/java/awt/AWTKeyStroke.java
new file mode 100644
index 0000000..5e7de4e
--- /dev/null
+++ b/awt/java/awt/AWTKeyStroke.java
@@ -0,0 +1,678 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AWTKeyStroke holds all of the information for the complete act of 
+ * typing a character. This includes the events that are generated when 
+ * the key is pressed, released, or typed (pressed and released generating
+ * a unicode character result) which are associated with the event
+ * objects KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, or KeyEvent.KEY_TYPED.
+ * It also holds information about which modifiers (such as control or 
+ * shift) were used in conjunction with the keystroke. The following masks 
+ * are available to identify the modifiers:
+ * <ul>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+ * <li>java.awt.event.InputEvent.META_MASK</li>  
+ * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+ * </ul>  
+ * <br>
+ *  The AWTKeyStroke is unique, and applications should not create their own 
+ *  instances of AWTKeyStroke. All applications should use getAWTKeyStroke 
+ *  methods for obtaining instances of AWTKeyStroke.
+ */
+public class AWTKeyStroke implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6430539691155161871L;
+
+    /** The Constant cache. */
+    private static final Map<AWTKeyStroke, AWTKeyStroke> cache = new HashMap<AWTKeyStroke, AWTKeyStroke>(); //Map<AWTKeyStroke, ? extends AWTKeyStroke>
+    
+    /** The Constant keyEventTypesMap. */
+    private static final Map<Integer, String> keyEventTypesMap = new HashMap<Integer, String>(); //Map<int, String>
+
+    private static Constructor<?> subConstructor;   
+
+    static {
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_PRESSED), "pressed"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_RELEASED), "released"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_TYPED), "typed"); //$NON-NLS-1$
+    }
+
+    /** The key char. */
+    private char keyChar;
+    
+    /** The key code. */
+    private int keyCode;
+    
+    /** The modifiers. */
+    private int modifiers;
+    
+    /** The on key release. */
+    private boolean onKeyRelease;
+    
+    /**
+     * Instantiates a new AWTKeyStroke. 
+     * getAWTKeyStroke method should be used by applications code.  
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease true if AWTKeyStroke is for a key release, overwise false. 
+     */
+    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+       setAWTKeyStroke(keyChar, keyCode, modifiers, onKeyRelease);
+    }
+
+    /** Sets the awt key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     */
+    private void setAWTKeyStroke( char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+        this.keyChar = keyChar;
+        this.keyCode = keyCode;
+        this.modifiers = modifiers;
+        this.onKeyRelease = onKeyRelease;
+    }
+    
+    /**
+     * Instantiates a new AWTKeyStroke with default parameters:
+     * KeyEvent.CHAR_UNDEFINED key char, KeyEvent.VK_UNDEFINED key code,
+     * without modifiers and false key realised value.
+     */
+    protected AWTKeyStroke() {
+        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns the unique number value for AWTKeyStroke object.
+     * 
+     * @return the int unique value of the AWTKeyStroke object.
+     */
+    @Override
+    public int hashCode() {
+        return modifiers + ( keyCode != KeyEvent.VK_UNDEFINED ?
+                keyCode : keyChar) + (onKeyRelease ? -1 : 0);
+    }
+
+    /**
+     * Gets the set of modifiers for the AWTKeyStroke object.
+     * 
+     * @return the int value which contains modifiers.
+     */
+    public final int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Compares the AWTKeyStroke object to the specified object.
+     * 
+     * @return true, if objects are identical, overwise false.
+     */
+    @Override
+    public final boolean equals(Object anObject) {
+        if (anObject instanceof AWTKeyStroke) {
+            AWTKeyStroke key = (AWTKeyStroke)anObject;
+            return ((key.keyCode == keyCode) && (key.keyChar == keyChar) &&
+                    (key.modifiers == modifiers) &&
+                    (key.onKeyRelease == onKeyRelease));
+        }
+        return false;
+    }
+
+    /**
+     * Returns the string representation of the AWTKeyStroke.
+     * This string should contain key stroke properties.
+     * 
+     * @return the string representation of the AWTKeyStroke.
+     */
+    @Override
+    public String toString() {
+        int type = getKeyEventType();
+        return InputEvent.getModifiersExText(getModifiers()) + " " + //$NON-NLS-1$
+            keyEventTypesMap.get(new Integer(type)) +  " " + //$NON-NLS-1$
+            (type == KeyEvent.KEY_TYPED ? new String(new char[] {keyChar}) :
+                                          KeyEvent.getKeyText(keyCode));
+    }
+
+    /**
+     * Gets the key code for the AWTKeyStroke object.
+     * 
+     * @return the key code for the AWTKeyStroke object.
+     */
+    public final int getKeyCode() {
+        return keyCode;
+    }
+
+    /**
+     * Gets the key character for the AWTKeyStroke object.
+     * 
+     * @return the key character for the AWTKeyStroke object.
+     */
+    public final char getKeyChar() {
+        return keyChar;
+    }
+
+    /**
+     * Gets the AWT key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode,
+                                                int modifiers,
+                                                boolean onKeyRelease) {
+        AWTKeyStroke key = newInstance(keyChar, keyCode, modifiers, onKeyRelease);
+
+        AWTKeyStroke value = cache.get(key);
+        if (value == null) {
+            value = key;
+            cache.put(key, value);
+        }
+        return value;
+    }
+
+    /**
+     * New instance.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke newInstance(char keyChar, int keyCode,
+                                            int modifiers,
+                                            boolean onKeyRelease) {
+        AWTKeyStroke key;
+        //???AWT
+//        if (subConstructor == null) {
+            key = new AWTKeyStroke();
+        //???AWT
+//        } else {
+//            try {
+//                key = (AWTKeyStroke) subConstructor.newInstance();
+//            } catch (Exception e) {
+//                throw new RuntimeException(e);
+//            }
+//        }
+        int allModifiers = getAllModifiers(modifiers);
+        key.setAWTKeyStroke(keyChar, keyCode, allModifiers, onKeyRelease);
+        return key;
+    }
+
+    /**
+     * Adds the mask.
+     * 
+     * @param mod the mod
+     * @param mask the mask
+     * 
+     * @return the int
+     */
+    private static int addMask(int mod, int mask) {
+        return ((mod & mask) != 0) ? (mod | mask) : mod;
+    }
+
+    /**
+     * return all (old & new) modifiers corresponding to.
+     * 
+     * @param mod old or new modifiers
+     * 
+     * @return old and new modifiers together
+     */
+    static int getAllModifiers(int mod) {
+        int allMod = mod;
+        int shift = (InputEvent.SHIFT_MASK | InputEvent.SHIFT_DOWN_MASK);
+        int ctrl = (InputEvent.CTRL_MASK | InputEvent.CTRL_DOWN_MASK);
+        int meta = (InputEvent.META_MASK | InputEvent.META_DOWN_MASK);
+        int alt = (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK);
+        int altGr = (InputEvent.ALT_GRAPH_MASK | InputEvent.ALT_GRAPH_DOWN_MASK);
+        // button modifiers are not converted between old & new
+
+        allMod = addMask(allMod, shift);
+        allMod = addMask(allMod, ctrl);
+        allMod = addMask(allMod, meta);
+        allMod = addMask(allMod, alt);
+        allMod = addMask(allMod, altGr);
+
+        return allMod;
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for parsed string.
+     * 
+     * The string must have the following syntax:
+     *<p>
+     * &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
+     *<p>
+     * modifiers := shift | control | ctrl | meta | alt | altGraph
+     * <br> 
+     * typedID := typed <typedKey>
+     * <br>
+     * typedKey := string of length 1 giving the Unicode character.
+     * <br>
+     * pressedReleasedID := (pressed | released) <key>
+     * <br>
+     * key := KeyEvent key code name, i.e. the name following "VK_".
+     * <p>
+     * @param s the String which contains key stroke parameters.
+     * 
+     * @return the AWTKeyStroke for string.
+     * 
+     * @throws IllegalArgumentException if string has incorrect format or null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(String s) {
+        if (s == null) {
+            // awt.65=null argument
+            throw new IllegalArgumentException(Messages.getString("awt.65")); //$NON-NLS-1$
+        }
+
+        StringTokenizer tokenizer = new StringTokenizer(s);
+
+        Boolean release = null;
+        int modifiers = 0;
+        int keyCode = KeyEvent.VK_UNDEFINED;
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+        boolean typed = false;
+        long modifier = 0;
+        String token = null;
+        do {
+            token = getNextToken(tokenizer);
+            modifier = parseModifier(token);
+            modifiers |= modifier;
+        } while (modifier > 0);
+
+        typed = parseTypedID(token);
+
+        if (typed) {
+            token = getNextToken(tokenizer);
+            keyChar = parseTypedKey(token);
+
+        }
+        if (keyChar == KeyEvent.CHAR_UNDEFINED) {
+            release = parsePressedReleasedID(token);
+            if (release != null) {
+                token = getNextToken(tokenizer);
+            }
+            keyCode = parseKey(token);
+        }
+        if (tokenizer.hasMoreTokens()) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+
+        return getAWTKeyStroke(keyChar, keyCode, modifiers,
+                               release == Boolean.TRUE);
+    }
+
+    /**
+     * Gets the next token.
+     * 
+     * @param tokenizer the tokenizer
+     * 
+     * @return the next token
+     */
+    private static String getNextToken(StringTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (NoSuchElementException exception) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets the key code.
+     * 
+     * @param s the s
+     * 
+     * @return the key code
+     */
+    static int getKeyCode(String s) {
+        try {
+            Field vk = KeyEvent.class.getField("VK_" + s); //$NON-NLS-1$
+            return vk.getInt(null);
+        } catch (Exception e) {
+            if (s.length() != 1) {
+                // awt.66=Invalid format
+                throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+            }
+            return KeyEvent.VK_UNDEFINED;
+        }
+    }
+
+    /**
+     * Gets an instance of the AWTKeyStroke for specified character.
+     * 
+     * @param keyChar the keyboard character value.
+     * 
+     * @return a AWTKeyStroke for specified character.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
+        return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a given key code, set 
+     * of modifiers, and specified key released flag value.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  <br>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
+                                               boolean onKeyRelease) {
+        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
+                               onKeyRelease);
+    }
+
+    /**
+     * Returns AWTKeyStroke for a specified character and set of modifiers. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * 
+     * @param keyChar the Character object which represents keyboard character value.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke object.
+     * 
+     * @throws IllegalArgumentException if keyChar value is null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) {
+        if (keyChar == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "keyChar")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
+                               modifiers, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a specified key code and 
+     * set of modifiers.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
+        return getAWTKeyStroke(keyCode, modifiers, false);
+    }
+
+    /**
+     * Gets the AWTKeyStroke for a key event. This method obtains the key char 
+     * and key code from the specified key event.
+     * 
+     * @param anEvent the key event which identifies the desired AWTKeyStroke.
+     * 
+     * @return the AWTKeyStroke for the key event.
+     */
+    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
+        int id = anEvent.getID();
+        char undef = KeyEvent.CHAR_UNDEFINED;
+        char keyChar = (id == KeyEvent.KEY_TYPED ? anEvent.getKeyChar() :
+                                                   undef);
+        int keyCode = (keyChar == undef ? anEvent.getKeyCode() :
+                                          KeyEvent.VK_UNDEFINED);
+        return getAWTKeyStroke(keyChar, keyCode, anEvent.getModifiersEx(),
+                               id == KeyEvent.KEY_RELEASED);
+    }
+
+    /**
+     * Gets the key event type for the AWTKeyStroke object.
+     * 
+     * @return the key event type: KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or KeyEvent.KEY_RELEASED
+     */
+    public final int getKeyEventType() {
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            return KeyEvent.KEY_TYPED;
+        }
+        return (onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED);
+    }
+
+    /**
+     * Retuns true if the key event is associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     * 
+     * @return true, if if the key event associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     */
+    public final boolean isOnKeyRelease() {
+        return onKeyRelease;
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return getAWTKeyStroke(this.keyChar, this.keyCode,
+                               this.modifiers, this.onKeyRelease);
+    }
+
+    /**
+     * Register subclass.
+     * 
+     * @param subclass the subclass
+     */
+    protected static void registerSubclass(Class<?> subclass) {
+        //???AWT
+        /*
+        if (subclass == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "subclass")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (! AWTKeyStroke.class.isAssignableFrom(subclass)) {
+            // awt.67=subclass is not derived from AWTKeyStroke
+            throw new ClassCastException(Messages.getString("awt.67")); //$NON-NLS-1$
+        }
+        try {
+            subConstructor = subclass.getDeclaredConstructor();
+            subConstructor.setAccessible(true);
+        } catch (SecurityException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            // awt.68=subclass could not be instantiated
+            throw new IllegalArgumentException(Messages.getString("awt.68")); //$NON-NLS-1$
+        }
+        cache.clear(); //flush the cache
+        */
+    }
+
+    /**
+     * Parses the modifier.
+     * 
+     * @param strMod the str mod
+     * 
+     * @return the long
+     */
+    private static long parseModifier(String strMod) {
+        long modifiers = 0l;
+        if (strMod.equals("shift")) { //$NON-NLS-1$
+            modifiers |= InputEvent.SHIFT_DOWN_MASK;
+        } else if (strMod.equals("control") || strMod.equals("ctrl")) { //$NON-NLS-1$ //$NON-NLS-2$
+            modifiers |= InputEvent.CTRL_DOWN_MASK;
+        } else if (strMod.equals("meta")) { //$NON-NLS-1$
+            modifiers |= InputEvent.META_DOWN_MASK;
+        } else if (strMod.equals("alt")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_DOWN_MASK;
+        } else if (strMod.equals("altGraph")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
+        } else if (strMod.equals("button1")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
+        } else if (strMod.equals("button2")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
+        } else if (strMod.equals("button3")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+        }
+        return modifiers;
+    }
+
+    /**
+     * Parses the typed id.
+     * 
+     * @param strTyped the str typed
+     * 
+     * @return true, if successful
+     */
+    private static boolean parseTypedID(String strTyped) {
+        if (strTyped.equals("typed")) { //$NON-NLS-1$
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses the typed key.
+     * 
+     * @param strChar the str char
+     * 
+     * @return the char
+     */
+    private static char parseTypedKey(String strChar) {
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+
+        if (strChar.length() != 1) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        keyChar = strChar.charAt(0);
+        return keyChar;
+    }
+
+    /**
+     * Parses the pressed released id.
+     * 
+     * @param str the str
+     * 
+     * @return the boolean
+     */
+    private static Boolean parsePressedReleasedID(String str) {
+
+        if (str.equals("pressed")) { //$NON-NLS-1$
+            return Boolean.FALSE;
+        } else if (str.equals("released")) { //$NON-NLS-1$
+            return Boolean.TRUE;
+        }
+        return null;
+    }
+
+    /**
+     * Parses the key.
+     * 
+     * @param strCode the str code
+     * 
+     * @return the int
+     */
+    private static int parseKey(String strCode) {
+        int keyCode = KeyEvent.VK_UNDEFINED;
+
+        keyCode = getKeyCode(strCode);
+
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        return keyCode;
+    }
+}
+
diff --git a/awt/java/awt/AWTListenerList.java b/awt/java/awt/AWTListenerList.java
new file mode 100644
index 0000000..3327d63
--- /dev/null
+++ b/awt/java/awt/AWTListenerList.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.util.EventListener;
+
+import org.apache.harmony.awt.ListenerList;
+
+final class AWTListenerList<T extends EventListener> extends ListenerList<T> {
+    private static final long serialVersionUID = -2622077171532840953L;
+
+    private final Component owner;
+    
+    AWTListenerList() {
+        super();
+        this.owner = null;
+    }
+
+    AWTListenerList(Component owner) {
+        super();
+        this.owner = owner;
+    }
+
+    @Override
+    public void addUserListener(T listener) {
+        super.addUserListener(listener);
+
+        if (owner != null) {
+            owner.deprecatedEventHandler = false;
+        }
+    }
+}
diff --git a/awt/java/awt/AWTPermission.java b/awt/java/awt/AWTPermission.java
new file mode 100644
index 0000000..25326ab
--- /dev/null
+++ b/awt/java/awt/AWTPermission.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.security.BasicPermission;
+
+/**
+ * The AWTPermission specifies the name of the permission and the 
+ * corresponding action list.
+ */
+public final class AWTPermission extends BasicPermission {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8890392402588814465L;
+
+    /**
+     * Instantiates a new AWTPermission with defined name and actions.
+     * 
+     * @param name the name of a new AWTPermission. 
+     * @param actions the actions of a new AWTPermission.
+     */
+    public AWTPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /**
+     * Instantiates a new AWT permission with the defined name.
+     * 
+     * @param name the name of a new AWTPermission. 
+     */
+    public AWTPermission(String name) {
+        super(name);
+    }
+
+}
+
diff --git a/awt/java/awt/ActiveEvent.java b/awt/java/awt/ActiveEvent.java
new file mode 100644
index 0000000..4133752
--- /dev/null
+++ b/awt/java/awt/ActiveEvent.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * This interface defines events that know how to dispatch themselves. 
+ * Such event can be placed upon the event queue and its dispatch method 
+ * will be called when the event is dispatched.
+ */
+public interface ActiveEvent {
+
+    /**
+     * Dispatches the event to the listeners of the event's source, 
+     * or does whatever it is this event is supposed to do.
+     */
+    public void dispatch();
+
+}
diff --git a/awt/java/awt/Adjustable.java b/awt/java/awt/Adjustable.java
new file mode 100644
index 0000000..3241cad
--- /dev/null
+++ b/awt/java/awt/Adjustable.java
@@ -0,0 +1,156 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+
+/**
+ * The Adjustable interface represents an adjustable numeric value 
+ * contained within a bounded range of values, such as the current 
+ * location in scrollable region or the value of a gauge.
+ */
+public interface Adjustable {
+
+    /** 
+     * The Constant HORIZONTAL indicates that the Adjustable's orientation 
+     * is horizontal. 
+     */
+    public static final int HORIZONTAL = 0;
+
+    /** 
+     * The Constant VERTICAL indicates that the Adjustable's orientation 
+     * is vertical. 
+     */
+    public static final int VERTICAL = 1;
+
+    /** 
+     * The Constant NO_ORIENTATION indicates that the Adjustable 
+     * has no orientation.
+     */
+    public static final int NO_ORIENTATION = 2;
+
+    /**
+     * Gets the value of the Adjustable.
+     * 
+     * @return the current value of the Adjustable.
+     */
+    public int getValue();
+
+    /**
+     * Sets the value to the Adjustable object.
+     * 
+     * @param a0 the new value of the Adjustable object. 
+     */
+    public void setValue(int a0);
+
+    /**
+     * Adds the AdjustmentListener to current Adjustment.
+     * 
+     * @param a0 the AdjustmentListener object.
+     */
+    public void addAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Gets the block increment of the Adjustable.
+     * 
+     * @return the block increment of the Adjustable.
+     */
+    public int getBlockIncrement();
+
+    /**
+     * Gets the maximum value of the Adjustable.
+     * 
+     * @return the maximum value of the Adjustable.
+     */
+    public int getMaximum();
+
+    /**
+     * Gets the minimum value of the Adjustable.
+     * 
+     * @return the minimum value of the Adjustable. 
+     */
+    public int getMinimum();
+
+    /**
+     * Gets the orientation of the Adjustable.
+     * 
+     * @return the orientation of the Adjustable.
+     */
+    public int getOrientation();
+
+    /**
+     * Gets the unit increment of the Adjustable.
+     * 
+     * @return the unit increment of the Adjustable.
+     */
+    public int getUnitIncrement();
+
+    /**
+     * Gets the visible amount of the Adjustable.
+     * 
+     * @return the visible amount of the Adjustable.
+     */
+    public int getVisibleAmount();
+
+    /**
+     * Removes the adjustment listener of the Adjustable.
+     * 
+     * @param a0 the specified AdjustmentListener to be removed.
+     */
+    public void removeAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Sets the block increment for the Adjustable.
+     * 
+     * @param a0 the new block increment.
+     */
+    public void setBlockIncrement(int a0);
+
+    /**
+     * Sets the maximum value of the Adjustable.
+     * 
+     * @param a0 the new maximum of the Adjustable.
+     */
+    public void setMaximum(int a0);
+
+    /**
+     * Sets the minimum value of the Adjustable.
+     * 
+     * @param a0 the new minimum of the Adjustable.
+     */
+    public void setMinimum(int a0);
+
+    /**
+     * Sets the unit increment of the Adjustable.
+     * 
+     * @param a0 the new unit increment of the Adjustable.
+     */
+    public void setUnitIncrement(int a0);
+
+    /**
+     * Sets the visible amount of the Adjustable.
+     * 
+     * @param a0 the new visible amount of the Adjustable.
+     */
+    public void setVisibleAmount(int a0);
+
+}
+
diff --git a/awt/java/awt/AlphaComposite.java b/awt/java/awt/AlphaComposite.java
new file mode 100644
index 0000000..d26753c
--- /dev/null
+++ b/awt/java/awt/AlphaComposite.java
@@ -0,0 +1,315 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.gl.ICompositeContext;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The AlphaComposite class defines a basic alpha compositing rules for 
+ * combining source and destination colors to achieve blending and 
+ * transparency effects with graphics and images.
+ */
+public final class AlphaComposite implements Composite {
+
+    /** 
+     * The Constant CLEAR indicates that both the color and the alpha of 
+     * the destination are cleared (Porter-Duff Clear rule).
+     */
+    public static final int CLEAR = 1;
+
+    /** 
+     * The Constant SRC indicates that the source is copied to the destination 
+     * (Porter-Duff Source rule).
+     */
+    public static final int SRC = 2;
+
+    /** The Constant DST indicates that the destination is left untouched 
+     * (Porter-Duff Destination rule).
+     */
+    public static final int DST = 9;
+
+    /** 
+     * The Constant SRC_OVER indicates that the source is composited over 
+     * the destination (Porter-Duff Source Over Destination rule).
+     */
+    public static final int SRC_OVER = 3;
+
+    /**
+     * The Constant DST_OVER indicates that The destination is composited over 
+     * the source and the result replaces the destination 
+     * (Porter-Duff Destination Over Source rule).
+     */
+    public static final int DST_OVER = 4;
+
+    /**
+     * The Constant SRC_IN indicates that the part of the source lying 
+     * inside of the destination replaces the destination (Porter-Duff 
+     * Source In Destination rule).
+     */
+    public static final int SRC_IN = 5;
+
+    /** 
+     * The Constant DST_IN indicates that the part of the destination 
+     * lying inside of the source replaces the destination 
+     * (Porter-Duff Destination In Source rule).
+     */
+    public static final int DST_IN = 6;
+
+    /**
+     * The Constant SRC_OUT indicates that the part of the source lying 
+     * outside of the destination replaces the destination (Porter-Duff 
+     * Source Held Out By Destination rule).
+     */
+    public static final int SRC_OUT = 7;
+
+    /** 
+     * The Constant DST_OUT indicates that the part of the destination 
+     * lying outside of the source replaces the destination (Porter-Duff 
+     * Destination Held Out By Source rule).
+     */
+    public static final int DST_OUT = 8;
+
+    /** 
+     * The Constant SRC_ATOP indicates that the part of the source lying 
+     * inside of the destination is composited onto the destination 
+     * (Porter-Duff Source Atop Destination rule).
+     */
+    public static final int SRC_ATOP = 10;
+
+    /** 
+     * The Constant DST_ATOP indicates that the part of the destination 
+     * lying inside of the source is composited over the source and replaces 
+     * the destination (Porter-Duff Destination Atop Source rule).
+     */
+    public static final int DST_ATOP = 11;
+
+    /**
+     * The Constant XOR indicates that the part of the source that lies 
+     * outside of the destination is combined with the part of the destination 
+     * that lies outside of the source (Porter-Duff Source Xor Destination rule).
+     */
+    public static final int XOR = 12;
+
+    /** AlphaComposite object with the opaque CLEAR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
+
+    /** AlphaComposite object with the opaque SRC rule and an alpha of 1.0f. */
+    public static final AlphaComposite Src = new AlphaComposite(SRC);
+
+    /** AlphaComposite object with the opaque DST rule and an alpha of 1.0f. */
+    public static final AlphaComposite Dst = new AlphaComposite(DST);
+
+    /** AlphaComposite object with the opaque SRC_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
+
+    /** AlphaComposite object with the opaque DST_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
+
+    /** AlphaComposite object with the opaque SRC_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
+
+    /** AlphaComposite object with the opaque DST_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
+
+    /** AlphaComposite object with the opaque SRC_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
+
+    /** AlphaComposite object with the opaque DST_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
+
+    /** AlphaComposite object with the opaque SRC_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
+
+    /** AlphaComposite object with the opaque DST_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
+
+    /** AlphaComposite object with the opaque XOR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Xor = new AlphaComposite(XOR);
+
+    /** The rule. */
+    private int rule;
+    
+    /** The alpha. */
+    private float alpha;
+
+    /**
+     * Instantiates a new alpha composite.
+     * Creates a context for the compositing operation. The context contains state that is used in performing the compositing operation.
+     * 
+     * @param rule the rule
+     * @param alpha the alpha
+     */
+    private AlphaComposite(int rule, float alpha){
+        if(rule < CLEAR || rule > XOR) {
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+        if(alpha < 0.0f || alpha > 1.0f) {
+            // awt.11E=Wrong alpha value
+            throw new IllegalArgumentException(Messages.getString("awt.11E")); //$NON-NLS-1$
+        }
+
+        this.rule = rule;
+        this.alpha = alpha;
+    }
+
+    /**
+     * Instantiates a new alpha composite.
+     * 
+     * @param rule the rule
+     */
+    private AlphaComposite(int rule){
+        this(rule, 1.0f);
+    }
+
+    /**
+     * Creates a CompositeContext object with the specified source ColorModel,
+     * destination ColorModel and RenderingHints parameters for a composing 
+     * operation.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints object.
+     * 
+     * @return the CompositeContext object.    
+     * 
+     * @see java.awt.Composite#createContext(java.awt.image.ColorModel, java.awt.image.ColorModel, java.awt.RenderingHints)
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints) {
+        return new ICompositeContext(this, srcColorModel, dstColorModel);
+    }
+
+    /**
+     * Compares the AlphaComposite object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the AlphaComposite object is equal to the specified
+     * object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(!(obj instanceof AlphaComposite)) {
+            return false;
+        }
+        AlphaComposite other = (AlphaComposite)obj;
+        return (this.rule == other.getRule() && this.alpha == other.getAlpha());
+    }
+
+    /**
+     * Returns the hash code of the AlphaComposite object.
+     * 
+     * @return the hash code of the AlphaComposite object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = Float.floatToIntBits(alpha);
+        int tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= rule;
+        return hash;
+    }
+
+    /**
+     * Gets the compositing rule of this AlphaComposite object.
+     * 
+     * @return the compositing rule of this AlphaComposite object.
+     */
+    public int getRule() {
+        return rule;
+    }
+
+    /**
+     * Gets the alpha value of this AlphaComposite object; returns 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     * 
+     * @return the alpha value of this AlphaComposite object or 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     */
+    public float getAlpha() {
+        return alpha;
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule and alpha value.
+     * 
+     * @param rule the compositing rule.
+     * @param alpha the alpha value.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule, float alpha) {
+        if(alpha == 1.0f) {
+            return getInstance(rule);
+        }
+        return new AlphaComposite(rule, alpha);
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule.
+     * 
+     * @param rule the compositing rule.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule) {
+        switch(rule){
+        case CLEAR:
+            return Clear;
+        case SRC:
+            return Src;
+        case DST:
+            return Dst;
+        case SRC_OVER:
+            return SrcOver;
+        case DST_OVER:
+            return DstOver;
+        case SRC_IN:
+            return SrcIn;
+        case DST_IN:
+            return DstIn;
+        case SRC_OUT:
+            return SrcOut;
+        case DST_OUT:
+            return DstOut;
+        case SRC_ATOP:
+            return SrcAtop;
+        case DST_ATOP:
+            return DstAtop;
+        case XOR:
+            return Xor;
+        default:
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/BasicStroke.java b/awt/java/awt/BasicStroke.java
new file mode 100644
index 0000000..955dc6b
--- /dev/null
+++ b/awt/java/awt/BasicStroke.java
@@ -0,0 +1,2204 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The BasicStroke class specifies a set of rendering attributes for the outlines 
+ * of graphics primitives. The BasicStroke attributes describe the shape of the 
+ * pen which draws the outline of a Shape and the decorations applied at the ends
+ * and joins of path segments of the Shape. The BasicStroke has the following
+ * rendering attributes:
+ * <p>
+ * <ul>
+ * <li> line width -the pen width which draws the outlines.</li>
+ * <li> end caps - indicates the decoration applied to the ends of unclosed 
+ * subpaths and dash segments. The BasicStroke defines three different decorations:
+ * CAP_BUTT, CAP_ROUND, and CAP_SQUARE.</li>
+ * <li>line joins - indicates the decoration applied at the intersection of 
+ * two path segments and at the intersection of the endpoints of a subpath.
+ * The BasicStroke defines three decorations: JOIN_BEVEL, JOIN_MITER, 
+ * and JOIN_ROUND.</li>
+ * <li>miter limit - the limit to trim a line join that has a JOIN_MITER 
+ * decoration.</li>
+ * <li>dash attributes - the definition of how to make a dash pattern by 
+ * alternating between opaque and transparent sections </li>
+ * </ul>
+ */
+public class BasicStroke implements Stroke {
+
+    /** 
+     * The Constant CAP_BUTT indicates the ends of unclosed subpaths 
+     * and dash segments have no added decoration.
+     */
+    public static final int CAP_BUTT = 0;
+    
+    /** 
+     * The Constant CAP_ROUND indicates the ends of unclosed subpaths 
+     * and dash segments have a round decoration.
+     */
+    public static final int CAP_ROUND = 1;
+    
+    /** 
+     * The Constant CAP_SQUARE indicates the ends of unclosed subpaths 
+     * and dash segments have a square projection.
+     */
+    public static final int CAP_SQUARE = 2;
+
+    /** 
+     * The Constant JOIN_MITER indicates that path segments are joined by 
+     * extending their outside edges until they meet.
+     */
+    public static final int JOIN_MITER = 0;
+    
+    /** 
+     * The Constant JOIN_ROUND indicates that path segments are joined by 
+     * rounding off the corner at a radius of half the line width.
+     */
+    public static final int JOIN_ROUND = 1;
+    
+    /** 
+     * The Constant JOIN_BEVEL indicates that path segments are joined by 
+     * connecting the outer corners of their wide outlines with 
+     * a straight segment.
+     */
+    public static final int JOIN_BEVEL = 2;
+    
+    /** Constants for calculating. */
+    static final int MAX_LEVEL = 20;        // Maximal deepness of curve subdivision
+    
+    /** The Constant CURVE_DELTA. */
+    static final double CURVE_DELTA = 2.0;  // Width tolerance
+    
+    /** The Constant CORNER_ANGLE. */
+    static final double CORNER_ANGLE = 4.0; // Minimum corner angle
+    
+    /** The Constant CORNER_ZERO. */
+    static final double CORNER_ZERO = 0.01; // Zero angle
+    
+    /** The Constant CUBIC_ARC. */
+    static final double CUBIC_ARC = 4.0 / 3.0 * (Math.sqrt(2.0) - 1);
+
+    /** Stroke width. */
+    float width;
+    
+    /** Stroke cap type. */
+    int cap;
+    
+    /** Stroke join type. */
+    int join;
+    
+    /** Stroke miter limit. */
+    float miterLimit;
+    
+    /** Stroke dashes array. */
+    float dash[];
+    
+    /** Stroke dash phase. */
+    float dashPhase;
+
+    /** The temporary pre-calculated values. */
+    double curveDelta;
+    
+    /** The corner delta. */
+    double cornerDelta;
+    
+    /** The zero delta. */
+    double zeroDelta;
+
+    /** The w2. */
+    double w2;
+    
+    /** The fmy. */
+    double fmx, fmy;
+    
+    /** The smy. */
+    double scx, scy, smx, smy;
+    
+    /** The cy. */
+    double mx, my, cx, cy;
+
+    /** The temporary indicators. */
+    boolean isMove;
+    
+    /** The is first. */
+    boolean isFirst;
+    
+    /** The check move. */
+    boolean checkMove;
+    
+    /** The temporary and destination work paths. */
+    BufferedPath dst, lp, rp, sp;
+    
+    /** Stroke dasher class. */
+    Dasher dasher;
+
+    /**
+     * Instantiates a new BasicStroke with default width, cap, join, limit,
+     * dash attributes parameters. The default parameters are a solid line of 
+     * width 1.0, CAP_SQUARE, JOIN_MITER, a miter limit of 10.0, null dash attributes,
+     * and a dash phase of 0.0f.
+     */
+    public BasicStroke() {
+        this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with the specified width,  
+     * caps, joins, limit, dash attributes, dash phase parameters.
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     * @param dash the array with the dashing pattern.
+     * @param dashPhase the offset to start the dashing pattern.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit, float[] dash, float dashPhase) {
+        if (width < 0.0f) {
+            // awt.133=Negative width
+            throw new IllegalArgumentException(Messages.getString("awt.133")); //$NON-NLS-1$
+        }
+        if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
+            // awt.134=Illegal cap
+            throw new IllegalArgumentException(Messages.getString("awt.134")); //$NON-NLS-1$
+        }
+        if (join != JOIN_MITER && join != JOIN_ROUND && join != JOIN_BEVEL) {
+            // awt.135=Illegal join
+            throw new IllegalArgumentException(Messages.getString("awt.135")); //$NON-NLS-1$
+        }
+        if (join == JOIN_MITER && miterLimit < 1.0f) {
+            // awt.136=miterLimit less than 1.0f
+            throw new IllegalArgumentException(Messages.getString("awt.136")); //$NON-NLS-1$
+        }
+        if (dash != null) {
+            if (dashPhase < 0.0f) {
+                // awt.137=Negative dashPhase
+                throw new IllegalArgumentException(Messages.getString("awt.137")); //$NON-NLS-1$
+            }
+            if (dash.length == 0) {
+                // awt.138=Zero dash length
+                throw new IllegalArgumentException(Messages.getString("awt.138")); //$NON-NLS-1$
+            }
+            ZERO: {
+                for(int i = 0; i < dash.length; i++) {
+                    if (dash[i] < 0.0) {
+                        // awt.139=Negative dash[{0}]
+                        throw new IllegalArgumentException(Messages.getString("awt.139", i)); //$NON-NLS-1$
+                    }
+                    if (dash[i] > 0.0) {
+                        break ZERO;
+                    }
+                }
+                // awt.13A=All dash lengths zero
+                throw new IllegalArgumentException(Messages.getString("awt.13A")); //$NON-NLS-1$
+            }
+        }
+        this.width = width;
+        this.cap = cap;
+        this.join = join;
+        this.miterLimit = miterLimit;
+        this.dash = dash;
+        this.dashPhase = dashPhase;
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join, limit
+     * and default dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit) {
+        this(width, cap, join, miterLimit, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join
+     * and default limit and dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     */
+    public BasicStroke(float width, int cap, int join) {
+        this(width, cap, join, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width and default cap, join,
+     * limit, dash attributes parameters.
+     * 
+     * @param width the width of BasicStroke.
+     */
+    public BasicStroke(float width) {
+        this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Gets the line width of the BasicStroke.
+     * 
+     * @return the line width of the BasicStroke.
+     */
+    public float getLineWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the end cap style of the BasicStroke.
+     * 
+     * @return the end cap style of the BasicStroke.
+     */
+    public int getEndCap() {
+        return cap;
+    }
+
+    /**
+     * Gets the line join style of the BasicStroke.
+     * 
+     * @return the line join style of the BasicStroke.
+     */
+    public int getLineJoin() {
+        return join;
+    }
+
+    /**
+     * Gets the miter limit of the BasicStroke (the limit to trim the miter join).
+     * 
+     * @return the miter limit of the BasicStroke.
+     */
+    public float getMiterLimit() {
+        return miterLimit;
+    }
+
+    /**
+     * Gets the dash attributes array of the BasicStroke.
+     * 
+     * @return the dash attributes array of the BasicStroke.
+     */
+    public float[] getDashArray() {
+        return dash;
+    }
+
+    /**
+     * Gets the dash phase of the BasicStroke.
+     * 
+     * @return the dash phase of the BasicStroke.
+     */
+    public float getDashPhase() {
+        return dashPhase;
+    }
+
+    /**
+     * Returns hash code of this BasicStroke.
+     * 
+     * @return the hash code of this BasicStroke.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(cap);
+        hash.append(join);
+        hash.append(miterLimit);
+        if (dash != null) {
+            hash.append(dashPhase);
+            for (float element : dash) {
+                hash.append(element);
+            }
+        }
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this BasicStroke object with the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object is a BasicStroke with the same data
+     * values as this BasicStroke; false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof BasicStroke) {
+            BasicStroke bs = (BasicStroke)obj;
+            return
+                bs.width == width &&
+                bs.cap == cap &&
+                bs.join == join &&
+                bs.miterLimit == miterLimit &&
+                bs.dashPhase == dashPhase &&
+                java.util.Arrays.equals(bs.dash, dash);
+        }
+        return false;
+    }
+
+    /**
+     * Calculates allowable curve derivation.
+     * 
+     * @param width the width
+     * 
+     * @return the curve delta
+     */
+    double getCurveDelta(double width) {
+        double a = width + CURVE_DELTA;
+        double cos = 1.0 - 2.0 * width * width / (a * a);
+        double sin = Math.sqrt(1.0 - cos * cos);
+        return Math.abs(sin / cos);
+    }
+
+    /**
+     * Calculates the value to detect a small angle.
+     * 
+     * @param width the width
+     * 
+     * @return the corner delta
+     */
+    double getCornerDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ANGLE / 180.0);
+    }
+
+    /**
+     * Calculates value to detect a zero angle.
+     * 
+     * @param width the width
+     * 
+     * @return the zero delta
+     */
+    double getZeroDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ZERO / 180.0);
+    }
+
+    /**
+     * Creates a Shape from the outline of the specified shape 
+     * drawn with this BasicStroke.
+     * 
+     * @param s the specified Shape to be stroked.
+     * 
+     * @return the Shape of the stroked outline.
+     * 
+     * @see java.awt.Stroke#createStrokedShape(java.awt.Shape)
+     */
+    public Shape createStrokedShape(Shape s) {
+        w2 = width / 2.0;
+        curveDelta = getCurveDelta(w2);
+        cornerDelta = getCornerDelta(w2);
+        zeroDelta = getZeroDelta(w2);
+
+        dst = new BufferedPath();
+        lp = new BufferedPath();
+        rp = new BufferedPath();
+
+        if (dash == null) {
+            createSolidShape(s.getPathIterator(null));
+        } else {
+            createDashedShape(s.getPathIterator(null));
+        }
+
+        return dst.createGeneralPath();
+    }
+
+    /**
+     * Generates a shape with a solid (not dashed) outline.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createSolidShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        isMove = false;
+        isFirst = false;
+        checkMove = true;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!isClosed) {
+                    closeSolidShape();
+                }
+                rp.clean();
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                isMove = true;
+                isClosed = false;
+                break;
+            case PathIterator.SEG_LINETO:
+                addLine(cx, cy, cx = coords[0], cy = coords[1], true);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addLine(cx, cy, mx, my, false);
+                addJoin(lp, mx, my, lp.xMove, lp.yMove, true);
+                addJoin(rp, mx, my, rp.xMove, rp.yMove, false);
+                lp.closePath();
+                rp.closePath();
+                lp.appendReverse(rp);
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+        if (!isClosed) {
+            closeSolidShape();
+        }
+
+        dst = lp;
+    }
+
+    /**
+     * Closes solid shape path.
+     */
+    void closeSolidShape() {
+        addCap(lp, cx, cy, rp.xLast, rp.yLast);
+        lp.combine(rp);
+        addCap(lp, mx, my, lp.xMove, lp.yMove);
+        lp.closePath();
+    }
+
+    /**
+     * Generates dashed stroked shape.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createDashedShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        smx = smy = scx = scy = 0.0;
+        isMove = false;
+        checkMove = false;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+
+                if (!isClosed) {
+                    closeDashedShape();
+                }
+
+                dasher = new Dasher(dash, dashPhase);
+                lp.clean();
+                rp.clean();
+                sp = null;
+                isFirst = true;
+                isMove = true;
+                isClosed = false;
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                addDashLine(cx, cy, cx = coords[0], cy = coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addDashQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addDashCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addDashLine(cx, cy, cx = mx, cy = my);
+
+                if (dasher.isConnected()) {
+                    // Connect current and head segments
+                    addJoin(lp, fmx, fmy, sp.xMove, sp.yMove, true);
+                    lp.join(sp);
+                    addJoin(lp, fmx, fmy, rp.xLast, rp.yLast, true);
+                    lp.combine(rp);
+                    addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                    lp.closePath();
+                    dst.append(lp);
+                    sp = null;
+                } else {
+                    closeDashedShape();
+                }
+
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+
+        if (!isClosed) {
+            closeDashedShape();
+        }
+
+    }
+
+    /**
+     * Closes dashed shape path.
+     */
+    void closeDashedShape() {
+        // Add head segment
+        if (sp != null) {
+            addCap(sp, fmx, fmy, sp.xMove, sp.yMove);
+            sp.closePath();
+            dst.append(sp);
+        }
+        if (lp.typeSize > 0) {
+            // Close current segment
+            if (!dasher.isClosed()) {
+                addCap(lp, scx, scy, rp.xLast, rp.yLast);
+                lp.combine(rp);
+                addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                lp.closePath();
+            }
+            dst.append(lp);
+        }
+    }
+
+    /**
+     * Adds cap to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     */
+    void addCap(BufferedPath p, double x0, double y0, double x2, double y2) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        switch(cap) {
+        case CAP_BUTT:
+            p.lineTo(x2, y2);
+            break;
+        case CAP_ROUND:
+            double mx = x10 * CUBIC_ARC;
+            double my = y10 * CUBIC_ARC;
+
+            double x3 = x0 + y10;
+            double y3 = y0 - x10;
+
+            x10 *= CUBIC_ARC;
+            y10 *= CUBIC_ARC;
+            x20 *= CUBIC_ARC;
+            y20 *= CUBIC_ARC;
+
+            p.cubicTo(x1 + y10, y1 - x10, x3 + mx, y3 + my, x3, y3);
+            p.cubicTo(x3 - mx, y3 - my, x2 - y20, y2 + x20, x2, y2);
+            break;
+        case CAP_SQUARE:
+            p.lineTo(x1 + y10, y1 - x10);
+            p.lineTo(x2 - y20, y2 + x20);
+            p.lineTo(x2, y2);
+            break;
+        }
+    }
+
+    /**
+     * Adds bevel and miter join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+        double sin0 = x10 * y20 - y10 * x20;
+
+        // Small corner
+        if (-cornerDelta < sin0 && sin0 < cornerDelta) {
+            double cos0 = x10 * x20 + y10 * y20;
+            if (cos0 > 0.0) {
+                // if zero corner do nothing
+                if (-zeroDelta > sin0 || sin0 > zeroDelta) {
+                    double x3 = x0 + w2 * w2 * (y20 - y10) / sin0;
+                    double y3 = y0 + w2 * w2 * (x10 - x20) / sin0;
+                    p.setLast(x3, y3);
+                }
+                return;
+            }
+            // Zero corner
+            if (-zeroDelta < sin0 && sin0 < zeroDelta) {
+                p.lineTo(x2, y2);
+            }
+            return;
+        }
+
+        if (isLeft ^ (sin0 < 0.0)) {
+            // Twisted corner
+            p.lineTo(x0, y0);
+            p.lineTo(x2, y2);
+        } else {
+            switch(join) {
+            case JOIN_BEVEL:
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_MITER:
+                double s1 = x1 * x10 + y1 * y10;
+                double s2 = x2 * x20 + y2 * y20;
+                double x3 = (s1 * y20 - s2 * y10) / sin0;
+                double y3 = (s2 * x10 - s1 * x20) / sin0;
+                double x30 = x3 - x0;
+                double y30 = y3 - y0;
+                double miterLength = Math.sqrt(x30 * x30 + y30 * y30);
+                if (miterLength < miterLimit * w2) {
+                    p.lineTo(x3, y3);
+                }
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_ROUND:
+                addRoundJoin(p, x0, y0, x2, y2, isLeft);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Adds round join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addRoundJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        double x30 = x10 + x20;
+        double y30 = y10 + y20;
+
+        double l30 = Math.sqrt(x30 * x30 + y30 * y30);
+
+        if (l30 < 1E-5) {
+            p.lineTo(x2, y2);
+            return;
+        }
+
+        double w = w2 / l30;
+
+        x30 *= w;
+        y30 *= w;
+
+        double x3 = x0 + x30;
+        double y3 = y0 + y30;
+
+        double cos = x10 * x20 + y10 * y20;
+        double a = Math.acos(cos / (w2 * w2));
+        if (cos >= 0.0) {
+            double k = 4.0 / 3.0 * Math.tan(a / 4.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x2 + y20, y2 - x20, x2, y2);
+        } else {
+            double k = 4.0 / 3.0 * Math.tan(a / 8.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+            x30 *= k;
+            y30 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x3 + y30, y3 - x30, x3, y3);
+            p.cubicTo(x3 - y30, y3 + x30, x2 + y20, y2 - x20, x2, y2);
+        }
+
+    }
+
+    /**
+     * Adds solid line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     * @param zero - if true it's allowable to add zero length line segment
+     */
+    void addLine(double x1, double y1, double x2, double y2, boolean zero) {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+
+        if (dx == 0.0 && dy == 0.0) {
+            if (!zero) {
+                return;
+            }
+            dx = w2;
+            dy = 0;
+        } else {
+            double w = w2 / Math.sqrt(dx * dx + dy * dy);
+            dx *= w;
+            dy *= w;
+        }
+
+        double lx1 = x1 - dy;
+        double ly1 = y1 + dx;
+        double rx1 = x1 + dy;
+        double ry1 = y1 - dx;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        lp.lineTo(x2 - dy, y2 + dx);
+        rp.lineTo(x2 + dy, y2 - dx);
+    }
+
+    /**
+     * Adds solid quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            addLine(x1, y1, x3, y3, false);
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        double w;
+        w = w2 / l21;
+        double mx1 = - y21 * w;
+        double my1 =   x21 * w;
+        w = w2 / l23;
+        double mx3 =   y23 * w;
+        double my3 = - x23 * w;
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (x21 * y23 - y21 * x23 == 0.0) {
+            // On line curve
+            if (x21 * x23 + y21 * y23 > 0.0) {
+                // Twisted curve
+                if (l21 == l23) {
+                    double px = x1 + (x21 + x23) / 4.0;
+                    double py = y1 + (y21 + y23) / 4.0;
+                    lp.lineTo(px + mx1, py + my1);
+                    rp.lineTo(px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    lp.lineTo(x3 - mx1, y3 - my1);
+                    rp.lineTo(x3 + mx1, y3 + my1);
+                } else {
+                    double px1, py1;
+                    double k = l21 / (l21 + l23);
+                    double px = x1 + (x21 + x23) * k * k;
+                    double py = y1 + (y21 + y23) * k * k;
+                    px1 = (x1 + px) / 2.0;
+                    py1 = (y1 + py) / 2.0;
+                    lp.quadTo(px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.quadTo(px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    px1 = (x3 + px) / 2.0;
+                    py1 = (y3 + py) / 2.0;
+                    lp.quadTo(px1 - mx1, py1 - my1, x3 - mx1, y3 - my1);
+                    rp.quadTo(px1 + mx1, py1 + my1, x3 + mx1, y3 + my1);
+                }
+            } else {
+                // Simple curve
+                lp.quadTo(x2 + mx1, y2 + my1, x3 + mx3, y3 + my3);
+                rp.quadTo(x2 - mx1, y2 - my1, x3 - mx3, y3 - my3);
+            }
+        } else {
+            addSubQuad(x1, y1, x2, y2, x3, y3, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid quad curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubQuad(double x1, double y1, double x2, double y2, double x3, double y3, int level) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double cos = x21 * x23 + y21 * y23;
+        double sin = x21 * y23 - y21 * x23;
+
+        if (level < MAX_LEVEL && (cos >= 0.0 || (Math.abs(sin / cos) > curveDelta))) {
+            double c1x = (x2 + x1) / 2.0;
+            double c1y = (y2 + y1) / 2.0;
+            double c2x = (x2 + x3) / 2.0;
+            double c2y = (y2 + y3) / 2.0;
+            double c3x = (c1x + c2x) / 2.0;
+            double c3y = (c1y + c2y) / 2.0;
+            addSubQuad(x1, y1, c1x, c1y, c3x, c3y, level + 1);
+            addSubQuad(c3x, c3y, c2x, c2y, x3, y3, level + 1);
+        } else {
+            double w;
+            double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            w = w2 / sin;
+            double mx2 = (x21 * l23 + x23 * l21) * w;
+            double my2 = (y21 * l23 + y23 * l21) * w;
+            w = w2 / l23;
+            double mx3 =   y23 * w;
+            double my3 = - x23 * w;
+            lp.quadTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3);
+            rp.quadTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3);
+        }
+    }
+
+    /**
+     * Adds solid cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x4, y4, false);
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addLine(x3, y3, x4, y4, false);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        double w, mx1, my1, mx4, my4;
+        boolean onLine;
+
+        if (l12 == 0.0) {
+            w = w2 / l23;
+            mx1 =   y23 * w;
+            my1 = - x23 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            onLine = - x23 * y34 + y23 * x34 == 0.0; // sin3
+        } else
+        if (l34 == 0.0) {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l23;
+            mx4 =   y23 * w;
+            my4 = - x23 * w;
+            onLine = - x12 * y23 + y12 * x23 == 0.0; // sin2
+        } else {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            if (l23 == 0.0) {
+                onLine = - x12 * y34 + y12 * x34 == 0.0;
+            } else {
+                onLine =
+                    - x12 * y34 + y12 * x34 == 0.0 &&
+                    - x12 * y23 + y12 * x23 == 0.0 && // sin2
+                    - x23 * y34 + y23 * x34 == 0.0;   // sin3
+            }
+        }
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (onLine) {
+            if ((x1 == x2 && y1 < y2) || x1 < x2) {
+                l12 = -l12;
+            }
+            if ((x2 == x3 && y2 < y3) || x2 < x3) {
+                l23 = -l23;
+            }
+            if ((x3 == x4 && y3 < y4) || x3 < x4) {
+                l34 = -l34;
+            }
+            double d = l23 * l23 - l12 * l34;
+            double roots[] = new double[3];
+            int rc = 0;
+            if (d == 0.0) {
+                double t = (l12 - l23) / (l12 + l34 - l23 - l23);
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            } else
+            if (d > 0.0) {
+                d = Math.sqrt(d);
+                double z = l12 + l34 - l23 - l23;
+                double t;
+                t = (l12 - l23 + d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+                t = (l12 - l23 - d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            }
+
+            if (rc > 0) {
+                // Sort roots
+                if (rc == 2 && roots[0] > roots[1]) {
+                    double tmp = roots[0];
+                    roots[0] = roots[1];
+                    roots[1] = tmp;
+                }
+                roots[rc++] = 1.0;
+
+                double ax = - x34 - x12 + x23 + x23;
+                double ay = - y34 - y12 + y23 + y23;
+                double bx = 3.0 * (- x23 + x12);
+                double by = 3.0 * (- y23 + y12);
+                double cx = 3.0 * (- x12);
+                double cy = 3.0 * (- y12);
+                double xPrev = x1;
+                double yPrev = y1;
+                for(int i = 0; i < rc; i++) {
+                    double t = roots[i];
+                    double px = t * (t * (t * ax + bx) + cx) + x1;
+                    double py = t * (t * (t * ay + by) + cy) + y1;
+                    double px1 = (xPrev + px) / 2.0;
+                    double py1 = (yPrev + py) / 2.0;
+                    lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    if (i < rc - 1) {
+                        lp.lineTo(px - mx1, py - my1);
+                        rp.lineTo(px + mx1, py + my1);
+                    }
+                    xPrev = px;
+                    yPrev = py;
+                    mx1 = - mx1;
+                    my1 = - my1;
+                }
+            } else {
+                lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
+                rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
+            }
+        } else {
+            addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid cubic curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, int level) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double cos2 = - x12 * x23 - y12 * y23;
+        double cos3 = - x23 * x34 - y23 * y34;
+        double sin2 = - x12 * y23 + y12 * x23;
+        double sin3 = - x23 * y34 + y23 * x34;
+        double sin0 = - x12 * y34 + y12 * x34;
+        double cos0 = - x12 * x34 - y12 * y34;
+
+        if (level < MAX_LEVEL && (sin2 != 0.0 || sin3 != 0.0 || sin0 != 0.0) &&
+            (cos2 >= 0.0 || cos3 >= 0.0 || cos0 >= 0.0 ||
+            (Math.abs(sin2 / cos2) > curveDelta) ||
+            (Math.abs(sin3 / cos3) > curveDelta) ||
+            (Math.abs(sin0 / cos0) > curveDelta)))
+        {
+            double cx = (x2 + x3) / 2.0;
+            double cy = (y2 + y3) / 2.0;
+            double lx2 = (x2 + x1) / 2.0;
+            double ly2 = (y2 + y1) / 2.0;
+            double rx3 = (x3 + x4) / 2.0;
+            double ry3 = (y3 + y4) / 2.0;
+            double lx3 = (cx + lx2) / 2.0;
+            double ly3 = (cy + ly2) / 2.0;
+            double rx2 = (cx + rx3) / 2.0;
+            double ry2 = (cy + ry3) / 2.0;
+            cx = (lx3 + rx2) / 2.0;
+            cy = (ly3 + ry2) / 2.0;
+            addSubCubic(x1, y1, lx2, ly2, lx3, ly3, cx, cy, level + 1);
+            addSubCubic(cx, cy, rx2, ry2, rx3, ry3, x4, y4, level + 1);
+        } else {
+            double w, mx1, my1, mx2, my2, mx3, my3, mx4, my4;
+            double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+            if (l12 == 0.0) {
+                w = w2 / l23;
+                mx1 =   y23 * w;
+                my1 = - x23 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            } else
+            if (l34 == 0.0) {
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l23;
+                mx4 =   y23 * w;
+                my4 = - x23 * w;
+            } else {
+                // Common case
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            }
+
+            if (sin2 == 0.0) {
+                mx2 = mx1;
+                my2 = my1;
+            } else {
+                w = w2 / sin2;
+                mx2 = -(x12 * l23 - x23 * l12) * w;
+                my2 = -(y12 * l23 - y23 * l12) * w;
+            }
+            if (sin3 == 0.0) {
+                mx3 = mx4;
+                my3 = my4;
+            } else {
+                w = w2 / sin3;
+                mx3 = -(x23 * l34 - x34 * l23) * w;
+                my3 = -(y23 * l34 - y34 * l23) * w;
+            }
+
+            lp.cubicTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3, x4 + mx4, y4 + my4);
+            rp.cubicTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3, x4 - mx4, y4 - my4);
+        }
+    }
+
+    /**
+     * Adds dashed line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     */
+    void addDashLine(double x1, double y1, double x2, double y2) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+
+        if (l21 == 0.0) {
+            return;
+        }
+
+        double px1, py1;
+        px1 = py1 = 0.0;
+        double w = w2 / l21;
+        double mx = - y21 * w;
+        double my =   x21 * w;
+
+        dasher.init(new DashIterator.Line(l21));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            scx = x1 + t * x21;
+            scy = y1 + t * y21;
+
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double lx1 = px1 + mx;
+                double ly1 = py1 + my;
+                double rx1 = px1 - mx;
+                double ry1 = py1 - my;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else
+                if (dasher.isContinue()) {
+                    double px2 = scx;
+                    double py2 = scy;
+                    lp.lineTo(px2 + mx, py2 + my);
+                    rp.lineTo(px2 - mx, py2 - my);
+                    if (dasher.close) {
+                        addCap(lp, px2, py2, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addDashQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        double ax = x1 + x3 - x2 - x2;
+        double ay = y1 + y3 - y2 - y2;
+        double bx = x2 - x1;
+        double by = y2 - y1;
+        double cx = x1;
+        double cy = y1;
+
+        double px1, py1, dx1, dy1;
+        px1 = py1 = dx1 = dy1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Quad(x1, y1, x2, y2, x3, y3));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            double dx = t * ax + bx;
+            double dy = t * ay + by;
+            scx = t * (dx + bx) + cx; // t^2 * ax + 2.0 * t * bx + cx
+            scy = t * (dy + by) + cy; // t^2 * ay + 2.0 * t * by + cy
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                dx1 = dx;
+                dy1 = dy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double px3 = scx;
+                    double py3 = scy;
+                    double sx = x2 - x23 * prev;
+                    double sy = y2 - y23 * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double px2 = px1 + (sx - px1) * t2;
+                    double py2 = py1 + (sy - py1) * t2;
+
+                    addQuad(px1, py1, px2, py2, px3, py3);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px3, py3, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addDashCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            // NOTHING
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addDashLine(x3, y3, x4, y4);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        double ax = x4 - x1 + 3.0 * (x2 - x3);
+        double ay = y4 - y1 + 3.0 * (y2 - y3);
+        double bx = 3.0 * (x1 + x3 - x2 - x2);
+        double by = 3.0 * (y1 + y3 - y2 - y2);
+        double cx = 3.0 * (x2 - x1);
+        double cy = 3.0 * (y2 - y1);
+        double dx = x1;
+        double dy = y1;
+
+        double px1 = 0.0;
+        double py1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Cubic(x1, y1, x2, y2, x3, y3, x4, y4));
+
+        while(!dasher.eof()) {
+
+            double t = dasher.getValue();
+            scx = t * (t * (t * ax + bx) + cx) + dx;
+            scy = t * (t * (t * ay + by) + cy) + dy;
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double dx1 = t * (t * (ax + ax + ax) + bx + bx) + cx;
+                double dy1 = t * (t * (ay + ay + ay) + by + by) + cy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double sx1 = x2 - x23 * prev;
+                    double sy1 = y2 - y23 * prev;
+                    double sx2 = x3 - x34 * prev;
+                    double sy2 = y3 - y34 * prev;
+                    double sx3 = sx1 + (sx2 - sx1) * prev;
+                    double sy3 = sy1 + (sy2 - sy1) * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double sx4 = sx3 + (sx2 - sx3) * t2;
+                    double sy4 = sy3 + (sy2 - sy3) * t2;
+
+                    double px4 = scx;
+                    double py4 = scy;
+                    double px2 = px1 + (sx3 - px1) * t2;
+                    double py2 = py1 + (sy3 - py1) * t2;
+                    double px3 = px2 + (sx4 - px2) * t2;
+                    double py3 = py2 + (sy4 - py2) * t2;
+
+                    addCubic(px1, py1, px2, py2, px3, py3, px4, py4);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px4, py4, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Dasher class provides dashing for particular dash style.
+     */
+    class Dasher {
+        
+        /** The pos. */
+        double pos;
+        
+        /** The first. */
+        boolean close, visible, first;
+        
+        /** The dash. */
+        float dash[];
+        
+        /** The phase. */
+        float phase;
+        
+        /** The index. */
+        int index;
+        
+        /** The iter. */
+        DashIterator iter;
+        
+        /**
+         * Instantiates a new dasher.
+         * 
+         * @param dash the dash
+         * @param phase the phase
+         */
+        Dasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+            index = 0;
+            pos = phase;
+            visible = true;
+            while (pos >= dash[index]) {
+                visible = !visible;
+                pos -= dash[index];
+                index = (index + 1) % dash.length;
+            }            
+            pos = -pos;
+            first = visible;
+        }
+        
+        /**
+         * Inits the.
+         * 
+         * @param iter the iter
+         */
+        void init(DashIterator iter) {
+            this.iter = iter;
+            close = true;
+        }
+        
+        /**
+         * Checks if is open.
+         * 
+         * @return true, if is open
+         */
+        boolean isOpen() {
+            return visible && pos < iter.length;
+        }
+        
+        /**
+         * Checks if is continue.
+         * 
+         * @return true, if is continue
+         */
+        boolean isContinue() {
+            return !visible && pos > 0;
+        }
+        
+        /**
+         * Checks if is closed.
+         * 
+         * @return true, if is closed
+         */
+        boolean isClosed() {
+            return close;
+        }
+        
+        /**
+         * Checks if is connected.
+         * 
+         * @return true, if is connected
+         */
+        boolean isConnected() {
+            return first && !close;
+        }
+
+        /**
+         * Eof.
+         * 
+         * @return true, if successful
+         */
+        boolean eof() {
+            if (!close) {
+                pos -= iter.length;
+                return true;
+            }
+            if (pos >= iter.length) {
+                if (visible) {
+                    pos -= iter.length;
+                    return true;
+                }
+                close = pos == iter.length;
+            }
+            return false;
+        }
+        
+        /**
+         * Next.
+         */
+        void next() {
+            if (close) {
+                pos += dash[index];
+                index = (index + 1) % dash.length;
+            } else {
+                // Go back
+                index = (index + dash.length - 1) % dash.length;
+                pos -= dash[index];
+            }
+            visible = !visible;
+        }
+        
+        /**
+         * Gets the value.
+         * 
+         * @return the value
+         */
+        double getValue() {
+            double t = iter.getNext(pos);
+            return t < 0 ? 0 : (t > 1 ? 1 : t);
+        }
+        
+    }
+
+    /**
+     * DashIterator class provides dashing for particular segment type.
+     */
+    static abstract class DashIterator {
+
+        /** The Constant FLATNESS. */
+        static final double FLATNESS = 1.0;
+
+        /**
+         * The Class Line.
+         */
+        static class Line extends DashIterator {
+
+            /**
+             * Instantiates a new line.
+             * 
+             * @param len the len
+             */
+            Line(double len) {
+                length = len;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                return dashPos / length;
+            }
+
+        }
+
+        /**
+         * The Class Quad.
+         */
+        static class Quad extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new quad.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             */
+            Quad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+                double nx = x1 + x3 - x2 - x2;
+                double ny = y1 + y3 - y2 - y2;
+
+                int n = (int)(1 + Math.sqrt(0.75 * (Math.abs(nx) + Math.abs(ny)) * FLATNESS));
+                step = 1.0 / n;
+
+                double ax = x1 + x3 - x2 - x2;
+                double ay = y1 + y3 - y2 - y2;
+                double bx = 2.0 * (x2 - x1);
+                double by = 2.0 * (y2 - y1);
+
+                double dx1 = step * (step * ax + bx);
+                double dy1 = step * (step * ay + by);
+                double dx2 = step * (step * ax * 2.0);
+                double dy2 = step * (step * ay * 2.0);
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /**
+         * The Class Cubic.
+         */
+        static class Cubic extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new cubic.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             * @param x4 the x4
+             * @param y4 the y4
+             */
+            Cubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+                double nx1 = x1 + x3 - x2 - x2;
+                double ny1 = y1 + y3 - y2 - y2;
+                double nx2 = x2 + x4 - x3 - x3;
+                double ny2 = y2 + y4 - y3 - y3;
+
+                double max = Math.max(Math.abs(nx1) + Math.abs(ny1), Math.abs(nx2) + Math.abs(ny2));
+                int n = (int)(1 + Math.sqrt(0.75 * max) * FLATNESS);
+                step = 1.0 / n;
+
+                double ax = x4 - x1 + 3.0 * (x2 - x3);
+                double ay = y4 - y1 + 3.0 * (y2 - y3);
+                double bx = 3.0 * (x1 + x3 - x2 - x2);
+                double by = 3.0 * (y1 + y3 - y2 - y2);
+                double cx = 3.0 * (x2 - x1);
+                double cy = 3.0 * (y2 - y1);
+
+                double dx1 = step * (step * (step * ax + bx) + cx);
+                double dy1 = step * (step * (step * ay + by) + cy);
+                double dx2 = step * (step * (step * ax * 6.0 + bx * 2.0));
+                double dy2 = step * (step * (step * ay * 6.0 + by * 2.0));
+                double dx3 = step * (step * (step * ax * 6.0));
+                double dy3 = step * (step * (step * ay * 6.0));
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    dx2 += dx3;
+                    dy2 += dy3;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /** The length. */
+        double length;
+
+        /**
+         * Gets the next.
+         * 
+         * @param dashPos the dash pos
+         * 
+         * @return the next
+         */
+        abstract double getNext(double dashPos);
+
+    }
+
+    /**
+     * BufferedPath class provides work path storing and processing.
+     */
+    static class BufferedPath {
+
+        /** The Constant bufCapacity. */
+        private static final int bufCapacity = 10;
+
+        /** The point shift. */
+        static int pointShift[] = {
+                2,  // MOVETO
+                2,  // LINETO
+                4,  // QUADTO
+                6,  // CUBICTO
+                0}; // CLOSE
+
+        /** The types. */
+        byte[] types;
+        
+        /** The points. */
+        float[] points;
+        
+        /** The type size. */
+        int typeSize;
+        
+        /** The point size. */
+        int pointSize;
+
+        /** The x last. */
+        float xLast;
+        
+        /** The y last. */
+        float yLast;
+        
+        /** The x move. */
+        float xMove;
+        
+        /** The y move. */
+        float yMove;
+
+        /**
+         * Instantiates a new buffered path.
+         */
+        public BufferedPath() {
+            types = new byte[bufCapacity];
+            points = new float[bufCapacity * 2];
+        }
+
+        /**
+         * Check buf.
+         * 
+         * @param typeCount the type count
+         * @param pointCount the point count
+         */
+        void checkBuf(int typeCount, int pointCount) {
+            if (typeSize + typeCount > types.length) {
+                byte tmp[] = new byte[typeSize + Math.max(bufCapacity, typeCount)];
+                System.arraycopy(types, 0, tmp, 0, typeSize);
+                types = tmp;
+            }
+            if (pointSize + pointCount > points.length) {
+                float tmp[] = new float[pointSize + Math.max(bufCapacity * 2, pointCount)];
+                System.arraycopy(points, 0, tmp, 0, pointSize);
+                points = tmp;
+            }
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty
+         */
+        boolean isEmpty() {
+            return typeSize == 0;
+        }
+
+        /**
+         * Clean.
+         */
+        void clean() {
+            typeSize = 0;
+            pointSize = 0;
+        }
+
+        /**
+         * Move to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void moveTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = xMove = (float)x;
+            points[pointSize++] = yMove = (float)y;
+        }
+
+        /**
+         * Line to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void lineTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_LINETO;
+            points[pointSize++] = xLast = (float)x;
+            points[pointSize++] = yLast = (float)y;
+        }
+
+        /**
+         * Quad to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         */
+        void quadTo(double x1, double y1, double x2, double y2) {
+            checkBuf(1, 4);
+            types[typeSize++] = PathIterator.SEG_QUADTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = xLast = (float)x2;
+            points[pointSize++] = yLast = (float)y2;
+        }
+
+        /**
+         * Cubic to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         * @param x3 the x3
+         * @param y3 the y3
+         */
+        void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) {
+            checkBuf(1, 6);
+            types[typeSize++] = PathIterator.SEG_CUBICTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = (float)x2;
+            points[pointSize++] = (float)y2;
+            points[pointSize++] = xLast = (float)x3;
+            points[pointSize++] = yLast = (float)y3;
+        }
+
+        /**
+         * Close path.
+         */
+        void closePath() {
+            checkBuf(1, 0);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+
+        /**
+         * Sets the last.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void setLast(double x, double y) {
+            points[pointSize - 2] = xLast = (float)x;
+            points[pointSize - 1] = yLast = (float)y;
+        }
+
+        /**
+         * Append.
+         * 
+         * @param p the p
+         */
+        void append(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            System.arraycopy(p.points, 0, points, pointSize, p.pointSize);
+            System.arraycopy(p.types, 0, types, typeSize, p.typeSize);
+            pointSize += p.pointSize;
+            typeSize += p.typeSize;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Append reverse.
+         * 
+         * @param p the p
+         */
+        void appendReverse(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 2; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            int closeIndex = 0;
+            for(int i = p.typeSize - 1; i >= 0; i--) {
+                byte type = p.types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    types[closeIndex] = PathIterator.SEG_MOVETO;
+                    types[typeSize++] = PathIterator.SEG_CLOSE;
+                } else {
+                    if (type == PathIterator.SEG_CLOSE) {
+                        closeIndex = typeSize;
+                    }
+                    types[typeSize++] = type;
+                }
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Join.
+         * 
+         * @param p the p
+         */
+        void join(BufferedPath p) {
+            // Skip MOVETO
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            System.arraycopy(p.points, 2, points, pointSize, p.pointSize - 2);
+            System.arraycopy(p.types, 1, types, typeSize, p.typeSize - 1);
+            pointSize += p.pointSize - 2;
+            typeSize += p.typeSize - 1;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Combine.
+         * 
+         * @param p the p
+         */
+        void combine(BufferedPath p) {
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 4; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            for(int i = p.typeSize - 1; i >= 1; i--) {
+                types[typeSize++] = p.types[i];
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Creates the general path.
+         * 
+         * @return the general path
+         */
+        GeneralPath createGeneralPath() {
+            GeneralPath p = new GeneralPath();
+            int j = 0;
+            for(int i = 0; i < typeSize; i++) {
+                int type = types[i];
+                switch(type){
+                case PathIterator.SEG_MOVETO:
+                    p.moveTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_LINETO:
+                    p.lineTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    p.quadTo(points[j], points[j + 1], points[j + 2], points[j + 3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    p.curveTo(points[j], points[j + 1], points[j + 2], points[j + 3], points[j + 4], points[j + 5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    p.closePath();
+                    break;
+                }
+                j += pointShift[type];
+            }
+            return p;
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/BufferCapabilities.java b/awt/java/awt/BufferCapabilities.java
new file mode 100644
index 0000000..80e8add
--- /dev/null
+++ b/awt/java/awt/BufferCapabilities.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The BufferCapabilities class represents the capabilities 
+ * and other properties of the image buffers.
+ */
+public class BufferCapabilities implements Cloneable {
+    
+    /** The front buffer capabilities. */
+    private final ImageCapabilities frontBufferCapabilities;
+    
+    /** The back buffer capabilities. */
+    private final ImageCapabilities backBufferCapabilities;
+    
+    /** The flip contents. */
+    private final FlipContents flipContents;
+
+    /**
+     * Instantiates a new BufferCapabilities object.
+     * 
+     * @param frontBufferCapabilities the front buffer capabilities, 
+     * can not be null.
+     * @param backBufferCapabilities the the back and intermediate 
+     * buffers capabilities, can not be null.
+     * @param flipContents the back buffer contents after page flipping, 
+     * null if page flipping is not used.
+     */
+    public BufferCapabilities(ImageCapabilities frontBufferCapabilities, 
+            ImageCapabilities backBufferCapabilities, FlipContents flipContents) {
+        if (frontBufferCapabilities == null || backBufferCapabilities == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.frontBufferCapabilities = frontBufferCapabilities;
+        this.backBufferCapabilities = backBufferCapabilities;
+        this.flipContents = flipContents;
+    }
+
+    /**
+     * Returns a copy of the BufferCapabilities object.
+     * 
+     * @return a copy of the BufferCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new BufferCapabilities(frontBufferCapabilities, backBufferCapabilities, flipContents);
+    }
+
+    /**
+     * Gets the image capabilities of the front buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the front buffer. 
+     */
+    public ImageCapabilities getFrontBufferCapabilities() {
+        return frontBufferCapabilities;
+    }
+
+    /**
+     * Gets the image capabilities of the back buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the back buffer. 
+     */
+    public ImageCapabilities getBackBufferCapabilities() {
+        return backBufferCapabilities;
+    }
+
+    /**
+     * Gets the flip contents of the back buffer after page-flipping. 
+     * 
+     * @return the FlipContents of the back buffer after page-flipping.
+     */
+    public FlipContents getFlipContents() {
+        return flipContents;
+    }
+
+    /**
+     * Checks if the buffer strategy uses page flipping.
+     * 
+     * @return true, if the buffer strategy uses page flipping,
+     * false otherwise.
+     */
+    public boolean isPageFlipping() {
+        return flipContents != null;
+    }
+
+    /**
+     * Checks if page flipping is only available in full-screen mode.
+     * 
+     * @return true, if page flipping is only available in full-screen mode,
+     * false otherwise.
+     */
+    public boolean isFullScreenRequired() {
+        return false;
+    }
+
+    /**
+     * Checks if page flipping can be performed using more than two buffers.
+     * 
+     * @return true, if page flipping can be performed using more than two buffers,
+     * false otherwise.
+     */
+    public boolean isMultiBufferAvailable() {
+        return false;
+    }
+
+    /**
+     * The FlipContents class represents a set of possible back buffer contents 
+     * after page-flipping.
+     */
+    public static final class FlipContents {
+        
+        /**
+         * The back buffered contents are cleared with the background color 
+         * after flipping.
+         */
+        public static final FlipContents BACKGROUND = new FlipContents();
+        
+        /** 
+         * The back buffered contents are copied to the front buffer before 
+         * flipping.
+         */
+        public static final FlipContents COPIED = new FlipContents();
+        
+        /** 
+         * The back buffer contents are the prior contents of the 
+         * front buffer.
+         */
+        public static final FlipContents PRIOR = new FlipContents();
+        
+        /** 
+         * The back buffer contents are undefined after flipping 
+         */
+        public static final FlipContents UNDEFINED = new FlipContents();
+
+        /**
+         * Instantiates a new flip contents.
+         */
+        private FlipContents() {
+
+        }
+
+        /**
+         * Returns the hash code of the FlipContents object.
+         * 
+         * @return the hash code of the FlipContents object.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Returns the String representation of the FlipContents object.
+         * 
+         * @return the string
+         */
+        @Override
+        public String toString() {
+            return super.toString();
+        }
+    }
+}
diff --git a/awt/java/awt/Color.java b/awt/java/awt/Color.java
new file mode 100644
index 0000000..e1e4178
--- /dev/null
+++ b/awt/java/awt/Color.java
@@ -0,0 +1,881 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Color class defines colors in the default sRGB color 
+ * space or in the specified ColorSpace. Every Color contains alpha value.
+ * The alpha value defines the transparency of a color and can be represented
+ * by a float value in the range 0.0 - 1.0 or 0 - 255. 
+  */
+public class Color implements Paint, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 118526816881161077L;
+
+    /*
+     * The values of the following colors are based on 1.5 release behavior which
+     * can be revealed using the following or similar code:
+     *   Color c = Color.white;
+     *   System.out.println(c);
+     */
+
+    /** The color white. */
+    public static final Color white = new Color(255, 255, 255);
+
+    /** The color white. */
+    public static final Color WHITE = white;
+
+    /** The color light gray. */
+    public static final Color lightGray = new Color(192, 192, 192);
+
+    /** The color light gray. */
+    public static final Color LIGHT_GRAY = lightGray;
+
+    /** The color gray. */
+    public static final Color gray = new Color(128, 128, 128);
+
+    /** The color gray. */
+    public static final Color GRAY = gray;
+
+    /** The color dark gray. */
+    public static final Color darkGray = new Color(64, 64, 64);
+
+    /** The color dark gray. */
+    public static final Color DARK_GRAY = darkGray;
+
+    /** The color black. */
+    public static final Color black = new Color(0, 0, 0);
+
+    /** The color black. */
+    public static final Color BLACK = black;
+
+    /** The color red. */
+    public static final Color red = new Color(255, 0, 0);
+
+    /** The color red. */
+    public static final Color RED = red;
+
+    /** The color pink. */
+    public static final Color pink = new Color(255, 175, 175);
+
+    /** The color pink. */
+    public static final Color PINK = pink;
+
+    /** The color orange. */
+    public static final Color orange = new Color(255, 200, 0);
+
+    /** The color orange. */
+    public static final Color ORANGE = orange;
+
+    /** The color yellow. */
+    public static final Color yellow = new Color(255, 255, 0);
+
+    /** The color yellow. */
+    public static final Color YELLOW = yellow;
+
+    /** The color green. */
+    public static final Color green = new Color(0, 255, 0);
+
+    /** The color green. */
+    public static final Color GREEN = green;
+
+    /** The color magenta. */
+    public static final Color magenta = new Color(255, 0, 255);
+
+    /** The color magenta. */
+    public static final Color MAGENTA = magenta;
+
+    /** The color cyan. */
+    public static final Color cyan = new Color(0, 255, 255);
+
+    /** The color cyan. */
+    public static final Color CYAN = cyan;
+
+    /** The color blue. */
+    public static final Color blue = new Color(0, 0, 255);
+
+    /** The color blue. */
+    public static final Color BLUE = blue;
+
+    /** integer RGB value. */
+    int value;
+
+    /** Float sRGB value. */
+    private float[] frgbvalue;
+
+    /** Color in an arbitrary color space with <code>float</code> components. If null, other value should be used. */
+    private float fvalue[];
+
+    /** Float alpha value. If frgbvalue is null, this is not valid data. */
+    private float falpha;
+
+    /** The color's color space if applicable. */
+    private ColorSpace cs;
+
+    /*
+     * The value of the SCALE_FACTOR is based on 1.5 release behavior which
+     * can be revealed using the following code:
+     *   Color c = new Color(100, 100, 100);
+     *   Color bc = c.brighter();
+     *   System.out.println("Brighter factor: " + ((float)c.getRed())/((float)bc.getRed()));
+     *   Color dc = c.darker();
+     *   System.out.println("Darker factor: " + ((float)dc.getRed())/((float)c.getRed()));
+     * The result is the same for brighter and darker methods, so we need only
+     * one scale factor for both.
+     */
+    /** The Constant SCALE_FACTOR. */
+    private static final double SCALE_FACTOR = 0.7;
+
+    /** The Constant MIN_SCALABLE. */
+    private static final int MIN_SCALABLE = 3; // should increase when multiplied by SCALE_FACTOR
+
+    /** The current paint context. */
+    transient private PaintContext currentPaintContext;
+
+    /**
+     * Creates a color in the specified ColorSpace, the specified color 
+     * components and the specified alpha. 
+     * 
+     * @param cspace the ColorSpace to be used to define the components.
+     * @param components the components.
+     * @param alpha the alpha.
+     */
+    public Color(ColorSpace cspace, float[] components, float alpha) {
+        int nComps = cspace.getNumComponents();
+        float comp;
+        fvalue = new float[nComps];
+
+        for(int i=0 ; i<nComps; i++) {
+            comp = components[i];
+            if(comp < 0.0f || comp > 1.0f) {
+                // awt.107=Color parameter outside of expected range: component {0}.
+                throw new IllegalArgumentException(
+                        Messages.getString("awt.107", i)); //$NON-NLS-1$
+            }
+            fvalue[i] = components[i];
+        }
+
+        if (alpha < 0.0f || alpha > 1.0f) {
+            // awt.108=Alpha value outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
+        }
+        falpha = alpha;
+
+        cs = cspace;
+
+        frgbvalue = cs.toRGB(fvalue);
+
+        value =  ((int)(frgbvalue[2]*255 + 0.5))    |
+                (((int)(frgbvalue[1]*255 + 0.5)) << 8 )  |
+                (((int)(frgbvalue[0]*255 + 0.5)) << 16 ) |
+                (((int)(falpha*255 + 0.5)) << 24 );
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified combined 
+     * RGBA value consisting of the alpha component in bits 24-31, 
+     * the red component in bits 16-23, the green component in bits 8-15, 
+     * and the blue component in bits 0-7. If the hasalpha argument is 
+     * false, the alpha has default value - 255.
+     * 
+     * @param rgba the RGBA components.
+     * @param hasAlpha alpha parameter is true if alpha bits are valid,
+     * false otherwise.
+     */
+    public Color(int rgba, boolean hasAlpha) {
+        if (!hasAlpha) {
+            value = rgba | 0xFF000000;
+        } else {
+            value = rgba;
+        }
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(int r, int g, int b, int a) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        value = b | (g << 8) | (r << 16) | (a << 24);
+    }
+
+    /**
+     * Instantiates a new opaque sRGB color with the specified red, green, 
+     * and blue values. The Alpha component is set to the default - 1.0.
+     * 
+     * @param r the red component. 
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(int r, int g, int b) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        // 0xFF for alpha channel
+        value = b | (g << 8) | (r << 16) | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified 
+     * RGB value consisting of the red component in bits 16-23, 
+     * the green component in bits 8-15, and the blue component 
+     * in bits 0-7. Alpha has default value - 255.
+     * 
+     * @param rgb the RGB components.
+     */
+    public Color(int rgb) {
+        value = rgb | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(float r, float g, float b, float a) {
+        this((int)(r*255+0.5),
+                (int)(g*255+0.5),
+                (int)(b*255+0.5),
+                (int)(a*255+0.5));
+        falpha = a;
+        fvalue = new float[3];
+        fvalue[0] = r;
+        fvalue[1] = g;
+        fvalue[2] = b;
+        frgbvalue = fvalue;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, and blue 
+     * components and default alfa value - 1.0.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(float r, float g, float b) {
+        this(r, g, b, 1.0f);
+    }
+
+    public PaintContext createContext(
+            ColorModel cm,
+            Rectangle r,
+            Rectangle2D r2d,
+            AffineTransform xform,
+            RenderingHints rhs
+    ) {
+        if(currentPaintContext != null) {
+            return currentPaintContext;
+        }
+        currentPaintContext = new Color.ColorPaintContext(value);
+        return currentPaintContext;
+    }
+
+    /**
+     * Returns a string representation of the Color object.
+     * 
+     * @return the string representation of the Color object.
+     */
+    @Override
+    public String toString() {
+        /*
+           The format of the string is based on 1.5 release behavior which
+           can be revealed using the following code:
+
+           Color c = new Color(1, 2, 3);
+           System.out.println(c);
+        */
+        
+        return getClass().getName() +
+                "[r=" + getRed() + //$NON-NLS-1$
+                ",g=" + getGreen() + //$NON-NLS-1$
+                ",b=" + getBlue() + //$NON-NLS-1$
+                "]"; //$NON-NLS-1$
+    }
+
+    /**
+     * Compares the specified Object to the Color.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Color whose 
+     * value is equal to this Color, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(obj instanceof Color) {
+            return ((Color)obj).value == this.value;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the specified ColorSpace. 
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(ColorSpace colorSpace, float[] components) {
+        int nComps = colorSpace.getNumComponents();
+        if(components == null) {
+            components = new float[nComps+1];
+        }
+
+        getColorComponents(colorSpace, components);
+
+        if(frgbvalue != null) {
+            components[nComps] = falpha;
+        } else {
+            components[nComps] = getAlpha()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the specified ColorSpace.
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
+        float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
+        float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
+
+        if(components == null) {
+            return csComponents;
+        }
+
+        for(int i=0; i<csComponents.length; i++) {
+            components[i] = csComponents[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the ColorSpace of this Color.
+     * 
+     * @return the ColorSpace object.
+     */
+    public ColorSpace getColorSpace() {
+        if (cs == null) {
+            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        }
+
+        return cs;
+    }
+
+    /**
+     * Creates a new Color which is a darker than this Color
+     * according to a fixed scale factor.
+     * 
+     * @return the darker Color.
+     */
+    public Color darker() {
+        return new Color(
+                (int)(getRed()*SCALE_FACTOR),
+                (int)(getGreen()*SCALE_FACTOR),
+                (int)(getBlue()*SCALE_FACTOR));
+    }
+
+    /**
+     * Creates a new Color which is a brighter than this Color.
+     * 
+     * @return the brighter Color.
+     */
+    public Color brighter() {
+
+        int r = getRed();
+        int b = getBlue();
+        int g = getGreen();
+
+        if(r == 0 && b == 0 && g == 0) {
+            return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
+        }
+
+        if(r < MIN_SCALABLE && r != 0) {
+            r = MIN_SCALABLE;
+        } else {
+            r = (int) (r/SCALE_FACTOR);
+            r = (r > 255) ? 255 : r;
+        }
+
+        if(b < MIN_SCALABLE && b != 0) {
+            b = MIN_SCALABLE;
+        } else {
+            b = (int) (b/SCALE_FACTOR);
+            b = (b > 255) ? 255 : b;
+        }
+
+        if(g < MIN_SCALABLE && g != 0) {
+            g = MIN_SCALABLE;
+        } else {
+            g = (int) (g/SCALE_FACTOR);
+            g = (g > 255) ? 255 : g;
+        }
+
+        return new Color(r, g, b);
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color and alpha components in a float array.
+     */
+    public float[] getRGBComponents(float[] components) {
+        if(components == null) {
+            components = new float[4];
+        }
+
+        if(frgbvalue != null) {
+            components[3] = falpha;
+        } else {
+            components[3] = getAlpha()/255f;
+        }
+
+        getRGBColorComponents(components);
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color components in a float array.
+     */
+    public float[] getRGBColorComponents(float[] components) {
+        if(components == null) {
+            components = new float[3];
+        }
+
+        if(frgbvalue != null) {
+            components[2] = frgbvalue[2];
+            components[1] = frgbvalue[1];
+            components[0] = frgbvalue[0];
+        } else {
+            components[2] = getBlue()/255f;
+            components[1] = getGreen()/255f;
+            components[0] = getRed()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color and alpha components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBComponents(components);
+        }
+
+        int nColorComps = fvalue.length;
+
+        if(components == null) {
+            components = new float[nColorComps+1];
+        }
+
+        getColorComponents(components);
+
+        components[nColorComps] = falpha;
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBColorComponents(components);
+        }
+
+        if(components == null) {
+            components = new float[fvalue.length];
+        }
+
+        for(int i=0; i<fvalue.length; i++) {
+            components[i] = fvalue[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a hash code of this Color object.
+     * 
+     * @return a hash code of this Color object.
+     */
+    @Override
+    public int hashCode() {
+        return value;
+    }
+
+    public int getTransparency() {
+        switch(getAlpha()) {
+            case 0xff:
+                return Transparency.OPAQUE;
+            case 0:
+                return Transparency.BITMASK;
+            default:
+                return Transparency.TRANSLUCENT;
+        }
+    }
+
+    /**
+     * Gets the red component of the Color in the range 0-255.
+     * 
+     * @return the red component of the Color.
+     */
+    public int getRed() {
+        return (value >> 16) & 0xFF;
+    }
+
+    /**
+     * Gets the RGB value that represents the color in the default sRGB ColorModel.
+     * 
+     * @return the RGB color value in the default sRGB ColorModel.
+     */
+    public int getRGB() {
+        return value;
+    }
+
+    /**
+     * Gets the green component of the Color in the range 0-255.
+     * 
+     * @return the green component of the Color.
+     */
+    public int getGreen() {
+        return (value >> 8) & 0xFF;
+    }
+
+    /**
+     * Gets the blue component of the Color in the range 0-255.
+     * 
+     * @return the blue component of the Color.
+     */
+    public int getBlue() {
+        return value & 0xFF;
+    }
+
+    /**
+     * Gets the alpha component of the Color in the range 0-255.
+     * 
+     * @return the alpha component of the Color.
+     */
+    public int getAlpha() {
+        return (value >> 24) & 0xFF;
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color
+     * specified by the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * specified by the second parameter.
+     */
+    public static Color getColor(String nm, Color def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return def;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color converted
+     * from the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * converted from the second parameter.
+     */
+    public static Color getColor(String nm, int def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return new Color(def);
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified String.
+     * 
+     * @param nm the specified string.
+     * 
+     * @return the Color object, or null.
+     */
+    public static Color getColor(String nm) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return null;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Decodes a String to an integer and returns the specified opaque Color.
+     * 
+     * @param nm a String which represents an opaque color as a 24-bit integer.
+     * 
+     * @throws NumberFormatException if the specified string can not be
+     * converted to an integer.
+     */
+    public static Color decode(String nm) throws NumberFormatException {
+        Integer integer = Integer.decode(nm);
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets a Color object using the specified values of the HSB color model.
+     * 
+     * @param h the hue component of the Color.
+     * @param s the saturation of the Color.
+     * @param b the brightness of the Color.
+     * 
+     * @return a color object with the specified hue, saturation and 
+     * brightness values.
+     */
+    public static Color getHSBColor(float h, float s, float b) {
+        return new Color(HSBtoRGB(h, s, b));
+    }
+
+    /**
+     * Converts the Color specified by the RGB model to an equivalent 
+     * color in the HSB model.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param hsbvals the array of result hue, saturation, brightness
+     * values or null.
+     * 
+     * @return the float array of hue, saturation, brightness values.
+     */
+    public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
+        if(hsbvals == null) {
+            hsbvals = new float[3];
+        }
+
+        int V = Math.max(b, Math.max(r, g));
+        int temp = Math.min(b, Math.min(r, g));
+
+        float H, S, B;
+
+        B = V/255.f;
+
+        if(V == temp) {
+            H = S = 0;
+        } else {
+            S = (V - temp)/((float)V);
+
+            float Cr = (V - r) / (float)(V - temp);
+            float Cg = (V - g) / (float)(V - temp);
+            float Cb = (V - b) / (float)(V - temp);
+
+            if (r == V) {
+                H = Cb - Cg;
+            } else if (g == V) {
+                H = 2 + Cr - Cb;
+            } else {
+                H = 4 + Cg - Cr;
+            }
+
+            H /= 6.f;
+            if(H < 0) {
+                H++;
+            }
+        }
+
+        hsbvals[0] = H;
+        hsbvals[1] = S;
+        hsbvals[2] = B;
+
+        return hsbvals;
+    }
+
+    /**
+     * Converts the Color specified by the HSB model to an equivalent 
+     * color in the default RGB model.
+     * 
+     * @param hue the hue component of the Color.
+     * @param saturation the saturation of the Color.
+     * @param brightness the brightness of the Color.
+     * 
+     * @return the RGB value of the color with the specified hue, 
+     * saturation and brightness.
+     */
+    public static int HSBtoRGB(float hue, float saturation, float brightness) {
+        float fr, fg, fb;
+
+        if(saturation == 0) {
+            fr = fg = fb = brightness;
+        } else {
+            float H = (hue - (float)Math.floor(hue)) * 6;
+            int I = (int) Math.floor(H);
+            float F = H - I;
+            float M = brightness * (1 - saturation);
+            float N = brightness * (1 - saturation * F);
+            float K = brightness * (1 - saturation * (1 - F));
+
+            switch(I) {
+                case 0:
+                    fr = brightness; fg = K; fb = M; break;
+                case 1:
+                    fr = N; fg = brightness; fb = M; break;
+                case 2:
+                    fr = M; fg = brightness; fb = K; break;
+                case 3:
+                    fr = M; fg = N; fb = brightness; break;
+                case 4:
+                    fr = K; fg = M; fb = brightness; break;
+                case 5:
+                    fr = brightness; fg = M; fb = N; break;
+                default:
+                    fr = fb = fg = 0; // impossible, to supress compiler error
+            }
+        }
+
+        int r = (int) (fr * 255. + 0.5);
+        int g = (int) (fg * 255. + 0.5);
+        int b = (int) (fb * 255. + 0.5);
+
+        return (r << 16) | (g << 8) | b | 0xFF000000;
+    }
+
+    /**
+     * The Class ColorPaintContext.
+     */
+    class ColorPaintContext implements PaintContext {
+        
+        /** The rgb value. */
+        int rgbValue;
+        
+        /** The saved raster. */
+        WritableRaster savedRaster = null;
+
+        /**
+         * Instantiates a new color paint context.
+         * 
+         * @param rgb the rgb
+         */
+        protected ColorPaintContext(int rgb) {
+            rgbValue = rgb;
+        }
+
+        public void dispose() {
+            savedRaster = null;
+        }
+
+        public ColorModel getColorModel() {
+            return ColorModel.getRGBdefault();
+        }
+
+        public Raster getRaster(int x, int y, int w, int h) {
+            if (savedRaster == null ||
+                    w != savedRaster.getWidth() ||
+                    h != savedRaster.getHeight()) {
+                savedRaster =
+                        getColorModel().createCompatibleWritableRaster(w, h);
+
+                // Suppose we have here simple INT/RGB color/sample model
+                DataBufferInt intBuffer =
+                        (DataBufferInt) savedRaster.getDataBuffer();
+                int rgbValues[] = intBuffer.getData();
+                int rgbFillValue = rgbValue;
+                Arrays.fill(rgbValues, rgbFillValue);
+            }
+
+            return savedRaster;
+        }
+    }
+}
+
diff --git a/awt/java/awt/Component.java b/awt/java/awt/Component.java
new file mode 100644
index 0000000..f19d285
--- /dev/null
+++ b/awt/java/awt/Component.java
@@ -0,0 +1,6408 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+//import java.awt.dnd.DropTarget;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.InvocationEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.awt.peer.ComponentPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleState;
+//import javax.accessibility.AccessibleStateSet;
+
+import org.apache.harmony.awt.ClipRegion;
+//import org.apache.harmony.awt.FieldsAccessor;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.state.State;
+//import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The abstract Component class specifies an object with a graphical 
+ * representation that can be displayed on the screen and that can 
+ * interact with the user (for example: scrollbars, buttons, checkboxes).
+ */
+public abstract class Component implements ImageObserver, MenuContainer, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7644114512714619750L;
+
+    /** The Constant TOP_ALIGNMENT indicates the top alignment of the component. */
+    public static final float TOP_ALIGNMENT = 0.0f;
+
+    /** The Constant CENTER_ALIGNMENT indicates the center alignment of the component. */
+    public static final float CENTER_ALIGNMENT = 0.5f;
+
+    /** The Constant BOTTOM_ALIGNMENT indicates the bottom alignment of the component. */
+    public static final float BOTTOM_ALIGNMENT = 1.0f;
+
+    /** The Constant LEFT_ALIGNMENT indicates the left alignment of the component. */
+    public static final float LEFT_ALIGNMENT = 0.0f;
+
+    /** The Constant RIGHT_ALIGNMENT indicates the right alignment of the component. */
+    public static final float RIGHT_ALIGNMENT = 1.0f;
+
+    /** The Constant childClassesFlags. */
+    private static final Hashtable<Class<?>, Boolean> childClassesFlags = new Hashtable<Class<?>, Boolean>();
+
+    /** The Constant peer. */
+    private static final ComponentPeer peer = new ComponentPeer() {
+    };
+
+    /** The Constant incrementalImageUpdate. */
+    private static final boolean incrementalImageUpdate;
+
+    /** The toolkit. */
+    final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent {
+        private static final long serialVersionUID = 642321655757800191L;
+
+        protected class AccessibleAWTComponentHandler implements ComponentListener {
+            protected AccessibleAWTComponentHandler() {
+            }
+
+            public void componentHidden(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.VISIBLE, null);
+            }
+
+            public void componentMoved(ComponentEvent e) {
+            }
+
+            public void componentResized(ComponentEvent e) {
+            }
+
+            public void componentShown(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.VISIBLE);
+            }
+        }
+
+        protected class AccessibleAWTFocusHandler implements FocusListener {
+            public void focusGained(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.FOCUSED);
+            }
+
+            public void focusLost(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.FOCUSED, null);
+            }
+        }
+    
+        protected ComponentListener accessibleAWTComponentHandler;
+    
+        protected FocusListener accessibleAWTFocusHandler;
+        */
+        /*
+         * Number of registered property change listeners.
+         */
+        /*
+        int listenersCount;
+
+        public void addFocusListener(FocusListener l) {
+            Component.this.addFocusListener(l);
+        }
+
+        @Override
+        public void addPropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.addPropertyChangeListener(listener);
+                listenersCount++;
+                if (accessibleAWTComponentHandler == null) {
+                    accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
+                    Component.this.addComponentListener(accessibleAWTComponentHandler);
+                }
+                if (accessibleAWTFocusHandler == null) {
+                    accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
+                    Component.this.addFocusListener(accessibleAWTFocusHandler);
+                }
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        public boolean contains(Point p) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.contains(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Accessible getAccessibleAt(Point arg0) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getBackground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBackground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Rectangle getBounds() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBounds();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Cursor getCursor() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getCursor();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Font getFont() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFont();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public FontMetrics getFontMetrics(Font f) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFontMetrics(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getForeground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getForeground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocation() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocation();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocationOnScreen() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocationOnScreen();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Dimension getSize() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getSize();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isEnabled() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isEnabled();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isFocusTraversable() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isFocusTraversable();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isShowing() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isShowing();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isVisible() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isVisible();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void removeFocusListener(FocusListener l) {
+            Component.this.removeFocusListener(l);
+        }
+
+        @Override
+        public void removePropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.removePropertyChangeListener(listener);
+                listenersCount--;
+                if (listenersCount > 0) {
+                    return;
+                }
+                // if there are no more listeners, remove handlers:
+                Component.this.removeFocusListener(accessibleAWTFocusHandler);
+                Component.this.removeComponentListener(accessibleAWTComponentHandler);
+                accessibleAWTComponentHandler = null;
+                accessibleAWTFocusHandler = null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void requestFocus() {
+            toolkit.lockAWT();
+            try {
+                Component.this.requestFocus();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBackground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBackground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBounds(Rectangle r) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBounds(r);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setCursor(Cursor cursor) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setCursor(cursor);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setEnabled(boolean enabled) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setEnabled(enabled);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setFont(Font f) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setFont(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setForeground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setForeground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setLocation(Point p) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setLocation(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setSize(Dimension size) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setSize(size);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setVisible(boolean visible) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setVisible(visible);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                Container parent = getParent();
+                return (parent instanceof Accessible ? (Accessible) parent : null);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int i) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            toolkit.lockAWT();
+            try {
+                return 0;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription(); // why override?
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                if (getAccessibleParent() == null) {
+                    return -1;
+                }
+                int count = 0;
+                Container parent = getParent();
+                for (int i = 0; i < parent.getComponentCount(); i++) {
+                    Component aComp = parent.getComponent(i);
+                    if (aComp instanceof Accessible) {
+                        if (aComp == Component.this) {
+                            return count;
+                        }
+                        ++count;
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            toolkit.lockAWT();
+            try {
+                return AccessibleRole.AWT_COMPONENT;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            toolkit.lockAWT();
+            try {
+                AccessibleStateSet set = new AccessibleStateSet();
+                if (isEnabled()) {
+                    set.add(AccessibleState.ENABLED);
+                }
+                if (isFocusable()) {
+                    set.add(AccessibleState.FOCUSABLE);
+                }
+                if (hasFocus()) {
+                    set.add(AccessibleState.FOCUSED);
+                }
+                if (isOpaque()) {
+                    set.add(AccessibleState.OPAQUE);
+                }
+                if (isShowing()) {
+                    set.add(AccessibleState.SHOWING);
+                }
+                if (isVisible()) {
+                    set.add(AccessibleState.VISIBLE);
+                }
+                return set;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Locale getLocale() throws IllegalComponentStateException {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocale();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+    }
+    */
+    /**
+     * The BltBufferStrategy class provides opportunity of blitting 
+     * offscreen surfaces to a component. For more information on 
+     * blitting, see <a href="http://en.wikipedia.org/wiki/Bit_blit">Bit blit</a>.
+     */
+    protected class BltBufferStrategy extends BufferStrategy {
+        
+        /** The back buffers. */
+        protected VolatileImage[] backBuffers;
+
+        /** The caps. */
+        protected BufferCapabilities caps;
+
+        /** The width. */
+        protected int width;
+
+        /** The height. */
+        protected int height;
+
+        /** The validated contents. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new BltBufferStrategy buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws NotImplementedException the not implemented exception.
+         */
+        protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) throws org.apache.harmony.luni.util.NotImplementedException {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         *  
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise.
+         *           
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates the back buffers.
+         * 
+         * @param numBuffers the number of buffers.
+         */
+        protected void createBackBuffers(int numBuffers) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The FlipBufferStrategy class is for flipping buffers on a component. 
+     */
+    protected class FlipBufferStrategy extends BufferStrategy {
+        
+        /** The Buffer Capabilities. */
+        protected BufferCapabilities caps;
+
+        /** The drawing buffer. */
+        protected Image drawBuffer;
+
+        /** The drawing VolatileImage buffer. */
+        protected VolatileImage drawVBuffer;
+
+        /** The number of buffers. */
+        protected int numBuffers;
+
+        /** The validated contents indicates if the drawing buffer is restored from
+         * lost state. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new flip buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities supplied could not 
+         * be supported or met.
+         */
+        protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            //???AWT
+            /*
+            if (!(Component.this instanceof Window) && !(Component.this instanceof Canvas)) {
+                // awt.14B=Only Canvas or Window is allowed
+                throw new ClassCastException(Messages.getString("awt.14B")); //$NON-NLS-1$
+            }
+            */
+            // TODO: throw new AWTException("Capabilities are not supported");
+            this.numBuffers = numBuffers;
+            this.caps = (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         * 
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise. 
+         * 
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates flipping buffers with the specified buffer capabilities.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities could not be 
+         * supported or met.
+         */
+        protected void createBuffers(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            if (numBuffers < 2) {
+                // awt.14C=Number of buffers must be greater than one
+                throw new IllegalArgumentException(Messages.getString("awt.14C")); //$NON-NLS-1$
+            }
+            if (!caps.isPageFlipping()) {
+                // awt.14D=Buffer capabilities should support flipping
+                throw new IllegalArgumentException(Messages.getString("awt.14D")); //$NON-NLS-1$
+            }
+            if (!Component.this.behaviour.isDisplayable()) {
+                // awt.14E=Component should be displayable
+                throw new IllegalStateException(Messages.getString("awt.14E")); //$NON-NLS-1$
+            }
+            // TODO: throw new AWTException("Capabilities are not supported");
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Destroy buffers.
+         */
+        protected void destroyBuffers() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Flips the contents of the back buffer to the front buffer.
+         * 
+         * @param flipAction the flip action.
+         */
+        protected void flip(BufferCapabilities.FlipContents flipAction) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Gets the back buffer as Image.
+         * 
+         * @return the back buffer as Image.
+         */
+        protected Image getBackBuffer() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The internal component's state utilized by the visual theme.
+     */
+    class ComponentState implements State {
+        
+        /** The default minimum size. */
+        private Dimension defaultMinimumSize = new Dimension();
+
+        /**
+         * Checks if the component is enabled.
+         * 
+         * @return true, if the component is enabled
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        /**
+         * Checks if the component is visible.
+         * 
+         * @return true, if the component is visible
+         */
+        public boolean isVisible() {
+            return visible;
+        }
+
+        /**
+         * Checks if is focused.
+         * 
+         * @return true, if is focused
+         */
+        public boolean isFocused() {
+            //???AWT: return isFocusOwner();
+            return false;
+        }
+
+        /**
+         * Gets the font.
+         * 
+         * @return the font
+         */
+        public Font getFont() {
+            return Component.this.getFont();
+        }
+
+        /**
+         * Checks if the font has been set.
+         * 
+         * @return true, if the font has been set
+         */
+        public boolean isFontSet() {
+            return font != null;
+        }
+
+        /**
+         * Gets the background color.
+         * 
+         * @return the background color
+         */
+        public Color getBackground() {
+            Color c = Component.this.getBackground();
+            return (c != null) ? c : getDefaultBackground();
+        }
+
+        /**
+         * Checks if the background is set.
+         * 
+         * @return true, if the background is set
+         */
+        public boolean isBackgroundSet() {
+            return backColor != null;
+        }
+
+        /**
+         * Gets the text color.
+         * 
+         * @return the text color
+         */
+        public Color getTextColor() {
+            Color c = getForeground();
+            return (c != null) ? c : getDefaultForeground();
+        }
+
+        /**
+         * Checks if the text color is set.
+         * 
+         * @return true, if the text color is set
+         */
+        public boolean isTextColorSet() {
+            return foreColor != null;
+        }
+
+        /**
+         * Gets the font metrics.
+         * 
+         * @return the font metrics
+         */
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics() {
+            return toolkit.getFontMetrics(Component.this.getFont());
+        }
+
+        /**
+         * Gets the bounding rectangle.
+         * 
+         * @return the bounding rectangle
+         */
+        public Rectangle getBounds() {
+            return new Rectangle(x, y, w, h);
+        }
+
+        /**
+         * Gets the size of the bounding rectangle.
+         * 
+         * @return the size of the bounding rectangle
+         */
+        public Dimension getSize() {
+            return new Dimension(w, h);
+        }
+
+        /**
+         * Gets the window id.
+         * 
+         * @return the window id
+         */
+        public long getWindowId() {
+            NativeWindow win = getNativeWindow();
+            return (win != null) ? win.getId() : 0;
+        }
+
+        /**
+         * Gets the default minimum size.
+         * 
+         * @return the default minimum size
+         */
+        public Dimension getDefaultMinimumSize() {
+            if (defaultMinimumSize == null) {
+                calculate();
+            }
+            return defaultMinimumSize;
+        }
+
+        /**
+         * Sets the default minimum size.
+         * 
+         * @param size the new default minimum size
+         */
+        public void setDefaultMinimumSize(Dimension size) {
+            defaultMinimumSize = size;
+        }
+
+        /**
+         * Reset the default minimum size to null.
+         */
+        public void reset() {
+            defaultMinimumSize = null;
+        }
+
+        /**
+         * Calculate the default minimum size: to be overridden.
+         */
+        public void calculate() {
+            // to be overridden
+        }
+    }
+
+    //???AWT: private transient AccessibleContext accessibleContext;
+
+    /** The behaviour. */
+    final transient ComponentBehavior behaviour;
+
+    //???AWT: Container parent;
+
+    /** The name. */
+    private String name;
+
+    /** The auto name. */
+    private boolean autoName = true;
+
+    /** The font. */
+    private Font font;
+
+    /** The back color. */
+    private Color backColor;
+
+    /** The fore color. */
+    private Color foreColor;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The enabled events. */
+    private long enabledEvents;
+
+    /** The enabled awt events. */
+    private long enabledAWTEvents;
+
+    /** The component listeners. */
+    private final AWTListenerList<ComponentListener> componentListeners = new AWTListenerList<ComponentListener>(
+            this);
+
+    /** The focus listeners. */
+    private final AWTListenerList<FocusListener> focusListeners = new AWTListenerList<FocusListener>(
+            this);
+
+    /** The hierarchy listeners. */
+    private final AWTListenerList<HierarchyListener> hierarchyListeners = new AWTListenerList<HierarchyListener>(
+            this);
+
+    /** The hierarchy bounds listeners. */
+    private final AWTListenerList<HierarchyBoundsListener> hierarchyBoundsListeners = new AWTListenerList<HierarchyBoundsListener>(
+            this);
+
+    /** The key listeners. */
+    private final AWTListenerList<KeyListener> keyListeners = new AWTListenerList<KeyListener>(
+            this);
+
+    /** The mouse listeners. */
+    private final AWTListenerList<MouseListener> mouseListeners = new AWTListenerList<MouseListener>(
+            this);
+
+    /** The mouse motion listeners. */
+    private final AWTListenerList<MouseMotionListener> mouseMotionListeners = new AWTListenerList<MouseMotionListener>(
+            this);
+
+    /** The mouse wheel listeners. */
+    private final AWTListenerList<MouseWheelListener> mouseWheelListeners = new AWTListenerList<MouseWheelListener>(
+            this);
+
+    /** The input method listeners. */
+    private final AWTListenerList<InputMethodListener> inputMethodListeners = new AWTListenerList<InputMethodListener>(
+            this);
+
+    /** The x. */
+    int x;
+
+    /** The y. */
+    int y;
+
+    /** The w. */
+    int w;
+
+    /** The h. */
+    int h;
+
+    /** The maximum size. */
+    private Dimension maximumSize;
+
+    /** The minimum size. */
+    private Dimension minimumSize;
+
+    /** The preferred size. */
+    private Dimension preferredSize;
+
+    /** The bounds mask param. */
+    private int boundsMaskParam;
+
+    /** The ignore repaint. */
+    private boolean ignoreRepaint;
+
+    /** The enabled. */
+    private boolean enabled = true;
+
+    /** The input methods enabled. */
+    private boolean inputMethodsEnabled = true;
+
+    /** The dispatch to im. */
+    transient boolean dispatchToIM = true;
+
+    /** The focusable. */
+    private boolean focusable = true; // By default, all Components return
+
+    // true from isFocusable() method
+    /** The visible. */
+    boolean visible = true;
+
+    /** The called set focusable. */
+    private boolean calledSetFocusable;
+
+    /** The overriden is focusable. */
+    private boolean overridenIsFocusable = true;
+
+    /** The focus traversal keys enabled. */
+    private boolean focusTraversalKeysEnabled = true;
+
+    /** Possible keys are: FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, UP_CYCLE_TRAVERSAL_KEYS. */
+    private final Map<Integer, Set<? extends AWTKeyStroke>> traversalKeys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+
+    /** The traversal i ds. */
+    int[] traversalIDs;
+
+    /** The locale. */
+    private Locale locale;
+
+    /** The orientation. */
+    private ComponentOrientation orientation;
+
+    /** The property change support. */
+    private PropertyChangeSupport propertyChangeSupport;
+
+    //???AWT: private ArrayList<PopupMenu> popups;
+
+    /** The coalescer. */
+    private boolean coalescer;
+
+    /** The events table. */
+    private Hashtable<Integer, LinkedList<AWTEvent>> eventsTable;
+
+    /** Cashed reference used during EventQueue.postEvent() */
+    private LinkedList<AWTEvent> eventsList;
+
+    /** The hierarchy changing counter. */
+    private int hierarchyChangingCounter;
+
+    /** The was showing. */
+    private boolean wasShowing;
+
+    /** The was displayable. */
+    private boolean wasDisplayable;
+
+    /** The cursor. */
+    Cursor cursor;
+
+    //???AWT: DropTarget dropTarget;
+
+    /** The mouse exited expected. */
+    private boolean mouseExitedExpected;
+
+    /** The repaint region. */
+    transient MultiRectArea repaintRegion;
+
+    //???AWT: transient RedrawManager redrawManager;
+    /** The redraw manager. */
+    transient Object redrawManager;
+
+    /** The valid. */
+    private boolean valid;
+
+    /** The updated images. */
+    private HashMap<Image, ImageParameters> updatedImages;
+
+    /**
+     * The lock object for private component's data which don't affect the
+     * component hierarchy.
+     */
+    private class ComponentLock {
+    }
+
+    /** The component lock. */
+    private final transient Object componentLock = new ComponentLock();
+    static {
+        PrivilegedAction<String[]> action = new PrivilegedAction<String[]>() {
+            public String[] run() {
+                String properties[] = new String[2];
+                properties[0] = System.getProperty("awt.image.redrawrate", "100"); //$NON-NLS-1$ //$NON-NLS-2$
+                properties[1] = System.getProperty("awt.image.incrementaldraw", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+                return properties;
+            }
+        };
+        String properties[] = AccessController.doPrivileged(action);
+        // FIXME: rate is never used, can this code and the get property above
+        // be removed?
+        // int rate;
+        //
+        // try {
+        // rate = Integer.decode(properties[0]).intValue();
+        // } catch (NumberFormatException e) {
+        // rate = 100;
+        // }
+        incrementalImageUpdate = properties[1].equals("true"); //$NON-NLS-1$
+    }
+
+    /**
+     * Instantiates a new component.
+     */
+    protected Component() {
+        toolkit.lockAWT();
+        try {
+            orientation = ComponentOrientation.UNKNOWN;
+            redrawManager = null;
+            //???AWT
+            /*
+            traversalIDs = this instanceof Container ? KeyboardFocusManager.contTraversalIDs
+                    : KeyboardFocusManager.compTraversalIDs;
+            for (int element : traversalIDs) {
+                traversalKeys.put(new Integer(element), null);
+            }
+            behaviour = createBehavior();
+            */
+            behaviour = null;
+            
+            deriveCoalescerFlag();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Determine that the class inherited from Component declares the method
+     * coalesceEvents(), and put the results to the childClassesFlags map.
+     */
+    private void deriveCoalescerFlag() {
+        Class<?> thisClass = getClass();
+        boolean flag = true;
+        synchronized (childClassesFlags) {
+            Boolean flagWrapper = childClassesFlags.get(thisClass);
+            if (flagWrapper == null) {
+                Method coalesceMethod = null;
+                for (Class<?> c = thisClass; c != Component.class; c = c.getSuperclass()) {
+                    try {
+                        coalesceMethod = c.getDeclaredMethod("coalesceEvents", new Class[] { //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent"), //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent") }); //$NON-NLS-1$
+                    } catch (Exception e) {
+                    }
+                    if (coalesceMethod != null) {
+                        break;
+                    }
+                }
+                flag = (coalesceMethod != null);
+                childClassesFlags.put(thisClass, Boolean.valueOf(flag));
+            } else {
+                flag = flagWrapper.booleanValue();
+            }
+        }
+        coalescer = flag;
+        if (flag) {
+            eventsTable = new Hashtable<Integer, LinkedList<AWTEvent>>();
+        } else {
+            eventsTable = null;
+        }
+    }
+
+    /**
+     * Sets the name of the Component.
+     * 
+     * @param name the new name of the Component.
+     */
+    public void setName(String name) {
+        String oldName;
+        toolkit.lockAWT();
+        try {
+            autoName = false;
+            oldName = this.name;
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("name", oldName, name); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the name of this Component.
+     * 
+     * @return the name of this Component.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            if ((name == null) && autoName) {
+                name = autoName();
+            }
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT
+        //int number = toolkit.autoNumber.nextComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Returns the string representation of the Component.
+     * 
+     * @return the string representation of the Component.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public void add(PopupMenu popup) {
+        toolkit.lockAWT();
+        try {
+            if (popup.getParent() == this) {
+                return;
+            }
+            if (popups == null) {
+                popups = new ArrayList<PopupMenu>();
+            }
+            popup.setParent(this);
+            popups.add(popup);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true, if the component contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return true, if the component contains the specified Point,
+     * false otherwise.
+     */
+    public boolean contains(Point p) {
+        toolkit.lockAWT();
+        try {
+            return contains(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true, if the component contains the point with 
+     * the specified coordinates.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if the component contains the point with 
+     * the specified coordinates, false otherwise.
+     */
+    public boolean contains(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return inside(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by replaced by getSize() method.
+     * 
+     * @return the dimension.
+     * 
+     * @deprecated Replaced by getSize() method.
+     */
+    @Deprecated
+    public Dimension size() {
+        toolkit.lockAWT();
+        try {
+            return new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    //???AWT
+    /*
+    public Container getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * List.
+     * 
+     * @param out the out
+     * @param indent the indent
+     * 
+     * @return the nearest heavyweight ancestor in hierarchy or
+     * <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWAncestor() {
+        return (parent != null ? parent.getHWSurface() : null);
+    }
+    */
+    
+    /**
+     * @return heavyweight component that is equal to or is a nearest
+     *         heavyweight container of the current component, or
+     *         <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWSurface() {
+        Component parent;
+        for (parent = this; (parent != null) && (parent.isLightweight()); parent = parent
+                .getParent()) {
+            ;
+        }
+        return parent;
+    }
+
+    Window getWindowAncestor() {
+        Component par;
+        for (par = this; par != null && !(par instanceof Window); par = par.getParent()) {
+            ;
+        }
+        return (Window) par;
+    }
+    */
+    
+    /** To be called by container */
+    //???AWT
+    /*
+    void setParent(Container parent) {
+        this.parent = parent;
+        setRedrawManager();
+    }
+
+    void setRedrawManager() {
+        redrawManager = getRedrawManager();
+    }
+
+    public void remove(MenuComponent menu) {
+        toolkit.lockAWT();
+        try {
+            if (menu.getParent() == this) {
+                menu.setParent(null);
+                popups.remove(menu);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintStream.
+     * 
+     * @param out the output PrintStream object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintStream out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     */
+    public void list(PrintWriter out) {
+        toolkit.lockAWT();
+        try {
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintWriter out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets a string composed of the desired number of 
+     * whitespace characters.
+     * 
+     * @param indent the length of the String to return
+     * 
+     * @return the string composed of the desired number of 
+     * whitespace characters
+     */
+    String getIndentStr(int indent) {
+        char[] ind = new char[indent];
+        for (int i = 0; i < indent; ind[i++] = ' ') {
+            ;
+        }
+        return new String(ind);
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintStream
+     * 
+     * @param out the output PrintStream object.
+     */
+    public void list(PrintStream out) {
+        toolkit.lockAWT();
+        try {
+            // default indent = 1
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the standard system 
+     * output stream.
+     */
+    public void list() {
+        toolkit.lockAWT();
+        try {
+            list(System.out);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints this component. 
+     * 
+     * @param g the Graphics to be used for painting. 
+     */
+    public void print(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void printAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paintAll(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by width and height
+     * parameters.
+     * 
+     * @param width the width of the Component.
+     * @param height the height of the Component.
+     */
+    public void setSize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            resize(width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by Dimension object.
+     * 
+     * @param d the new size of the Component.
+     */
+    public void setSize(Dimension d) {
+        toolkit.lockAWT();
+        try {
+            resize(d);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
+            setBounds(x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param size the size.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(Dimension size) {
+        toolkit.lockAWT();
+        try {
+            setSize(size.width, size.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is completely opaque.
+     * 
+     * @return true, if this component is completely opaque, 
+     *  false by default.
+     */
+    public boolean isOpaque() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isOpaque();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Disables.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void disable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, false);
+    }
+
+    /**
+     * Enables this component.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void enable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(true);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, true);
+    }
+
+    /**
+     * Enables or disable this component.
+     * 
+     * @param b the boolean parameter.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method. 
+     */
+    @Deprecated
+    public void enable(boolean b) {
+        toolkit.lockAWT();
+        try {
+            if (b) {
+                enable();
+            } else {
+                disable();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the location of this component to the specified Point object;
+     * returns the point of the component's top-left corner.
+     * 
+     * @param rv the Point object where the component's top-left corner
+     * position will be stored.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation(Point rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Point();
+            }
+            rv.setLocation(getX(), getY());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component on the form;
+     * returns the point of the component's top-left corner.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation() {
+        toolkit.lockAWT();
+        try {
+            return location();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the size of this Component.
+     * 
+     * @return the size of this Component.
+     */
+    public Dimension getSize() {
+        toolkit.lockAWT();
+        try {
+            return size();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the size of this Component to the specified Dimension 
+     * object.
+     * 
+     * @param rv the Dimension object where the size of the Component 
+     * will be stored.
+     * 
+     * @return the Dimension of this Component.
+     */
+    public Dimension getSize(Dimension rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Dimension();
+            }
+            rv.setSize(getWidth(), getHeight());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is valid. A component is valid 
+     * if it is correctly sized and positioned within its parent container
+     *  and all its children are also valid. 
+     * 
+     * @return true, if the Component is valid, false otherwise.
+     */
+    public boolean isValid() {
+        toolkit.lockAWT();
+        try {
+            return valid && behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @return the Point.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Point location() {
+        toolkit.lockAWT();
+        try {
+            return new Point(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Connects this Component to a native screen resource and makes it 
+     * displayable. This method not be called directly by user applications.
+     */
+    public void addNotify() {
+        toolkit.lockAWT();
+        try {
+            prepare4HierarchyChange();
+            behaviour.addNotify();
+            //???AWT
+//            finishHierarchyChange(this, parent, 0);
+//            if (dropTarget != null) {
+//                dropTarget.addNotify(peer);
+//            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Map to display.
+     * 
+     * @param b the b
+     */
+    void mapToDisplay(boolean b) {
+        //???AWT
+        /*
+        if (b && !isDisplayable()) {
+            if ((this instanceof Window) || ((parent != null) && parent.isDisplayable())) {
+                addNotify();
+            }
+        } else if (!b && isDisplayable()) {
+            removeNotify();
+        }
+        */
+    }
+
+    /**
+     * Gets the toolkit.
+     * 
+     * @return accessible context specific for particular component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+ 
+    /**
+     * Gets Toolkit for the current Component.
+     * 
+     * @return the Toolkit of this Component.
+     */
+    public Toolkit getToolkit() {
+        return toolkit;
+    }
+
+    /**
+     * Gets this component's locking object for AWT component tree 
+     * and layout operations.
+     * 
+     * @return the tree locking object.
+     */
+    public final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * @param evt the Event.
+     * @param what the event's key.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Use ActionListener class for registering event listener.   
+     */
+    @Deprecated
+    public boolean action(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+
+    /**
+     * Gets the property change support.
+     * 
+     * @return the property change support
+     */
+    private PropertyChangeSupport getPropertyChangeSupport() {
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                propertyChangeSupport = new PropertyChangeSupport(this);
+            }
+            return propertyChangeSupport;
+        }
+    }
+    
+    //???AWT
+    /*
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(listener);
+    }
+
+    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(propertyName, listener);
+    }
+
+    public void applyComponentOrientation(ComponentOrientation orientation) {
+        toolkit.lockAWT();
+        try {
+            setComponentOrientation(orientation);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component. 
+     * 
+     * @param id the ID of traversal key.
+     * 
+     * @return true, if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component,
+     * false otherwise. 
+     */
+    public boolean areFocusTraversalKeysSet(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer Id = new Integer(id);
+            if (traversalKeys.containsKey(Id)) {
+                return traversalKeys.get(Id) != null;
+            }
+            // awt.14F=invalid focus traversal key identifier
+            throw new IllegalArgumentException(Messages.getString("awt.14F")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounds of the Component.
+     * 
+     * @return the rectangle bounds of the Component.
+     * 
+     * @deprecated Use getBounds() methood.
+     */
+    @Deprecated
+    public Rectangle bounds() {
+        toolkit.lockAWT();
+        try {
+            return new Rectangle(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image
+     * with the specified width and height that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param width the width of scaled image which status is being checked, or -1.
+     * @param height the height of scaled image which status is being checked, or -1.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Coalesces the existed event with new event.
+     * 
+     * @param existingEvent the existing event in the EventQueue.
+     * @param newEvent the new event to be posted to the EventQueue.
+     * 
+     * @return the coalesced AWTEvent, or null if there is no coalescing done. 
+     */
+    protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) {
+        toolkit.lockAWT();
+        try {
+            // Nothing to do:
+            // 1. Mouse events coalesced at WTK level
+            // 2. Paint events handled by RedrawManager
+            // This method is for overriding only
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component is a coalescer.
+     * 
+     * @return true, if is coalescer
+     */
+    boolean isCoalescer() {
+        return coalescer;
+    }
+
+    /**
+     * Gets the relative event.
+     * 
+     * @param id the id
+     * 
+     * @return the relative event
+     */
+    AWTEvent getRelativeEvent(int id) {
+        Integer idWrapper = new Integer(id);
+        eventsList = eventsTable.get(idWrapper);
+        if (eventsList == null) {
+            eventsList = new LinkedList<AWTEvent>();
+            eventsTable.put(idWrapper, eventsList);
+            return null;
+        }
+        if (eventsList.isEmpty()) {
+            return null;
+        }
+        return eventsList.getLast();
+    }
+
+    /**
+     * Adds the new event.
+     * 
+     * @param event the event
+     */
+    void addNewEvent(AWTEvent event) {
+        eventsList.addLast(event);
+    }
+
+    /**
+     * Removes the relative event.
+     */
+    void removeRelativeEvent() {
+        eventsList.removeLast();
+    }
+
+    /**
+     * Removes the next event.
+     * 
+     * @param id the id
+     */
+    void removeNextEvent(int id) {
+        eventsTable.get(new Integer(id)).removeFirst();
+    }
+
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param producer the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public Image createImage(ImageProducer producer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.createImage(producer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image to be used for double buffering.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * 
+     * @return the off-screen drawable image or null if the component is not 
+     * displayable or GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public Image createImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            ColorModel cm = gc.getColorModel(Transparency.OPAQUE);
+            WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+            Image image = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image with the specified width,
+     * height and ImageCapabilities.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param caps the ImageCapabilities.
+     * 
+     * @return the volatile image
+     * 
+     * @throws AWTException if an image with the specified capabilities 
+     * cannot be created.
+     */
+    public VolatileImage createVolatileImage(int width, int height, ImageCapabilities caps)
+            throws AWTException {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height, caps);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates a volatile off-screen drawable image which is used 
+     * for double buffering.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the volatile image a volatile off-screen drawable image 
+     * which is used for double buffering or null if the component 
+     * is not displayable, or GraphicsEnvironment.isHeadless() method
+     * returns true.
+     */
+    public VolatileImage createVolatileImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Fill the image being created by createImage() or createVolatileImage()
+     * with the component's background color to prepare it for double-buffered
+     * painting.
+     * 
+     * @param image the image
+     * @param width the width
+     * @param height the height
+     */
+    private void fillImageBackground(Image image, int width, int height) {
+        Graphics gr = image.getGraphics();
+        gr.setColor(getBackground());
+        gr.fillRect(0, 0, width, height);
+        gr.dispose();
+    }
+
+    /**
+     * Delivers event.
+     * 
+     * @param evt the event.
+     * 
+     * @deprecated Replaced by dispatchEvent(AWTEvent e) method.
+     */
+    @Deprecated
+    public void deliverEvent(Event evt) {
+        postEvent(evt);
+    }
+
+    /**
+     * Prompts the layout manager to lay out this component. 
+     */
+    public void doLayout() {
+        toolkit.lockAWT();
+        try {
+            layout();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // Implemented in Container
+    }
+
+    /**
+     * Fire property change impl.
+     * 
+     * @param propertyName the property name
+     * @param oldValue the old value
+     * @param newValue the new value
+     */
+    private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
+        PropertyChangeSupport pcs;
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                return;
+            }
+            pcs = propertyChangeSupport;
+        }
+        pcs.firePropertyChange(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Reports a bound property changes for int properties.
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
+        firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
+    }
+
+    /**
+     * Report a bound property change for a boolean-valued property. 
+     *  
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
+        firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean
+                .valueOf(newValue));
+    }
+
+    /**
+     * Reports a bound property change for an Object-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value
+     * @param newValue the property's new value
+     */
+    protected void firePropertyChange(final String propertyName, final Object oldValue,
+            final Object newValue) {
+        firePropertyChangeImpl(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Report a bound property change for a byte-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
+        firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
+    }
+
+    /**
+     * Report a bound property change for a char-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, char oldValue, char newValue) {
+        firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
+    }
+
+    /**
+     * Report a bound property change for a short-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, short oldValue, short newValue) {
+        firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
+    }
+
+    /**
+     * Report a bound property change for a long-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, long oldValue, long newValue) {
+        firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
+    }
+
+    /**
+     * Report a bound property change for a float-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, float oldValue, float newValue) {
+        firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
+    }
+
+    /**
+     * Report a bound property change for a double-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, double oldValue, double newValue) {
+        firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
+    }
+
+    /**
+     * Gets the alignment along the x axis. 
+     * 
+     * @return the alignment along the x axis. 
+     */
+    public float getAlignmentX() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the alignment along the y axis. 
+     * 
+     * @return the alignment along y axis.
+     */
+    public float getAlignmentY() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the background color for this component.
+     * 
+     * @return the background color for this component.
+     */
+    public Color getBackground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if ((backColor == null) && (parent != null)) {
+                return parent.getBackground();
+            }
+            */
+            return backColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of this component.
+     * 
+     * @return the bounding rectangle of this component.
+     */
+    public Rectangle getBounds() {
+        toolkit.lockAWT();
+        try {
+            return bounds();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Writes the data of the bounding rectangle to the specified 
+     * Rectangle object.
+     * 
+     * @param rv the Rectangle object where the bounding rectangle's data is stored.  
+     * 
+     * @return the bounding rectangle.
+     */
+    public Rectangle getBounds(Rectangle rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Rectangle();
+            }
+            rv.setBounds(x, y, w, h);
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the color model of the Component.
+     * 
+     * @return the color model of the Component.
+     */
+    public ColorModel getColorModel() {
+        toolkit.lockAWT();
+        try {
+            return getToolkit().getColorModel();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return the Component which contains the specified Point.
+     */
+    public Component getComponentAt(Point p) {
+        toolkit.lockAWT();
+        try {
+            return getComponentAt(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the point with the
+     * specified coordinates.
+     * 
+     * @param x the x coordinate of the point.
+     * @param y the y coordinate of the point.
+     * 
+     * @return the Component which contains the point with the
+     * specified coordinates.
+     */
+    public Component getComponentAt(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return locate(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the component's orientation.
+     * 
+     * @return the component's orientation.
+     */
+    public ComponentOrientation getComponentOrientation() {
+        toolkit.lockAWT();
+        try {
+            return orientation;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the cursor of the Component.
+     * 
+     * @return the Cursor.
+     */
+    public Cursor getCursor() {
+        toolkit.lockAWT();
+        try {
+            if (cursor != null) {
+                return cursor;
+            //???AWT
+            /*
+            } else if (parent != null) {
+                return parent.getCursor();
+            */
+            }
+            return Cursor.getDefaultCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public DropTarget getDropTarget() {
+        toolkit.lockAWT();
+        try {
+            return dropTarget;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    public Container getFocusCycleRootAncestor() {
+        toolkit.lockAWT();
+        try {
+            for (Container c = parent; c != null; c = c.getParent()) {
+                if (c.isFocusCycleRoot()) {
+                    return c;
+                }
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Set<? extends AWTKeyStroke> keys = traversalKeys.get(kId);
+            if (keys == null && parent != null) {
+                keys = parent.getFocusTraversalKeys(id);
+            }
+            if (keys == null) {
+                keys = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+                        .getDefaultFocusTraversalKeys(id);
+            }
+            return (Set<AWTKeyStroke>) keys;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks if the the focus traversal keys are enabled for this component.
+     * 
+     * @return true, if the the focus traversal keys are enabled for 
+     * this component, false otherwise.
+     */
+    public boolean getFocusTraversalKeysEnabled() {
+        toolkit.lockAWT();
+        try {
+            return focusTraversalKeysEnabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the font metrics of the specified Font.
+     * 
+     * @param f the Font.
+     * 
+     * @return the FontMetrics of the specified Font.
+     */
+    @SuppressWarnings("deprecation")
+    public FontMetrics getFontMetrics(Font f) {
+        return toolkit.getFontMetrics(f);
+    }
+
+    /**
+     * Gets the foreground color of the Component.
+     * 
+     * @return the foreground color of the Component.
+     */
+    public Color getForeground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (foreColor == null && parent != null) {
+                return parent.getForeground();
+            }
+            */
+            return foreColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Graphics of the Component or null if this Component
+     * is not displayable.
+     * 
+     * @return the Graphics of the Component or null if this Component
+     * is not displayable.
+     */
+    public Graphics getGraphics() {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            Graphics g = behaviour.getGraphics(0, 0, w, h);
+            g.setColor(foreColor);
+            g.setFont(font);
+            return g;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Gets the GraphicsConfiguration associated with this Component.
+     * 
+     * @return the GraphicsConfiguration associated with this Component.
+     */
+    public GraphicsConfiguration getGraphicsConfiguration() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            Window win = getWindowAncestor();
+            if (win == null) {
+                return null;
+            }
+            return win.getGraphicsConfiguration();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return null;
+    }
+
+    /**
+     * Gets the height of the Component.
+     * 
+     * @return the height of the Component.
+     */
+    public int getHeight() {
+        toolkit.lockAWT();
+        try {
+            return h;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if paint messages received from the operating system 
+     * should be ignored.
+     * 
+     * @return true if paint messages received from the operating system 
+     * should be ignored, false otherwise.
+     */
+    public boolean getIgnoreRepaint() {
+        toolkit.lockAWT();
+        try {
+            return ignoreRepaint;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input context of this component for handling 
+     * the communication with input methods when text is entered 
+     * in this component.
+     * 
+     * @return the InputContext used by this Component or 
+     * null if no context is specifined.
+     */
+    public InputContext getInputContext() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            Container parent = getParent();
+            if (parent != null) {
+                return parent.getInputContext();
+            }
+            */
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     * 
+     * @return the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     */
+    public InputMethodRequests getInputMethodRequests() {
+        return null;
+    }
+
+    /**
+     * Gets the locale of this Component.
+     * 
+     * @return the locale of this Component.
+     */
+    public Locale getLocale() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (locale == null) {
+                if (parent == null) {
+                    if (this instanceof Window) {
+                        return Locale.getDefault();
+                    }
+                    // awt.150=no parent
+                    throw new IllegalComponentStateException(Messages.getString("awt.150")); //$NON-NLS-1$
+                }
+                return getParent().getLocale();
+            }
+            */
+            return locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component in the form of a point 
+     * specifying the component's top-left corner in the 
+     * screen's coordinate space.
+     * 
+     * @return the Point giving the component's location in the 
+     * screen's coordinate space.
+     * 
+     * @throws IllegalComponentStateException if the component is 
+     * not shown on the screen.
+     */
+    public Point getLocationOnScreen() throws IllegalComponentStateException {
+        toolkit.lockAWT();
+        try {
+            Point p = new Point();
+            if (isShowing()) {
+                //???AWT
+                /*
+                Component comp;
+                for (comp = this; comp != null && !(comp instanceof Window); comp = comp
+                        .getParent()) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                if (comp instanceof Window) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                */
+                return p;
+            }
+            // awt.151=component must be showing on the screen to determine its location
+            throw new IllegalComponentStateException(Messages.getString("awt.151")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the peer. This method should not be called directly by
+     * user applications.
+     * 
+     * @return the ComponentPeer.
+     * 
+     * @deprecated Replaced by isDisplayable().
+     */
+    @Deprecated
+    public ComponentPeer getPeer() {
+        toolkit.lockAWT();
+        try {
+            if (behaviour.isDisplayable()) {
+                return peer;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of the property change listeners registered to
+     * this Component.
+     * 
+     * @return an array of the PropertyChangeListeners registered to
+     * this Component.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return getPropertyChangeSupport().getPropertyChangeListeners();
+    }
+
+    /**
+     * Gets an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     * 
+     * @param propertyName the property name.
+     * 
+     * @return an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+        return getPropertyChangeSupport().getPropertyChangeListeners(propertyName);
+    }
+
+    /**
+     * Gets the width of the Component.
+     * 
+     * @return the width of the Component.
+     */
+    public int getWidth() {
+        toolkit.lockAWT();
+        try {
+            return w;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the x coordinate of the component's top-left corner.
+     * 
+     * @return the x coordinate of the component's top-left corner.
+     */
+    public int getX() {
+        toolkit.lockAWT();
+        try {
+            return x;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the y coordinate of the component's top-left corner.
+     * 
+     * @return the y coordinate of the component's top-left corner.
+     */
+    public int getY() {
+        toolkit.lockAWT();
+        try {
+            return y;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Got the focus.
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent) method.
+     */
+    @Deprecated
+    public boolean gotFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Handles event.
+     * 
+     * @param evt the Event.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processEvent(AWTEvent) method.
+     */
+    @Deprecated
+    public boolean handleEvent(Event evt) {
+        switch (evt.id) {
+            case Event.ACTION_EVENT:
+                return action(evt, evt.arg);
+            case Event.GOT_FOCUS:
+                return gotFocus(evt, null);
+            case Event.LOST_FOCUS:
+                return lostFocus(evt, null);
+            case Event.MOUSE_DOWN:
+                return mouseDown(evt, evt.x, evt.y);
+            case Event.MOUSE_DRAG:
+                return mouseDrag(evt, evt.x, evt.y);
+            case Event.MOUSE_ENTER:
+                return mouseEnter(evt, evt.x, evt.y);
+            case Event.MOUSE_EXIT:
+                return mouseExit(evt, evt.x, evt.y);
+            case Event.MOUSE_MOVE:
+                return mouseMove(evt, evt.x, evt.y);
+            case Event.MOUSE_UP:
+                return mouseUp(evt, evt.x, evt.y);
+            case Event.KEY_ACTION:
+            case Event.KEY_PRESS:
+                return keyDown(evt, evt.key);
+            case Event.KEY_ACTION_RELEASE:
+            case Event.KEY_RELEASE:
+                return keyUp(evt, evt.key);
+        }
+        return false;// event not handled
+    }
+
+    /**
+     * Checks whether the Component is the focus owner or not.
+     * 
+     * @return true, if the Component is the focus owner, false otherwise.
+     */
+    public boolean hasFocus() {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return isFocusOwner();
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Hides the Component.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void hide() {
+        toolkit.lockAWT();
+        try {
+            if (!visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            visible = false;
+            moveFocusOnHide();
+            behaviour.setVisible(false);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(null);
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the point with the specified coordinates 
+     * belongs to the Commponent.
+     * 
+     * @param x the x coordinate of the Point.
+     * @param y the y coordinate of the Point.
+     * 
+     * @return true, if the point with the specified coordinates 
+     * belongs to the Commponent, false otherwise.
+     * 
+     * @deprecated Replaced by contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Invalidates the component, this component and all parents 
+     * above it are marked as needing to be laid out. 
+     */
+    public void invalidate() {
+        toolkit.lockAWT();
+        try {
+            valid = false;
+            resetDefaultSize();
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the background color is set to this Component.
+     * 
+     * @return true, if the background color is set to this Component,
+     * false otherwise.
+     */
+    public boolean isBackgroundSet() {
+        toolkit.lockAWT();
+        try {
+            return backColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not a cursor is set for the Component.
+     * 
+     * @return true, if a cursor is set for the Component,
+     * false otherwise.
+     */
+    public boolean isCursorSet() {
+        toolkit.lockAWT();
+        try {
+            return cursor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is displayable.
+     * 
+     * @return true, if this Component is displayable, false otherwise.
+     */
+    public boolean isDisplayable() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is painted to an buffer
+     * which is copied to the screen later.
+     * 
+     * @return true, if this component is painted to an buffer
+     * which is copied to the screen later, false otherwise.
+     */
+    public boolean isDoubleBuffered() {
+        toolkit.lockAWT();
+        try {
+            // false by default
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is enabled.
+     * 
+     * @return true, if this Component is enabled, false otherwise.
+     */
+    public boolean isEnabled() {
+        toolkit.lockAWT();
+        try {
+            return enabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * "Recursive" isEnabled().
+     * 
+     * @return true if not only component itself is enabled but its heavyweight
+     * parent is also "indirectly" enabled
+     */
+    boolean isIndirectlyEnabled() {
+        Component comp = this;
+        while (comp != null) {
+            if (!comp.isLightweight() && !comp.isEnabled()) {
+                return false;
+            }
+            //???AWT: comp = comp.getRealParent();
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the component is key enabled.
+     * 
+     * @return true, if the component is enabled and indirectly enabled
+     */
+    boolean isKeyEnabled() {
+        if (!isEnabled()) {
+            return false;
+        }
+        return isIndirectlyEnabled();
+    }
+
+    /**
+     * Gets only parent of a child component, but not owner of a window.
+     * 
+     * @return parent of child component, null if component is a top-level
+     * (Window instance)
+     */
+    //???AWT
+    /*
+    Container getRealParent() {
+        return (!(this instanceof Window) ? getParent() : null);
+    }
+
+    public boolean isFocusCycleRoot(Container container) {
+        toolkit.lockAWT();
+        try {
+            return getFocusCycleRootAncestor() == container;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public boolean isFocusOwner() {
+        toolkit.lockAWT();
+        try {
+            return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == this;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks whether or not this Component can be focusable.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     * 
+     * @deprecated Replaced by isFocusable(). 
+     */
+    @Deprecated
+    public boolean isFocusTraversable() {
+        toolkit.lockAWT();
+        try {
+            overridenIsFocusable = false;
+            return focusable; // a Component must either be both focusable and
+            // focus traversable, or neither
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component can be focusable or not.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     */
+    public boolean isFocusable() {
+        toolkit.lockAWT();
+        try {
+            return isFocusTraversable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the Font is set for this Component or not.
+     * 
+     * @return true, if the Font is set, false otherwise.
+     */
+    public boolean isFontSet() {
+        toolkit.lockAWT();
+        try {
+            return font != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if foreground color is set for the Component or not.
+     * 
+     * @return true, if is foreground color is set for the Component,
+     * false otherwise.
+     */
+    public boolean isForegroundSet() {
+        toolkit.lockAWT();
+        try {
+            return foreColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if this component has a lightweight peer.
+     * 
+     * @return true, if this component has a lightweight peer,
+     * false if it has a native peer or no peer.
+     */
+    public boolean isLightweight() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isLightweight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Checks whether or not this Component is shown.
+     * 
+     * @return true, if this Component is shown, false otherwise.
+     */
+    public boolean isShowing() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            return (isVisible() && isDisplayable() && (parent != null) && parent.isShowing());
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return false;
+    }
+
+    /**
+     * Checks whether or not this Component is visible.
+     * 
+     * @return true, if the Component is visible, false otherwise.
+     */
+    public boolean isVisible() {
+        toolkit.lockAWT();
+        try {
+            return visible;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyDown(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyUp(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: Replaced by doLayout() method.
+     * 
+     * @deprecated Replaced by doLayout() method.
+     */
+    @Deprecated
+    public void layout() {
+        toolkit.lockAWT();
+        try {
+            // Implemented in Container
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return The component.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Component locate(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            if (contains(x, y)) {
+                return this;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processFocusEvent(FocusEvent). 
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent).
+     */
+    @Deprecated
+    public boolean lostFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the MouseEvent.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseDown(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public boolean mouseDrag(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseEnter(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseExit(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @return true, if successful.
+     */
+    @Deprecated
+    public boolean mouseMove(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseUp(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by setLocation(int, int) method.
+     * 
+     * @param x the x coordinates.
+     * @param y the y coordinates.
+     * 
+     * @deprecated Replaced by setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
+            setBounds(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    @Deprecated
+    public void nextFocus() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns a string representation of the component's state.
+     * 
+     * @return the string representation of the component's state.
+     */
+    protected String paramString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getName() + "," + getX() + "," + getY() + "," + getWidth() + "x" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                    + getHeight() + (!isVisible() ? ",hidden" : ""); //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public boolean postEvent(Event evt) {
+        boolean handled = handleEvent(evt);
+        if (handled) {
+            return true;
+        }
+        //???AWT
+        /*
+
+        // propagate non-handled events up to parent
+        Component par = parent;
+        // try to call postEvent only on components which
+        // override any of deprecated method handlers
+        // while (par != null && !par.deprecatedEventHandler) {
+        // par = par.parent;
+        // }
+        // translate event coordinates before posting it to parent
+        if (par != null) {
+            evt.translate(x, y);
+            par.postEvent(evt);
+        }
+        
+        */
+        return false;
+    }
+
+    /**
+     * Prepares an image for rendering on the Component. 
+     *  
+     * @param image the Image to be prepared.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image has been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares an image for rendering on the Component with the
+     * specified width, height, and ImageObserver. 
+     * 
+     * @param image the Image to be prepared.
+     * @param width the width of scaled image.
+     * @param height the height of scaled height.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image is been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Makes this Component undisplayable.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (dropTarget != null) {
+                dropTarget.removeNotify(peer);
+            }
+            */
+            prepare4HierarchyChange();
+            ///???AWT: moveFocus();
+            behaviour.removeNotify();
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            removeNotifyInputContext();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Calls InputContext.removeNotify
+     */
+    private void removeNotifyInputContext() {
+        if (!inputMethodsEnabled) {
+            return;
+        }
+        InputContext ic = getInputContext();
+        if (ic != null) {
+            //???AWT: ic.removeNotify(this);
+        }
+    }
+
+    /**
+     * This method is called when some property of a component changes, making
+     * it unfocusable, e. g. hide(), removeNotify(), setEnabled(false),
+     * setFocusable(false) is called, and therefore automatic forward focus
+     * traversal is necessary
+     */
+    //???AWT
+    /*
+    void moveFocus() {
+        // don't use transferFocus(), but query focus traversal policy directly
+        // and if it returns null, transfer focus up cycle
+        // and find next focusable component there
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        Container root = kfm.getCurrentFocusCycleRoot();
+        Component nextComp = this;
+        boolean success = !isFocusOwner();
+        while (!success) {
+            if (root != nextComp.getFocusCycleRootAncestor()) {
+                // component was probably removed from container
+                // so focus will be lost in some time
+                return;
+            }
+            nextComp = root.getFocusTraversalPolicy().getComponentAfter(root, nextComp);
+            if (nextComp == this) {
+                nextComp = null; // avoid looping
+            }
+            if (nextComp != null) {
+                success = nextComp.requestFocusInWindow();
+            } else {
+                nextComp = root;
+                root = root.getFocusCycleRootAncestor();
+                // if no acceptable component is found at all - clear global
+                // focus owner
+                if (root == null) {
+                    if (nextComp instanceof Window) {
+                        Window wnd = (Window) nextComp;
+                        wnd.setFocusOwner(null);
+                        wnd.setRequestedFocus(null);
+                    }
+                    kfm.clearGlobalFocusOwner();
+                    return;
+                }
+            }
+        }
+    }
+    */
+
+    /**
+     * For Container there's a difference between moving focus when being made
+     * invisible or made unfocusable in some other way, because when container
+     * is made invisible, component still remains visible, i. e. its hide() or
+     * setVisible() is not called.
+     */
+    void moveFocusOnHide() {
+        //???AWT: moveFocus();
+    }
+
+    /**
+     * Removes the property change listener registered for this component.
+     * 
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Removes the property change listener registered fot this component 
+     * for the specified propertyy.
+     * 
+     * @param propertyName the property name.
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(propertyName, listener);
+    }
+
+
+    /**
+     * Repaints the specified rectangle of this component within 
+     * tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(long tm, int x, int y, int width, int height) {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            if (width <= 0 || height <= 0 || (redrawManager == null) || !isShowing()) {
+                return;
+            }
+            if (behaviour instanceof LWBehavior) {
+                if (parent == null || !parent.visible || !parent.behaviour.isDisplayable()) {
+                    return;
+                }
+                if (repaintRegion == null) {
+                    repaintRegion = new MultiRectArea(new Rectangle(x, y, width, height));
+                }
+                repaintRegion.intersect(new Rectangle(0, 0, this.w, this.h));
+                repaintRegion.translate(this.x, this.y);
+                parent.repaintRegion = repaintRegion;
+                repaintRegion = null;
+                parent.repaint(tm, x + this.x, y + this.y, width, height);
+            } else {
+                if (repaintRegion != null) {
+                    redrawManager.addUpdateRegion(this, repaintRegion);
+                    repaintRegion = null;
+                } else {
+                    redrawManager.addUpdateRegion(this, new Rectangle(x, y, width, height));
+                }
+                toolkit.getSystemEventQueueCore().notifyEventMonitor(toolkit);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+    }
+
+    /**
+     * Post event.
+     * 
+     * @param e the e
+     */
+    void postEvent(AWTEvent e) {
+        getToolkit().getSystemEventQueueImpl().postEvent(e);
+    }
+
+    /**
+     * Repaints the specified Rectangle of this Component.
+     * 
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(int x, int y, int width, int height) {
+        toolkit.lockAWT();
+        try {
+            repaint(0, x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints this component.
+     */
+    public void repaint() {
+        toolkit.lockAWT();
+        try {
+            if (w > 0 && h > 0) {
+                repaint(0, 0, 0, w, h);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints the component within tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     */
+    public void repaint(long tm) {
+        toolkit.lockAWT();
+        try {
+            repaint(tm, 0, 0, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Requests that this Component get the input focus temporarily. 
+     * This component must be displayable, visible, and focusable.
+     * 
+     * @param temporary this parameter is true if the focus change 
+     * is temporary, when the window loses the focus.
+     * 
+     * @return true if the focus change request is succeeded,
+     * false otherwise.
+     */
+    protected boolean requestFocus(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return requestFocusImpl(temporary, true, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT
+        return false;
+    }
+
+    /**
+     * Requests that this Component get the input focus. 
+     * This component must be displayable, visible, and focusable.
+     */
+    public void requestFocus() {
+        toolkit.lockAWT();
+        try {
+            requestFocus(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    protected boolean requestFocusInWindow(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            Window wnd = getWindowAncestor();
+            if ((wnd == null) || !wnd.isFocused()) {
+                return false;
+            }
+            return requestFocusImpl(temporary, false, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    boolean requestFocusImpl(boolean temporary, boolean crossWindow, boolean rejectionRecovery) {
+        if (!rejectionRecovery && isFocusOwner()) {
+            return true;
+        }
+        Window wnd = getWindowAncestor();
+        Container par = getRealParent();
+        if ((par != null) && par.isRemoved) {
+            return false;
+        }
+        if (!isShowing() || !isFocusable() || !wnd.isFocusableWindow()) {
+            return false;
+        }
+        return KeyboardFocusManager.getCurrentKeyboardFocusManager().requestFocus(this,
+                temporary, crossWindow, true);
+    }
+
+    public boolean requestFocusInWindow() {
+        toolkit.lockAWT();
+        try {
+            return requestFocusInWindow(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Deprecated: replaced by setBounds(int, int, int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width. 
+     * @param h the height.
+     * 
+     * @deprecated Replaced by setBounds(int, int, int, int) method.
+     */
+    @Deprecated
+    public void reshape(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            setBounds(x, y, w, h, boundsMaskParam, true);
+            boundsMaskParam = 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            reshape(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height
+     * and posts the appropriate events.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     * @param bMask the bitmask of bounds options
+     * @param updateBehavior the whether to update the behavoir's bounds as well
+     */
+    void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
+        int oldX = this.x;
+        int oldY = this.y;
+        int oldW = this.w;
+        int oldH = this.h;
+        setBoundsFields(x, y, w, h, bMask);
+        // Moved
+        if ((oldX != this.x) || (oldY != this.y)) {
+            //???AWT: invalidateRealParent();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
+        }
+        // Resized
+        if ((oldW != this.w) || (oldH != this.h)) {
+            invalidate();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
+        }
+        if (updateBehavior) {
+            behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
+        }
+        notifyInputMethod(new Rectangle(x, y, w, h));
+    }
+
+    /**
+     * Calls InputContextImpl.notifyClientWindowChanged.
+     * 
+     * @param bounds the bounds
+     */
+    void notifyInputMethod(Rectangle bounds) {
+        // only Window actually notifies IM of bounds change
+    }
+
+    /**
+     * Sets the bounds fields.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param bMask the b mask
+     */
+    private void setBoundsFields(int x, int y, int w, int h, int bMask) {
+        if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
+            this.w = w;
+            this.h = h;
+        }
+        if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
+            this.x = x;
+            this.y = y;
+        }
+    }
+
+    /**
+     * Gets the native insets.
+     * 
+     * @return the native insets
+     */
+    Insets getNativeInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Gets the insets.
+     * 
+     * @return the insets
+     */
+    Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Checks if is mouse exited expected.
+     * 
+     * @return true, if is mouse exited expected
+     */
+    boolean isMouseExitedExpected() {
+        return mouseExitedExpected;
+    }
+
+    /**
+     * Sets the mouse exited expected.
+     * 
+     * @param expected the new mouse exited expected
+     */
+    void setMouseExitedExpected(boolean expected) {
+        mouseExitedExpected = expected;
+    }
+
+    /**
+     * Sets the new bounding rectangle for this Component.
+     * 
+     * @param r the new bounding rectangle.
+     */
+    public void setBounds(Rectangle r) {
+        toolkit.lockAWT();
+        try {
+            setBounds(r.x, r.y, r.width, r.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the component orientation which affects the component's
+     * elements and text within this component. 
+     * 
+     * @param o the ComponentOrientation object.
+     */
+    public void setComponentOrientation(ComponentOrientation o) {
+        ComponentOrientation oldOrientation;
+        toolkit.lockAWT();
+        try {
+            oldOrientation = orientation;
+            orientation = o;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
+        invalidate();
+    }
+
+    /**
+     * Sets the specified cursor for this Component.
+     * 
+     * @param cursor the new Cursor.
+     */
+    public void setCursor(Cursor cursor) {
+        toolkit.lockAWT();
+        try {
+            this.cursor = cursor;
+            setCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Set current cursor shape to Component's Cursor.
+     */
+    void setCursor() {
+        if (isDisplayable() && isShowing()) {
+            Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
+            Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
+            //???AWT
+            /*
+            if (absRect.contains(absPointerPos)) {
+                // set Cursor only on top-level Windows(on X11)
+                Window topLevelWnd = getWindowAncestor();
+                if (topLevelWnd != null) {
+                    Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos,
+                            topLevelWnd);
+                    Component compUnderCursor = topLevelWnd.findComponentAt(pointerPos);
+                    // if (compUnderCursor == this ||
+                    // compUnderCursor.getCursorAncestor() == this) {
+                    NativeWindow wnd = topLevelWnd.getNativeWindow();
+                    if (compUnderCursor != null && wnd != null) {
+                        compUnderCursor.getRealCursor().getNativeCursor()
+                                .setCursor(wnd.getId());
+                    }
+                    // }
+                }
+            }
+            */
+        }
+    }
+
+    /**
+     * Gets the ancestor Cursor if Component is disabled (directly or via an
+     * ancestor) even if Cursor is explicitly set.
+     * 
+     * @param value the value
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Cursor getRealCursor() {
+        Component cursorAncestor = getCursorAncestor();
+        return cursorAncestor != null ? cursorAncestor.getCursor() : Cursor.getDefaultCursor();
+    }
+    */
+
+    /**
+     * Gets the ancestor(or component itself) whose cursor is set when pointer
+     * is inside component
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Component getCursorAncestor() {
+        Component comp;
+        for (comp = this; comp != null; comp = comp.getParent()) {
+            if (comp instanceof Window || comp.isCursorSet() && comp.isKeyEnabled()) {
+                return comp;
+            }
+        }
+        return null;
+    }
+
+    public void setDropTarget(DropTarget dt) {
+        toolkit.lockAWT();
+        try {
+            if (dropTarget == dt) {
+                return;
+            }
+            DropTarget oldDropTarget = dropTarget;
+            dropTarget = dt;
+            if (oldDropTarget != null) {
+                if (behaviour.isDisplayable()) {
+                    oldDropTarget.removeNotify(peer);
+                }
+                oldDropTarget.setComponent(null);
+            }
+            if (dt != null) {
+                dt.setComponent(this);
+                if (behaviour.isDisplayable()) {
+                    dt.addNotify(peer);
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Sets this component to the "enabled" or "disabled" state depending
+     * on the specified boolean parameter.
+     * 
+     * @param value true if this component should be enabled; false
+     * if this component should be disabled.
+     */
+    public void setEnabled(boolean value) {
+        toolkit.lockAWT();
+        try {
+            enable(value);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the enabled impl.
+     * 
+     * @param value the new enabled impl
+     */
+    void setEnabledImpl(boolean value) {
+        if (enabled != value) {
+            enabled = value;
+            setCursor();
+            if (!enabled) {
+                moveFocusOnHide();
+            }
+            behaviour.setEnabled(value);
+        }
+    }
+
+    //???AWT
+    /*
+    private void fireAccessibleStateChange(AccessibleState state, boolean value) {
+        if (behaviour.isLightweight()) {
+            return;
+        }
+        AccessibleContext ac = getAccessibleContext();
+        if (ac != null) {
+            AccessibleState oldValue = null;
+            AccessibleState newValue = null;
+            if (value) {
+                newValue = state;
+            } else {
+                oldValue = state;
+            }
+            ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, oldValue,
+                    newValue);
+        }
+    }
+    */
+
+    //???AWT
+    /*
+    public void setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes) {
+        Set<? extends AWTKeyStroke> oldTraversalKeys;
+        String propName = "FocusTraversalKeys"; //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Map<Integer, Set<? extends AWTKeyStroke>> keys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+            for (int kid : traversalIDs) {
+                Integer key = new Integer(kid);
+                keys.put(key, getFocusTraversalKeys(kid));
+            }
+            KeyboardFocusManager.checkKeyStrokes(traversalIDs, keys, kId, keystrokes);
+            oldTraversalKeys = traversalKeys.get(new Integer(id));
+            // put a copy of keystrokes object into map:
+            Set<? extends AWTKeyStroke> newKeys = keystrokes;
+            if (keystrokes != null) {
+                newKeys = new HashSet<AWTKeyStroke>(keystrokes);
+            }
+            traversalKeys.put(kId, newKeys);
+            String direction = ""; //$NON-NLS-1$
+            switch (id) {
+                case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                    direction = "forward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                    direction = "backward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+                    direction = "upCycle"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+                    direction = "downCycle"; //$NON-NLS-1$
+                    break;
+            }
+            propName = direction + propName;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange(propName, oldTraversalKeys, keystrokes);
+    }
+    */
+
+    /**
+     * Sets the focus traversal keys state for this component.
+     * 
+     * @param value true if the focus traversal keys state is enabled,
+     * false if the focus traversal keys state is disabled.
+     */
+    public void setFocusTraversalKeysEnabled(boolean value) {
+        boolean oldFocusTraversalKeysEnabled;
+        toolkit.lockAWT();
+        try {
+            oldFocusTraversalKeysEnabled = focusTraversalKeysEnabled;
+            focusTraversalKeysEnabled = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusTraversalKeysEnabled", oldFocusTraversalKeysEnabled, //$NON-NLS-1$
+                focusTraversalKeysEnabled);
+    }
+
+    //???AWT
+    /*
+    public void setFocusable(boolean focusable) {
+        boolean oldFocusable;
+        toolkit.lockAWT();
+        try {
+            calledSetFocusable = true;
+            oldFocusable = this.focusable;
+            this.focusable = focusable;
+            if (!focusable) {
+                moveFocus();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$
+    }
+
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            return (font == null) && (parent != null) ? parent.getFont() : font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Sets the font for this Component.
+     * 
+     * @param f the new font of the Component.
+     */
+    public void setFont(Font f) {
+        Font oldFont;
+        toolkit.lockAWT();
+        try {
+            oldFont = font;
+            setFontImpl(f);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("font", oldFont, font); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the font impl.
+     * 
+     * @param f the new font impl
+     */
+    void setFontImpl(Font f) {
+        font = f;
+        invalidate();
+        if (isShowing()) {
+            repaint();
+        }
+    }
+
+
+    /**
+     * Invalidate the component if it inherits the font from the parent. This
+     * method is overridden in Container.
+     * 
+     * @return true if the component was invalidated, false otherwise
+     */
+    boolean propagateFont() {
+        if (font == null) {
+            invalidate();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the foreground color for this Component.
+     * 
+     * @param c the new foreground color.
+     */
+    public void setForeground(Color c) {
+        Color oldFgColor;
+        toolkit.lockAWT();
+        try {
+            oldFgColor = foreColor;
+            foreColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the background color for the Component.
+     * 
+     * @param c the new background color for this component.
+     */
+    public void setBackground(Color c) {
+        Color oldBkColor;
+        toolkit.lockAWT();
+        try {
+            oldBkColor = backColor;
+            backColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the flag for whether paint messages received from the operating 
+     * system should be ignored or not. 
+     * 
+     * @param value true if paint messages received from the operating 
+     * system should be ignored, false otherwise.
+     */
+    public void setIgnoreRepaint(boolean value) {
+        toolkit.lockAWT();
+        try {
+            ignoreRepaint = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locale of the component.
+     * 
+     * @param locale the new Locale.
+     */
+    public void setLocale(Locale locale) {
+        Locale oldLocale;
+        toolkit.lockAWT();
+        try {
+            oldLocale = this.locale;
+            this.locale = locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("locale", oldLocale, locale); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the location of the Component to the specified point.
+     * 
+     * @param p the new location of the Component
+     */
+    public void setLocation(Point p) {
+        toolkit.lockAWT();
+        try {
+            setLocation(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the location of the Component to the specified x, y coordinates.  
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     */
+    public void setLocation(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            move(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the visibility state of the component.
+     * 
+     * @param b true if the component is visible, false if the component
+     * is not shown.
+     */
+    public void setVisible(boolean b) {
+        // show() & hide() are not deprecated for Window,
+        // so have to call them from setVisible()
+        show(b);
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show() {
+        toolkit.lockAWT();
+        try {
+            if (visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            mapToDisplay(true);
+            validate();
+            visible = true;
+            behaviour.setVisible(true);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(new Rectangle(x, y, w, h));
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @param b the visibility's state.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show(boolean b) {
+        if (b) {
+            show();
+        } else {
+            hide();
+        }
+    }
+
+    //???AWT
+    /*
+    void transferFocus(int dir) {
+        Container root = null;
+        if (this instanceof Container) {
+            Container cont = (Container) this;
+            if (cont.isFocusCycleRoot()) {
+                root = cont.getFocusTraversalRoot();
+            }
+        }
+        if (root == null) {
+            root = getFocusCycleRootAncestor();
+        }
+        // transfer focus up cycle if root is unreachable
+        Component comp = this;
+        while ((root != null)
+                && !(root.isFocusCycleRoot() && root.isShowing() && root.isEnabled() && root
+                        .isFocusable())) {
+            comp = root;
+            root = root.getFocusCycleRootAncestor();
+        }
+        if (root == null) {
+            return;
+        }
+        FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
+        Component nextComp = null;
+        switch (dir) {
+            case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentAfter(root, comp);
+                break;
+            case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentBefore(root, comp);
+                break;
+        }
+        if (nextComp != null) {
+            nextComp.requestFocus(false);
+        }
+    }
+    
+    public void transferFocus() {
+        toolkit.lockAWT();
+        try {
+            nextFocus();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusBackward() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusUpCycle() {
+        toolkit.lockAWT();
+        try {
+            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+            Container root = kfm.getCurrentFocusCycleRoot();
+            
+            if(root == null) {
+                return;
+            }
+            
+            boolean success = false;
+            Component nextComp = null;
+            Container newRoot = root;
+            do {
+                nextComp = newRoot instanceof Window ? newRoot.getFocusTraversalPolicy()
+                        .getDefaultComponent(newRoot) : newRoot;
+                newRoot = newRoot.getFocusCycleRootAncestor();
+                if (nextComp == null) {
+                    break;
+                }
+                success = nextComp.requestFocusInWindow();
+                if (newRoot == null) {
+                    break;
+                }
+                kfm.setGlobalCurrentFocusCycleRoot(newRoot);
+            } while (!success);
+            if (!success && root != newRoot) {
+                kfm.setGlobalCurrentFocusCycleRoot(root);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Validates that this component has a valid layout.
+     */
+    public void validate() {
+        toolkit.lockAWT();
+        try {
+            if (!behaviour.isDisplayable()) {
+                return;
+            }
+            validateImpl();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Validate impl.
+     */
+    void validateImpl() {
+        valid = true;
+    }
+
+    /**
+     * Gets the native window.
+     * 
+     * @return the native window
+     */
+    NativeWindow getNativeWindow() {
+        return behaviour.getNativeWindow();
+    }
+
+    /**
+     * Checks whether or not a maximum size is set for the Component.
+     * 
+     * @return true, if the maximum size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isMaximumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return maximumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the minimum size is set for the component.
+     * 
+     * @return true, if the minimum size is set for the component,
+     * false otherwise.
+     */
+    public boolean isMinimumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the preferred size is set for the Component.
+     * 
+     * @return true, if the preferred size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isPreferredSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the maximum size of the Component.
+     * 
+     * @return the maximum size of the Component.
+     */
+    public Dimension getMaximumSize() {
+        toolkit.lockAWT();
+        try {
+            return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(
+                    Short.MAX_VALUE, Short.MAX_VALUE);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the minimum size of the Component.
+     * 
+     * @return the minimum size of the Component.
+     */
+    public Dimension getMinimumSize() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public Dimension minimumSize() {
+        toolkit.lockAWT();
+        try {
+            if (isMinimumSizeSet()) {
+                return (Dimension)minimumSize.clone();
+            }
+            Dimension defSize = getDefaultMinimumSize();
+            if (defSize != null) {
+                return (Dimension)defSize.clone();
+            }
+            return isDisplayable()? new Dimension(1, 1) : new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the preferred size of the Component.
+     * 
+     * @return the preferred size of the Component.
+     */
+    public Dimension getPreferredSize() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getPreferredSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getPreferredSize() method.
+     */
+    @Deprecated
+    public Dimension preferredSize() {
+        toolkit.lockAWT();
+        try {
+            if (isPreferredSizeSet()) {
+                return new Dimension(preferredSize);
+            }
+            Dimension defSize = getDefaultPreferredSize();
+            if (defSize != null) {
+                return new Dimension(defSize);
+            }
+            return new Dimension(getMinimumSize());
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the maximum size of the Component.
+     * 
+     * @param maximumSize the new maximum size of the Component.
+     */
+    public void setMaximumSize(Dimension maximumSize) {
+        Dimension oldMaximumSize;
+        toolkit.lockAWT();
+        try {
+            oldMaximumSize = this.maximumSize;
+            if (oldMaximumSize != null) {
+                oldMaximumSize = oldMaximumSize.getSize();
+            }
+            if (this.maximumSize == null) {
+                if (maximumSize != null) {
+                    this.maximumSize = new Dimension(maximumSize);
+                }
+            } else {
+                if (maximumSize != null) {
+                    this.maximumSize.setSize(maximumSize);
+                } else {
+                    this.maximumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the minimum size of the Component.
+     * 
+     * @param minimumSize the new minimum size of the Component.
+     */
+    public void setMinimumSize(Dimension minimumSize) {
+        Dimension oldMinimumSize;
+        toolkit.lockAWT();
+        try {
+            oldMinimumSize = this.minimumSize;
+            if (oldMinimumSize != null) {
+                oldMinimumSize = oldMinimumSize.getSize();
+            }
+            if (this.minimumSize == null) {
+                if (minimumSize != null) {
+                    this.minimumSize = new Dimension(minimumSize);
+                }
+            } else {
+                if (minimumSize != null) {
+                    this.minimumSize.setSize(minimumSize);
+                } else {
+                    this.minimumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the preferred size of the Component.
+     * 
+     * @param preferredSize the new preferred size of the Component.
+     */
+    public void setPreferredSize(Dimension preferredSize) {
+        Dimension oldPreferredSize;
+        toolkit.lockAWT();
+        try {
+            oldPreferredSize = this.preferredSize;
+            if (oldPreferredSize != null) {
+                oldPreferredSize = oldPreferredSize.getSize();
+            }
+            if (this.preferredSize == null) {
+                if (preferredSize != null) {
+                    this.preferredSize = new Dimension(preferredSize);
+                }
+            } else {
+                if (preferredSize != null) {
+                    this.preferredSize.setSize(preferredSize);
+                } else {
+                    this.preferredSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    RedrawManager getRedrawManager() {
+        if (parent == null) {
+            return null;
+        }
+        return parent.getRedrawManager();
+    }
+    */
+
+    /**
+     * Checks if is focusability explicitly set.
+     * 
+     * @return true if component has a focusable peer
+     */
+    //???AWT
+    /*
+    boolean isPeerFocusable() {
+        // The recommendations for Windows and Unix are that
+        // Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows,
+        // and lightweight Components have non-focusable peers,
+        // and all other Components have focusable peers.
+        if (this instanceof Canvas || this instanceof Label || this instanceof Panel
+                || this instanceof Scrollbar || this instanceof ScrollPane
+                || this instanceof Window || isLightweight()) {
+            return false;
+        }
+        return true;
+    }
+    */
+
+    /**
+     * @return true if focusability was explicitly set via a call to
+     *         setFocusable() or via overriding isFocusable() or
+     *         isFocusTraversable()
+     */
+    boolean isFocusabilityExplicitlySet() {
+        return calledSetFocusable || overridenIsFocusable;
+    }
+
+    /**
+     * Paints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paintAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Updates this Component.
+     * 
+     * @param g the Graphics to be used for updating.
+     */
+    public void update(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            if (!isLightweight() && !isPrepainter()) {
+                g.setColor(getBackground());
+                g.fillRect(0, 0, w, h);
+                g.setColor(getForeground());
+            }
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Paints this component.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paint(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            // Just to nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares the component to be painted.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    void prepaint(Graphics g) {
+        // Just to nothing. For overriding.
+    }
+
+    /**
+     * Checks if is prepainter.
+     * 
+     * @return true, if is prepainter
+     */
+    boolean isPrepainter() {
+        return false;
+    }
+
+    /**
+     * Prepare4 hierarchy change.
+     */
+    void prepare4HierarchyChange() {
+        if (hierarchyChangingCounter++ == 0) {
+            wasShowing = isShowing();
+            wasDisplayable = isDisplayable();
+            prepareChildren4HierarchyChange();
+        }
+    }
+
+    /**
+     * Prepare children4 hierarchy change.
+     */
+    void prepareChildren4HierarchyChange() {
+        // To be inherited by Container
+    }
+
+    //???AWT
+    /*
+    void finishHierarchyChange(Component changed, Container changedParent, int ancestorFlags) {
+        if (--hierarchyChangingCounter == 0) {
+            int changeFlags = ancestorFlags;
+            if (wasShowing != isShowing()) {
+                changeFlags |= HierarchyEvent.SHOWING_CHANGED;
+            }
+            if (wasDisplayable != isDisplayable()) {
+                changeFlags |= HierarchyEvent.DISPLAYABILITY_CHANGED;
+            }
+            if (changeFlags > 0) {
+                postEvent(new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED, changed,
+                        changedParent, changeFlags));
+            }
+            finishChildrenHierarchyChange(changed, changedParent, ancestorFlags);
+        }
+    }
+
+
+    void finishChildrenHierarchyChange(Component changed, Container changedParent,
+            int ancestorFlags) {
+        // To be inherited by Container
+    }
+
+    void postHierarchyBoundsEvents(Component changed, int id) {
+        postEvent(new HierarchyEvent(this, id, changed, null, 0));
+    }
+    */
+    
+    /**
+     * Spread hierarchy bounds events.
+     * 
+     * @param changed the changed
+     * @param id the id
+     */
+    void spreadHierarchyBoundsEvents(Component changed, int id) {
+        // To be inherited by Container
+    }
+
+    /**
+     * Dispatches an event to this component.
+     * 
+     * @param e the Event.
+     */
+    public final void dispatchEvent(AWTEvent e) {
+        //???AWT
+        /*
+        if (e.isConsumed()) {
+            return;
+        }
+        if (e instanceof PaintEvent) {
+            toolkit.dispatchAWTEvent(e);
+            processPaintEvent((PaintEvent) e);
+            return;
+        }
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        if (!e.dispatchedByKFM && kfm.dispatchEvent(e)) {
+            return;
+        }
+        if (e instanceof KeyEvent) {
+            KeyEvent ke = (KeyEvent) e;
+            // consumes KeyEvent which represents a focus traversal key
+            if (getFocusTraversalKeysEnabled()) {
+                kfm.processKeyEvent(this, ke);
+                if (ke.isConsumed()) {
+                    return;
+                }
+            }
+        }
+        if (inputMethodsEnabled && dispatchToIM && e.isPosted && dispatchEventToIM(e)) {
+            return;
+        }
+        if (e.getID() == WindowEvent.WINDOW_ICONIFIED) {
+            notifyInputMethod(null);
+        }
+        AWTEvent.EventDescriptor descriptor = toolkit.eventTypeLookup.getEventDescriptor(e);
+        toolkit.dispatchAWTEvent(e);
+        if (descriptor != null) {
+            if (isEventEnabled(descriptor.eventMask)
+                    || (getListeners(descriptor.listenerType).length > 0)) {
+                processEvent(e);
+            }
+            // input events can be consumed by user listeners:
+            if (!e.isConsumed() && ((enabledAWTEvents & descriptor.eventMask) != 0)) {
+                postprocessEvent(e, descriptor.eventMask);
+            }
+        }
+        postDeprecatedEvent(e);
+        */
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param e the e
+     */
+    private void postDeprecatedEvent(AWTEvent e) {
+        if (deprecatedEventHandler) {
+            Event evt = e.getEvent();
+            if (evt != null) {
+                postEvent(evt);
+            }
+        }
+    }
+
+    /**
+     * Postprocess event.
+     * 
+     * @param e the e
+     * @param eventMask the event mask
+     */
+    void postprocessEvent(AWTEvent e, long eventMask) {
+        toolkit.lockAWT();
+        try {
+            // call system listeners under AWT lock
+            if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+                preprocessFocusEvent((FocusEvent) e);
+            } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+                preprocessKeyEvent((KeyEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+                preprocessMouseEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+                preprocessMouseMotionEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+                preprocessComponentEvent((ComponentEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+                preprocessMouseWheelEvent((MouseWheelEvent) e);
+            } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+                preprocessInputMethodEvent((InputMethodEvent) e);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Preprocess input method event.
+     * 
+     * @param e the e
+     */
+    private void preprocessInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse wheel event.
+     * 
+     * @param e the e
+     */
+    private void preprocessMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getSystemListeners());
+    }
+
+    /**
+     * Process mouse wheel event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseWheelEventImpl(MouseWheelEvent e, Collection<MouseWheelListener> c) {
+        for (MouseWheelListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_WHEEL:
+                    listener.mouseWheelMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Preprocess component event.
+     * 
+     * @param e the e
+     */
+    private void preprocessComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse motion event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess key event.
+     * 
+     * @param e the e
+     */
+    void preprocessKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess focus event.
+     * 
+     * @param e the e
+     */
+    void preprocessFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getSystemListeners());
+    }
+
+    /**
+     * Processes AWTEvent occurred on this component. 
+     * 
+     * @param e the AWTEvent.
+     */
+    protected void processEvent(AWTEvent e) {
+        long eventMask = toolkit.eventTypeLookup.getEventMask(e);
+        if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+            processComponentEvent((ComponentEvent) e);
+        } else if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+            processFocusEvent((FocusEvent) e);
+        } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+            processKeyEvent((KeyEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+            processMouseEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+            processMouseWheelEvent((MouseWheelEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+            processMouseMotionEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_EVENT_MASK) {
+            processHierarchyEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
+            processHierarchyBoundsEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+            processInputMethodEvent((InputMethodEvent) e);
+        }
+    }
+
+    /**
+     * Gets an array of all listener's objects based on the specified
+     * listener type and registered to this Component.
+     * 
+     * @param listenerType the listener type.
+     * 
+     * @return an array of all listener's objects based on the specified
+     * listener type and registered to this Component. 
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
+        if (ComponentListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getComponentListeners();
+        } else if (FocusListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getFocusListeners();
+        } else if (HierarchyBoundsListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyBoundsListeners();
+        } else if (HierarchyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyListeners();
+        } else if (InputMethodListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getInputMethodListeners();
+        } else if (KeyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getKeyListeners();
+        } else if (MouseWheelListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseWheelListeners();
+        } else if (MouseMotionListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseMotionListeners();
+        } else if (MouseListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseListeners();
+        } else if (PropertyChangeListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getPropertyChangeListeners();
+        }
+        return (T[]) Array.newInstance(listenerType, 0);
+    }
+
+    /**
+     * Process paint event.
+     * 
+     * @param event the event
+     */
+    private void processPaintEvent(PaintEvent event) {
+        if (redrawManager == null) {
+            return;
+        }
+        Rectangle clipRect = event.getUpdateRect();
+        if ((clipRect.width <= 0) || (clipRect.height <= 0)) {
+            return;
+        }
+        Graphics g = getGraphics();
+        if (g == null) {
+            return;
+        }
+        initGraphics(g, event);
+        if (!getIgnoreRepaint()) {
+            if (event.getID() == PaintEvent.PAINT) {
+                paint(g);
+            } else {
+                update(g);
+            }
+        }
+        g.dispose();
+    }
+
+    /**
+     * Inits the graphics.
+     * 
+     * @param g the g
+     * @param e the e
+     */
+    void initGraphics(Graphics g, PaintEvent e) {
+        Rectangle clip = e.getUpdateRect();
+        if (clip instanceof ClipRegion) {
+            g.setClip(((ClipRegion) clip).getClip());
+        } else {
+            g.setClip(clip);
+        }
+        if (isPrepainter()) {
+            prepaint(g);
+        } else if (!isLightweight() && (e.getID() == PaintEvent.PAINT)) {
+            g.setColor(getBackground());
+            g.fillRect(0, 0, w, h);
+        }
+        g.setFont(getFont());
+        g.setColor(getForeground());
+    }
+
+    /**
+     * Enables the events with the specified event mask to be delivered to 
+     * this component.
+     * 
+     * @param eventsToEnable the events mask which specifies the types 
+     * of events to enable.
+     */
+    protected final void enableEvents(long eventsToEnable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents |= eventsToEnable;
+            deprecatedEventHandler = false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Enable awt events.
+     * 
+     * @param eventsToEnable the events to enable
+     */
+    private void enableAWTEvents(long eventsToEnable) {
+        enabledAWTEvents |= eventsToEnable;
+    }
+
+    /**
+     * Disables the events with types specified by the specified event mask 
+     * from being delivered to this component.
+     * 
+     * @param eventsToDisable the event mask specifying the event types. 
+     */
+    protected final void disableEvents(long eventsToDisable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents &= ~eventsToDisable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /*
+     * For use in MouseDispatcher only. Really it checks not only mouse events.
+     */
+    /**
+     * Checks if is mouse event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is mouse event enabled
+     */
+    boolean isMouseEventEnabled(long eventMask) {
+        return (isEventEnabled(eventMask) || (enabledAWTEvents & eventMask) != 0);
+    }
+
+    /**
+     * Checks if is event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is event enabled
+     */
+    boolean isEventEnabled(long eventMask) {
+        return ((enabledEvents & eventMask) != 0);
+    }
+
+    /**
+     * Enables or disables input method support for this component. 
+     * 
+     * @param enable true to enable input method support, false to disable it. 
+     */
+    public void enableInputMethods(boolean enable) {
+        toolkit.lockAWT();
+        try {
+            if (!enable) {
+                removeNotifyInputContext();
+            }
+            inputMethodsEnabled = enable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of all component's listeners registered for this
+     * component.
+     * 
+     * @return an array of all component's listeners registered for this
+     * component.
+     */
+    public ComponentListener[] getComponentListeners() {
+        return componentListeners.getUserListeners(new ComponentListener[0]);
+    }
+
+    /**
+     * Adds the specified component listener to the Component for receiving
+     * component's event.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void addComponentListener(ComponentListener l) {
+        componentListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the component listener registered for this Component.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void removeComponentListener(ComponentListener l) {
+        componentListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a component event that has occurred on this component 
+     * by dispatching them to any registered ComponentListener objects.
+     * 
+     * @param e the ComponentEvent.
+     */
+    protected void processComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getUserListeners());
+    }
+
+    /**
+     * Process component event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processComponentEventImpl(ComponentEvent e, Collection<ComponentListener> c) {
+        for (ComponentListener listener : c) {
+            switch (e.getID()) {
+                case ComponentEvent.COMPONENT_HIDDEN:
+                    listener.componentHidden(e);
+                    break;
+                case ComponentEvent.COMPONENT_MOVED:
+                    listener.componentMoved(e);
+                    break;
+                case ComponentEvent.COMPONENT_RESIZED:
+                    listener.componentResized(e);
+                    break;
+                case ComponentEvent.COMPONENT_SHOWN:
+                    listener.componentShown(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of focus listeners registered for this Component.
+     * 
+     * @return the array of focus listeners registered for this Component.
+     */
+    public FocusListener[] getFocusListeners() {
+        return focusListeners.getUserListeners(new FocusListener[0]);
+    }
+
+    /**
+     * Adds the specified focus listener to the Component for receiving
+     * focus events.
+     * 
+     * @param l the FocusListener.
+     */
+    public void addFocusListener(FocusListener l) {
+        focusListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt focus listener.
+     * 
+     * @param l the l
+     */
+    void addAWTFocusListener(FocusListener l) {
+        enableAWTEvents(AWTEvent.FOCUS_EVENT_MASK);
+        focusListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the focus listener registered for this Component.
+     * 
+     * @param l the FocusListener.
+     */
+    public void removeFocusListener(FocusListener l) {
+        focusListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a FocusEvent that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the FocusEvent.
+     */
+    protected void processFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getUserListeners());
+    }
+
+    /**
+     * Process focus event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processFocusEventImpl(FocusEvent e, Collection<FocusListener> c) {
+        for (FocusListener listener : c) {
+            switch (e.getID()) {
+                case FocusEvent.FOCUS_GAINED:
+                    listener.focusGained(e);
+                    break;
+                case FocusEvent.FOCUS_LOST:
+                    listener.focusLost(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of registered HierarchyListeners for
+     * this Component.
+     * 
+     * @return an array of registered HierarchyListeners for
+     * this Component.
+     */
+    public HierarchyListener[] getHierarchyListeners() {
+        return hierarchyListeners.getUserListeners(new HierarchyListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy listener.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void addHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy listener registered for this component.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void removeHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy event that has occurred on this component
+     * by dispatching it to the registered listeners. 
+     * 
+     * @param e the HierarchyEvent.
+     */
+    protected void processHierarchyEvent(HierarchyEvent e) {
+        for (HierarchyListener listener : hierarchyListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.HIERARCHY_CHANGED:
+                    listener.hierarchyChanged(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of HierarchyBoundsListener objects registered
+     * to this Component.
+     * 
+     * @return an array of HierarchyBoundsListener objects.
+     */
+    public HierarchyBoundsListener[] getHierarchyBoundsListeners() {
+        return hierarchyBoundsListeners.getUserListeners(new HierarchyBoundsListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy bounds listener.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy bounds listener registered for this Component.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy bounds event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the HierarchyBoundsEvent.
+     */
+    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
+        for (HierarchyBoundsListener listener : hierarchyBoundsListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.ANCESTOR_MOVED:
+                    listener.ancestorMoved(e);
+                    break;
+                case HierarchyEvent.ANCESTOR_RESIZED:
+                    listener.ancestorResized(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the key listeners registered to the Component.
+     * 
+     * @return an array of the key listeners registered to the Component.
+     */
+    public KeyListener[] getKeyListeners() {
+        return keyListeners.getUserListeners(new KeyListener[0]);
+    }
+
+    /**
+     * Adds the specified key listener.
+     * 
+     * @param l the KeyListener.
+     */
+    public void addKeyListener(KeyListener l) {
+        keyListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt key listener.
+     * 
+     * @param l the l
+     */
+    void addAWTKeyListener(KeyListener l) {
+        enableAWTEvents(AWTEvent.KEY_EVENT_MASK);
+        keyListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the key listener registered for this Component.
+     * 
+     * @param l the KeyListener.
+     */
+    public void removeKeyListener(KeyListener l) {
+        keyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a key event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the KeyEvent.
+     */
+    protected void processKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getUserListeners());
+    }
+
+    /**
+     * Process key event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processKeyEventImpl(KeyEvent e, Collection<KeyListener> c) {
+        for (KeyListener listener : c) {
+            switch (e.getID()) {
+                case KeyEvent.KEY_PRESSED:
+                    listener.keyPressed(e);
+                    break;
+                case KeyEvent.KEY_RELEASED:
+                    listener.keyReleased(e);
+                    break;
+                case KeyEvent.KEY_TYPED:
+                    listener.keyTyped(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse listeners registered to the Component.
+     * 
+     * @return an array of the mouse listeners registered to the Component.
+     */
+    public MouseListener[] getMouseListeners() {
+        return mouseListeners.getUserListeners(new MouseListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse listener.
+     * 
+     * @param l the MouseListener.
+     */
+    public void addMouseListener(MouseListener l) {
+        mouseListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt mouse listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseListener(MouseListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_EVENT_MASK);
+        mouseListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse motion listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseMotionListener(MouseMotionListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+        mouseMotionListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt component listener.
+     * 
+     * @param l the l
+     */
+    void addAWTComponentListener(ComponentListener l) {
+        enableAWTEvents(AWTEvent.COMPONENT_EVENT_MASK);
+        componentListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt input method listener.
+     * 
+     * @param l the l
+     */
+    void addAWTInputMethodListener(InputMethodListener l) {
+        enableAWTEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+        inputMethodListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse wheel listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseWheelListener(MouseWheelListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+        mouseWheelListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the mouse listener registered for this Component.
+     * 
+     * @param l the MouseListener.
+     */
+    public void removeMouseListener(MouseListener l) {
+        mouseListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getUserListeners());
+    }
+
+    /**
+     * Process mouse event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseEventImpl(MouseEvent e, Collection<MouseListener> c) {
+        for (MouseListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_CLICKED:
+                    listener.mouseClicked(e);
+                    break;
+                case MouseEvent.MOUSE_ENTERED:
+                    listener.mouseEntered(e);
+                    break;
+                case MouseEvent.MOUSE_EXITED:
+                    listener.mouseExited(e);
+                    break;
+                case MouseEvent.MOUSE_PRESSED:
+                    listener.mousePressed(e);
+                    break;
+                case MouseEvent.MOUSE_RELEASED:
+                    listener.mouseReleased(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Process mouse motion event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseMotionEventImpl(MouseEvent e, Collection<MouseMotionListener> c) {
+        for (MouseMotionListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_DRAGGED:
+                    listener.mouseDragged(e);
+                    break;
+                case MouseEvent.MOUSE_MOVED:
+                    listener.mouseMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse motion listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseMotionListeners registered to
+     * the Component.
+     */
+    public MouseMotionListener[] getMouseMotionListeners() {
+        return mouseMotionListeners.getUserListeners(new MouseMotionListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse motion listener.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void addMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse motion listener registered for this component.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void removeMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse motion event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the mouse wheel listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseWheelListeners registered to
+     * the Component.
+     */
+    public MouseWheelListener[] getMouseWheelListeners() {
+        return mouseWheelListeners.getUserListeners(new MouseWheelListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse wheel listener.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void addMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse wheel listener registered for this component.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void removeMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse wheel event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseWheelEvent.
+     */
+    protected void processMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the InputMethodListener listeners 
+     * registered to the Component.
+     * 
+     * @return an array of the InputMethodListener listeners 
+     * registered to the Component.
+     */
+    public InputMethodListener[] getInputMethodListeners() {
+        return inputMethodListeners.getUserListeners(new InputMethodListener[0]);
+    }
+
+    /**
+     * Adds the specified input method listener.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void addInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the input method listener registered for this component.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void removeInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes an input method event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the InputMethodEvent.
+     */
+    protected void processInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getUserListeners());
+    }
+
+    /**
+     * Process input method event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processInputMethodEventImpl(InputMethodEvent e,
+            Collection<InputMethodListener> c) {
+        for (InputMethodListener listener : c) {
+            switch (e.getID()) {
+                case InputMethodEvent.CARET_POSITION_CHANGED:
+                    listener.caretPositionChanged(e);
+                    break;
+                case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+                    listener.inputMethodTextChanged(e);
+                    break;
+            }
+        }
+    }
+
+    //???AWT
+    /*
+    public Point getMousePosition() throws HeadlessException {
+        Point absPointerPos = MouseInfo.getPointerInfo().getLocation();
+        Window winUnderPtr = toolkit.dispatcher.mouseDispatcher.findWindowAt(absPointerPos);
+        Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos, winUnderPtr);
+        boolean isUnderPointer = false;
+        if (winUnderPtr == null) {
+            return null;
+        }
+        isUnderPointer = winUnderPtr.isComponentAt(this, pointerPos);
+        if (isUnderPointer) {
+            return MouseDispatcher.convertPoint(null, absPointerPos, this);
+        }
+        return null;
+    }
+    */
+
+    /**
+     * Set native caret at the given position <br>
+     * Note: this method takes AWT lock inside because it walks through the
+     * component hierarchy.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPos(final int x, final int y) {
+        Runnable r = new Runnable() {
+            public void run() {
+                toolkit.lockAWT();
+                try {
+                    setCaretPosImpl(x, y);
+                } finally {
+                    toolkit.unlockAWT();
+                }
+            }
+        };
+        if (Thread.currentThread() instanceof EventDispatchThread) {
+            r.run();
+        } else {
+            toolkit.getSystemEventQueueImpl().postEvent(new InvocationEvent(this, r));
+        }
+    }
+
+    /**
+     * This method should be called only at event dispatch thread.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPosImpl(int x, int y) {
+        Component c = this;
+        while ((c != null) && c.behaviour.isLightweight()) {
+            x += c.x;
+            y += c.y;
+            //???AWT: c = c.getParent();
+        }
+        if (c == null) {
+            return;
+        }
+        //???AWT
+        /*
+        if (c instanceof Window) {
+            Insets insets = c.getNativeInsets();
+            x -= insets.left;
+            y -= insets.top;
+        }
+        toolkit.getWindowFactory().setCaretPosition(x, y);
+        */
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default minimum size.
+     * 
+     * @return the default minimum size
+     */
+    Dimension getDefaultMinimumSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default preferred size.
+     * 
+     * @return the default preferred size
+     */
+    Dimension getDefaultPreferredSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Reset default size.
+     */
+    void resetDefaultSize() {
+    }
+
+    //???AWT
+    /*
+    ComponentBehavior createBehavior() {
+        return new LWBehavior(this);
+    }
+    */
+
+    /**
+     * Gets the default background.
+     * 
+     * @return the default background
+     */
+    Color getDefaultBackground() {
+        //???AWT: return getWindowAncestor().getDefaultBackground();
+        return getBackground();
+    }
+
+    /**
+     * Gets the default foreground.
+     * 
+     * @return the default foreground
+     */
+    Color getDefaultForeground() {
+        //???AWT return getWindowAncestor().getDefaultForeground();
+        return getForeground();
+    }
+
+    /**
+     * Called when native resource for this component is created (for
+     * heavyweights only).
+     * 
+     * @param win the win
+     */
+    void nativeWindowCreated(NativeWindow win) {
+        // to be overridden
+    }
+
+    /**
+     * Determine the component's area hidden behind the windows that have higher
+     * Z-order, including windows of other applications.
+     * 
+     * @param image the image
+     * @param destLocation the dest location
+     * @param destSize the dest size
+     * @param source the source
+     * 
+     * @return the calculated region, or null if it cannot be determined
+     */
+    //???AWT
+    /*
+    MultiRectArea getObscuredRegion(Rectangle part) {
+        if (!visible || parent == null || !parent.visible) {
+            return null;
+        }
+        Rectangle r = new Rectangle(0, 0, w, h);
+        if (part != null) {
+            r = r.intersection(part);
+        }
+        if (r.isEmpty()) {
+            return null;
+        }
+        r.translate(x, y);
+        MultiRectArea ret = parent.getObscuredRegion(r);
+        if (ret != null) {
+            parent.addObscuredRegions(ret, this);
+            ret.translate(-x, -y);
+            ret.intersect(new Rectangle(0, 0, w, h));
+        }
+        return ret;
+    }
+    */
+
+    //???AWT
+    /*
+    private void readObject(ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+        stream.defaultReadObject();
+        FieldsAccessor accessor = new FieldsAccessor(Component.class, this);
+        accessor.set("toolkit", Toolkit.getDefaultToolkit()); //$NON-NLS-1$
+        accessor.set("behaviour", createBehavior()); //$NON-NLS-1$
+        accessor.set("componentLock", new Object()); // $NON-LOCK-1$ //$NON-NLS-1$
+    }
+    */
+
+    final void onDrawImage(Image image, Point destLocation, Dimension destSize, Rectangle source) {
+        ImageParameters imageParams;
+        if (updatedImages == null) {
+            updatedImages = new HashMap<Image, ImageParameters>();
+        }
+        imageParams = updatedImages.get(image);
+        if (imageParams == null) {
+            imageParams = new ImageParameters();
+            updatedImages.put(image, imageParams);
+        }
+        imageParams.addDrawing(destLocation, destSize, source);
+    }
+
+    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            boolean done = false;
+            if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
+                done = true;
+            } else if ((infoflags & SOMEBITS) != 0 && incrementalImageUpdate) {
+                done = true;
+            }
+            if (done) {
+                repaint();
+            }
+            return (infoflags & (ABORT | ALLBITS)) == 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    private void invalidateRealParent() {
+        Container realParent = getRealParent();
+        if ((realParent != null) && realParent.isValid()) {
+            realParent.invalidate();
+        }
+    }
+    */
+
+    /**
+     * The Class ImageParameters.
+     */
+    private class ImageParameters {
+        
+        /** The drawing params. */
+        private final LinkedList<DrawingParameters> drawingParams = new LinkedList<DrawingParameters>();
+
+        /** The size. */
+        Dimension size = new Dimension(Component.this.w, Component.this.h);
+
+        /**
+         * Adds the drawing.
+         * 
+         * @param destLocation the dest location
+         * @param destSize the dest size
+         * @param source the source
+         */
+        void addDrawing(Point destLocation, Dimension destSize, Rectangle source) {
+            drawingParams.add(new DrawingParameters(destLocation, destSize, source));
+        }
+
+        /**
+         * Drawing parameters iterator.
+         * 
+         * @return the iterator< drawing parameters>
+         */
+        Iterator<DrawingParameters> drawingParametersIterator() {
+            return drawingParams.iterator();
+        }
+
+        /**
+         * The Class DrawingParameters.
+         */
+        class DrawingParameters {
+            
+            /** The dest location. */
+            Point destLocation;
+
+            /** The dest size. */
+            Dimension destSize;
+
+            /** The source. */
+            Rectangle source;
+
+            /**
+             * Instantiates a new drawing parameters.
+             * 
+             * @param destLocation the dest location
+             * @param destSize the dest size
+             * @param source the source
+             */
+            DrawingParameters(Point destLocation, Dimension destSize, Rectangle source) {
+                this.destLocation = new Point(destLocation);
+                if (destSize != null) {
+                    this.destSize = new Dimension(destSize);
+                } else {
+                    this.destSize = null;
+                }
+                if (source != null) {
+                    this.source = new Rectangle(source);
+                } else {
+                    this.source = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * TextComponent support.
+     * 
+     * @param e the e
+     * 
+     * @return true, if dispatch event to im
+     */
+    //???AWT
+    /*
+    private TextKit textKit = null;
+
+    TextKit getTextKit() {
+        return textKit;
+    }
+
+    void setTextKit(TextKit kit) {
+        textKit = kit;
+    }
+    */
+
+    /**
+     * TextField support
+     */
+    //???AWT
+    /*
+    private TextFieldKit textFieldKit = null;
+
+    TextFieldKit getTextFieldKit() {
+        return textFieldKit;
+    }
+
+    void setTextFieldKit(TextFieldKit kit) {
+        textFieldKit = kit;
+    }
+    */
+
+    /**
+     * Dispatches input & focus events to input method
+     * context.
+     * @param e event to pass to InputContext.dispatchEvent()
+     * @return true if event was consumed by IM, false otherwise
+     */
+    private boolean dispatchEventToIM(AWTEvent e) {
+        InputContext ic = getInputContext();
+        if (ic == null) {
+            return false;
+        }
+        int id = e.getID();
+        boolean isInputEvent = ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST))
+                || ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST));
+        if (((id >= FocusEvent.FOCUS_FIRST) && (id <= FocusEvent.FOCUS_LAST)) || isInputEvent) {
+            ic.dispatchEvent(e);
+        }
+        return e.isConsumed();
+    }
+}
diff --git a/awt/java/awt/ComponentBehavior.java b/awt/java/awt/ComponentBehavior.java
new file mode 100644
index 0000000..89c9999
--- /dev/null
+++ b/awt/java/awt/ComponentBehavior.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The interface of the helper object that encapsulates the difference
+ * between lightweight and heavyweight components. 
+ */
+interface ComponentBehavior {
+
+    void addNotify();
+
+    void setBounds(int x, int y, int w, int h, int bMask);
+
+    void setVisible(boolean b);
+
+    Graphics getGraphics(int translationX, int translationY, int width, int height);
+
+    NativeWindow getNativeWindow();
+
+    boolean isLightweight();
+
+    void onMove(int x, int y);
+
+    boolean isOpaque();
+
+    boolean isDisplayable();
+
+    void setEnabled(boolean value);
+
+    void removeNotify();
+
+    void setZOrder(int newIndex, int oldIndex);
+
+    boolean setFocus(boolean focus, Component opposite);
+}
diff --git a/awt/java/awt/ComponentOrientation.java b/awt/java/awt/ComponentOrientation.java
new file mode 100644
index 0000000..ddb118d
--- /dev/null
+++ b/awt/java/awt/ComponentOrientation.java
@@ -0,0 +1,140 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * The ComponentOrientation class specifies the language-sensitive orientation 
+ * of component's elements or text. It is used to reflect the differences in this 
+ * ordering between different writting systems. The ComponentOrientation class 
+ * indicates the orientation of the elements/text in the horizontal direction
+ * ("left to right" or "right to left") and in the vertical direction
+ * ("top to bottom" or "bottom to top").
+ */
+public final class ComponentOrientation implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4113291392143563828L;
+
+    /** 
+     * The Constant LEFT_TO_RIGHT indicates that items run left to right.
+     */
+    public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
+
+    /** 
+     * The Constant RIGHT_TO_LEFT indicates that items run right to left.
+     */
+    public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
+
+    /** The Constant UNKNOWN indicates that a component's orientation is not set. */
+    public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
+
+    /** The Constant rlLangs. */
+    private static final Set<String> rlLangs = new HashSet<String>(); //RIGHT_TO_LEFT languages
+
+    /** The horizontal. */
+    private final boolean horizontal;
+
+    /** The left2right. */
+    private final boolean left2right;
+
+    static {
+        rlLangs.add("ar"); //$NON-NLS-1$
+        rlLangs.add("fa"); //$NON-NLS-1$
+        rlLangs.add("iw"); //$NON-NLS-1$
+        rlLangs.add("ur"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the orientation for the given ResourceBundle's localization.
+     * 
+     * @param bdl the ResourceBundle.
+     * 
+     * @return the ComponentOrientation.
+     * 
+     * @deprecated Use getOrientation(java.util.Locale) method.
+     */
+    @Deprecated
+    public static ComponentOrientation getOrientation(ResourceBundle bdl) {
+        Object obj = null;
+        try {
+            obj = bdl.getObject("Orientation"); //$NON-NLS-1$
+        }
+        catch (MissingResourceException mre) {
+            obj = null;
+        }
+        if (obj instanceof ComponentOrientation) {
+            return (ComponentOrientation) obj;
+        }
+        Locale locale = bdl.getLocale();
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return getOrientation(locale);
+    }
+
+    /**
+     * Gets the orientation for the specified locale.
+     * 
+     * @param locale the specified Locale.
+     * 
+     * @return the ComponentOrientation.
+     */
+    public static ComponentOrientation getOrientation(Locale locale) {
+        String lang = locale.getLanguage();
+        return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
+    }
+
+    /**
+     * Instantiates a new component orientation.
+     * 
+     * @param hor whether the items should be arranged horizontally
+     * @param l2r whether this orientation specifies a left-to-right flow
+     */
+    private ComponentOrientation(boolean hor, boolean l2r) {
+        horizontal = hor;
+        left2right = l2r;
+    }
+
+    /**
+     * Returns true if the text of the of writing systems arranged
+     * horizontally.
+     * 
+     * @return true, if the text is written horizontally, false 
+     * for a vertical arrangement. 
+     */
+    public boolean isHorizontal() {
+        return horizontal;
+    }
+
+    /**
+     * Returns true if the text is arranged from left to right.
+     * 
+     * @return true, for writing systems written from left to right; 
+     * false for right-to-left.
+     */
+    public boolean isLeftToRight() {
+        return left2right;
+    }
+
+}
diff --git a/awt/java/awt/Composite.java b/awt/java/awt/Composite.java
new file mode 100644
index 0000000..8e5b90a
--- /dev/null
+++ b/awt/java/awt/Composite.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+
+/**
+ * The Composite interface allows the methods to compose a draw primitive 
+ * on the graphics area. The classes implementing this interface provides 
+ * the rules and a method to create the context for a particular operation.
+ */
+public interface Composite {
+
+    /**
+     * Creates a CompositeContext which defines the encapsulated and 
+     * optimized environment for a compositing operation. Several contexts 
+     * can exist for a single Composite object.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints.
+     * 
+     * @return the CompositeContext object.
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints);
+
+}
+
diff --git a/awt/java/awt/CompositeContext.java b/awt/java/awt/CompositeContext.java
new file mode 100644
index 0000000..c676032
--- /dev/null
+++ b/awt/java/awt/CompositeContext.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * The CompositeContext interface specifies the encapsulated and optimized 
+ * environment for a compositing operation. 
+ */
+public interface CompositeContext {
+
+    /**
+     * Composes the two source Raster objects and places the result in the 
+     * destination WritableRaster. 
+     * 
+     * @param src the source Raster.
+     * @param dstIn the destination Raster.
+     * @param dstOut the WritableRaster object where the result of
+     * composing operation is stored.
+     */
+    public void compose(Raster src, Raster dstIn, WritableRaster dstOut);
+
+    /**
+     * Releases resources allocated for a context.
+     */
+    public void dispose();
+
+}
+
diff --git a/awt/java/awt/Cursor.java b/awt/java/awt/Cursor.java
new file mode 100644
index 0000000..625686c
--- /dev/null
+++ b/awt/java/awt/Cursor.java
@@ -0,0 +1,372 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+/**
+ * The Cursor class represents the bitmap of the mouse cursor.
+ */
+public class Cursor implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8028237497568985504L;
+    
+    /** The Constant DEFAULT_CURSOR indicates the default cursor type. */
+    public static final int DEFAULT_CURSOR = 0;
+
+    /** The Constant CROSSHAIR_CURSOR cursor type. */
+    public static final int CROSSHAIR_CURSOR = 1;
+
+    /** The Constant TEXT_CURSOR cursor type. */
+    public static final int TEXT_CURSOR = 2;
+
+    /** The Constant WAIT_CURSOR cursor type. */
+    public static final int WAIT_CURSOR = 3;
+
+    /** The Constant SW_RESIZE_CURSOR cursor type. */
+    public static final int SW_RESIZE_CURSOR = 4;
+
+    /** The Constant SE_RESIZE_CURSOR cursor type. */
+    public static final int SE_RESIZE_CURSOR = 5;
+
+    /** The Constant NW_RESIZE_CURSOR cursor type. */
+    public static final int NW_RESIZE_CURSOR = 6;
+
+    /** The Constant NE_RESIZE_CURSOR cursor type. */
+    public static final int NE_RESIZE_CURSOR = 7;
+
+    /** The Constant N_RESIZE_CURSOR cursor type. */
+    public static final int N_RESIZE_CURSOR = 8;
+
+    /** The Constant S_RESIZE_CURSOR cursor type. */
+    public static final int S_RESIZE_CURSOR = 9;
+
+    /** The Constant W_RESIZE_CURSOR cursor type. */
+    public static final int W_RESIZE_CURSOR = 10;
+
+    /** The Constant E_RESIZE_CURSOR cursor type. */
+    public static final int E_RESIZE_CURSOR = 11;
+
+    /** The Constant HAND_CURSOR cursor type. */
+    public static final int HAND_CURSOR = 12;
+
+    /** The Constant MOVE_CURSOR cursor type. */
+    public static final int MOVE_CURSOR = 13;
+
+    /** A mapping from names to system custom cursors. */
+    static Map<String, Cursor> systemCustomCursors;
+    
+    /** The cursor props. */
+    static Properties cursorProps;
+
+    /** The Constant predefinedNames. */
+    static final String[] predefinedNames = {
+            "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
+
+    };
+
+    /** The predefined set of cursors. */
+    protected static Cursor[] predefined = {
+            new Cursor(DEFAULT_CURSOR), null, null, null,
+            null, null, null, null,
+            null, null, null, null,
+            null, null
+    };
+
+    /** The Constant CUSTOM_CURSOR is associated with all custom cursor types. 
+     * (Those which are not predefined)
+     */
+    public static final int CUSTOM_CURSOR = -1;
+
+    /** The name of the cursor. */
+    protected String name;
+
+    /** The type of the cursor, chosen from the list of cursor type constants. */
+    private final int type;
+    
+    /** The native cursor. */
+    private transient NativeCursor nativeCursor;
+    
+    /** The exact point on the cursor image that indicates which point 
+     * the cursor is selecting (pointing to). The coordinates are given 
+     * with respect the origin of the Image (its upper left corner).
+     */
+    private Point hotSpot;
+    
+    /** The image to draw on the screen representing the cursor. */
+    private Image image;
+
+    /**
+     * Instantiates a new cursor with the specified name.
+     * 
+     * @param name the name of cursor.
+     */
+    protected Cursor(String name) {
+        this(name, null, new Point());
+    }
+
+    /**
+     * Instantiates a new cursor of the specified type.
+     * 
+     * @param type the type of cursor.
+     */
+    public Cursor(int type) {
+        checkType(type);
+        this.type = type;
+        if ((type >= 0) && (type < predefinedNames.length)) {
+            name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Instantiates a new cursor.
+     * 
+     * @param name the name
+     * @param img the img
+     * @param hotSpot the hot spot
+     */
+    Cursor(String name, Image img, Point hotSpot) {
+        this.name = name;
+        type = CUSTOM_CURSOR;
+        this.hotSpot = hotSpot;
+        image = img;
+    }
+
+    /**
+     * Finalize method overrided finalize method from Object class.
+     * 
+     * @throws Throwable if the native cursor is not null and throws
+     * a throwable when destroyed.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (nativeCursor != null) {
+            nativeCursor.destroyCursor();
+        }
+    }
+
+    /**
+     * Gets the name of the cursor.
+     * 
+     * @return the name of the cursor.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the String representation of the cursor.
+     * 
+     * @return the String representation of the cursor.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the cursor type.
+     * 
+     * @return the cursor type
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the predefined cursor with the specified type.
+     * 
+     * @param type the type of cursor.
+     * 
+     * @return the predefined cursor with the specified type.
+     */
+    public static Cursor getPredefinedCursor(int type) {
+        checkType(type);
+        Cursor cursor = predefined[type];
+        if (cursor == null) {
+            cursor = new Cursor(type);
+            predefined[type] = cursor;
+        }
+        return cursor;
+    }
+
+    /**
+     * Gets the default cursor.
+     * 
+     * @return the default cursor.
+     */
+    public static Cursor getDefaultCursor() {
+        return getPredefinedCursor(DEFAULT_CURSOR);
+    }
+
+    /**
+     * Gets the specified system custom cursor.
+     * 
+     * @param name the name of the desired system cursor.
+     * 
+     * @return the specific system cursor with the specified name.
+     * 
+     * @throws AWTException if the desired cursor has malformed data
+     * such as an incorrectly defined hot spot.
+     * @throws HeadlessException if the isHeadless method of the GraphicsEnvironment
+     * returns true.
+     */
+    public static Cursor getSystemCustomCursor(String name)
+    throws AWTException, HeadlessException {
+        Toolkit.checkHeadless();
+        return getSystemCustomCursorFromMap(name);
+    }
+
+    /**
+     * Gets the specified system custom cursor from the map of system custom cursors.
+     * 
+     * @param name the name of the desired cursor.
+     * 
+     * @return the desired system custom cursor from the 
+     * map of system custom cursors.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static Cursor getSystemCustomCursorFromMap (String name)
+    throws AWTException {
+        loadCursorProps();
+        if (systemCustomCursors == null) {
+            systemCustomCursors = new HashMap<String, Cursor>();
+        }
+        Cursor cursor = systemCustomCursors.get(name);
+        if (cursor != null) {
+            return cursor;
+        }
+        // awt.141=failed to parse hotspot property for cursor:
+        String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
+        String nm = "Cursor." + name; //$NON-NLS-1$
+        String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
+        String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
+        String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
+        int idx = hotSpotStr.indexOf(',');
+        if (idx < 0) {
+            throw new AWTException(exMsg);
+        }
+        int x, y;
+        try {
+            x = new Integer(hotSpotStr.substring(0, idx)).intValue();
+            y = new Integer(hotSpotStr.substring(idx + 1,
+                                                 hotSpotStr.length())).intValue();
+        } catch (NumberFormatException nfe) {
+            throw new AWTException(exMsg);
+        }
+        Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
+        cursor = new Cursor(nameStr, img, new Point(x, y));
+        systemCustomCursors.put(name, cursor);
+
+        return cursor;
+    }
+
+    /**
+     * Load cursor props.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static void loadCursorProps() throws AWTException {
+        if (cursorProps != null) {
+            return;
+        }
+        String sep = File.separator;
+        String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
+                                cursorsDir;
+        String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
+        String cursorPropsFullFileName = (cursorsAbsDir + sep +
+                                          cursorPropsFileName);
+        cursorProps = new Properties();
+        try {
+            cursorProps.load(new FileInputStream(new File(
+                    cursorPropsFullFileName)));
+        } catch (FileNotFoundException e) {
+            // awt.142=Exception: class {0} {1} occurred while loading: {2}
+            throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
+                      new Object[]{e.getClass(), e.getMessage(), cursorPropsFullFileName}));
+        } catch (IOException e) {
+            throw new AWTException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * Check type.
+     * 
+     * @param type the type
+     */
+    static void checkType(int type) {
+        // can't use predefined array here because it may not have been
+        // initialized yet
+        if ((type < 0) || (type >= predefinedNames.length)) {
+            // awt.143=illegal cursor type
+            throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
+        }
+    }
+
+    // "lazily" create native cursors:
+    /**
+     * Gets the native cursor.
+     * 
+     * @return the native cursor
+     */
+    NativeCursor getNativeCursor() {
+        if (nativeCursor != null) {
+            return nativeCursor;
+        }
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        if (type != CUSTOM_CURSOR) {
+            nativeCursor = toolkit.createNativeCursor(type);
+        } else {
+            nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot,
+                                                            name);
+        }
+        return nativeCursor;
+    }
+
+    /**
+     * Sets the native cursor.
+     * 
+     * @param nativeCursor the new native cursor
+     */
+    void setNativeCursor(NativeCursor nativeCursor) {
+        this.nativeCursor = nativeCursor;
+    }
+}
+
diff --git a/awt/java/awt/Dimension.java b/awt/java/awt/Dimension.java
new file mode 100644
index 0000000..8137846
--- /dev/null
+++ b/awt/java/awt/Dimension.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Dimension2D;
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Dimension represents the size (width and height) of a component.
+ * The width and height values can be negative, but in that case the 
+ * behavior of some methods is unexpected. 
+ */
+public class Dimension extends Dimension2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 4723952579491349524L;
+
+    /** The width dimension. */
+    public int width;
+    
+    /** The height dimension. */
+    public int height;
+
+    /**
+     * Instantiates a new Dimension with the same data as the specified Dimension.
+     * 
+     * @param d the Dimension to copy the data from when creating the 
+     * new Dimension object.
+     */
+    public Dimension(Dimension d) {
+        this(d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new Dimension with zero width and height.
+     */
+    public Dimension() {
+        this(0, 0);
+    }
+
+    /**
+     * Instantiates a new Dimension with the specified width and height.
+     * 
+     * @param width the width of the new Dimension.
+     * @param height the height of the new Dimension.
+     */
+    public Dimension(int width, int height) {
+        setSize(width, height);
+    }
+
+    /**
+     * Returns the hash code of the Dimension.
+     * 
+     * @return the hash code of the Dimension.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(height);
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this Dimension object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Dimension with 
+     * the same width and height data as this Dimension. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Dimension) {
+            Dimension d = (Dimension)obj;
+            return (d.width == width && d.height == height);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the String associated to this Dimension object.
+     * 
+     * @return the String associated to this Dimension object.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Dimension().toString())
+        return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified width and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of this Dimension object by copying the 
+     * data from the specified Dimension object.
+     * 
+     * @param d the Dimension that gives the new size values.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified double width 
+     * and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#setSize(double, double)
+     */
+    @Override
+    public void setSize(double width, double height) {
+        setSize((int)Math.ceil(width), (int)Math.ceil(height));
+    }
+
+    /**
+     * Gets the size of the Dimension.
+     * 
+     * @return the size of the Dimension.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Gets the height of the Dimension.
+     * 
+     * @return the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the Dimension.
+     * 
+     * @return the width of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+}
+
diff --git a/awt/java/awt/Dispatcher.java b/awt/java/awt/Dispatcher.java
new file mode 100644
index 0000000..d457af4
--- /dev/null
+++ b/awt/java/awt/Dispatcher.java
@@ -0,0 +1,723 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+/**
+ * Helper package-private class for managing lightweight components &
+ * dispatching events from heavyweight source
+ */
+class Dispatcher {
+
+    //???AWT: final PopupDispatcher popupDispatcher = new PopupDispatcher();
+
+    //???AWT: final FocusDispatcher focusDispatcher;
+
+    final MouseGrabManager mouseGrabManager = new MouseGrabManager();
+
+    final MouseDispatcher mouseDispatcher;
+
+    private final ComponentDispatcher componentDispatcher = new ComponentDispatcher();
+
+    private final KeyDispatcher keyDispatcher = new KeyDispatcher();
+
+    private final Toolkit toolkit;
+
+    int clickInterval = 250;
+
+    /**
+     * @param toolkit - AWT toolkit
+     */
+    Dispatcher(Toolkit toolkit) {
+        this.toolkit = toolkit;
+
+        //???AWT: focusDispatcher = new FocusDispatcher(toolkit);
+        mouseDispatcher = new MouseDispatcher(mouseGrabManager, toolkit);
+    }
+
+    /**
+     * Dispatch native event: produce appropriate AWT events, 
+     * update component's fields when needed
+     * @param event - native event to dispatch
+     * @return - true means default processing by OS is not needed
+     */
+    public boolean onEvent(NativeEvent event) {
+        int eventId = event.getEventId();
+
+        if (eventId == NativeEvent.ID_CREATED) {
+            return toolkit.onWindowCreated(event.getWindowId());
+        } else if (eventId == NativeEvent.ID_MOUSE_GRAB_CANCELED) {
+            return mouseGrabManager.onGrabCanceled();
+        //???AWT
+//        } else if (popupDispatcher.onEvent(event)) {
+//            return false;
+        } else {
+            Component src = toolkit.getComponentById(event.getWindowId());
+
+            if (src != null) {
+                if (((eventId >= ComponentEvent.COMPONENT_FIRST) && (eventId <= ComponentEvent.COMPONENT_LAST))
+                        || ((eventId >= WindowEvent.WINDOW_FIRST) && (eventId <= WindowEvent.WINDOW_LAST))
+                        || (eventId == NativeEvent.ID_INSETS_CHANGED)
+                        || (eventId == NativeEvent.ID_BOUNDS_CHANGED)
+                        || (eventId == NativeEvent.ID_THEME_CHANGED)) {
+                    return componentDispatcher.dispatch(src, event);
+                } else if ((eventId >= MouseEvent.MOUSE_FIRST)
+                        && (eventId <= MouseEvent.MOUSE_LAST)) {
+                    return mouseDispatcher.dispatch(src, event);
+                } else if (eventId == PaintEvent.PAINT) {
+                    //???AWT: src.redrawManager.addPaintRegion(src, event.getClipRects());
+                    return true;
+                }
+            }
+            if ((eventId >= FocusEvent.FOCUS_FIRST)
+                    && (eventId <= FocusEvent.FOCUS_LAST)) {
+
+                //???AWT: return focusDispatcher.dispatch(src, event);
+                return false;
+            } else if ((eventId >= KeyEvent.KEY_FIRST)
+                    && (eventId <= KeyEvent.KEY_LAST)) {
+                return keyDispatcher.dispatch(src, event);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * The dispatcher of native events that affect 
+     * component's state or bounds
+     */
+    final class ComponentDispatcher {
+
+        /**
+         * Handle native event that affects component's state or bounds
+         * @param src - the component updated by the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+
+            if ((id == NativeEvent.ID_INSETS_CHANGED)
+                    || (id == NativeEvent.ID_THEME_CHANGED)) {
+                return dispatchInsets(event, src);
+            } else if ((id >= WindowEvent.WINDOW_FIRST)
+                    && (id <= WindowEvent.WINDOW_LAST)) {
+                return dispatchWindow(event, src);
+            } else {
+                return dispatchPureComponent(event, src);
+            }
+        }
+
+        /**
+         * Handle the change of top-level window's native decorations 
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchInsets(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            if (src instanceof Window) {
+                ((Window) src).setNativeInsets(event.getInsets());
+            }
+            */
+            return false;
+        }
+
+        /**
+         * Handle the change of top-level window's state
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchWindow(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            Window window = (Window) src;
+            int id = event.getEventId();
+
+            if (id == WindowEvent.WINDOW_CLOSING) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                          new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
+
+                return true;
+            } else if (id == WindowEvent.WINDOW_STATE_CHANGED) {
+                if (window instanceof Frame) {
+                    ((Frame) window)
+                            .updateExtendedState(event.getWindowState());
+                }
+            }
+            */
+
+            return false;
+        }
+
+        /**
+         * Handle the change of component's size and/or position
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        private boolean dispatchPureComponent(NativeEvent event, Component src) {
+            Rectangle rect = event.getWindowRect();
+            Point loc = rect.getLocation();
+            int mask;
+
+            switch (event.getEventId()) {
+            case NativeEvent.ID_BOUNDS_CHANGED:
+                mask = 0;
+                break;
+            case ComponentEvent.COMPONENT_MOVED:
+                mask = NativeWindow.BOUNDS_NOSIZE;
+                break;
+            case ComponentEvent.COMPONENT_RESIZED:
+                mask = NativeWindow.BOUNDS_NOMOVE;
+                break;
+            default:
+                // awt.12E=Unknown component event id.
+                throw new RuntimeException(Messages.getString("awt.12E")); //$NON-NLS-1$
+            }
+
+            //???AWT
+            /*
+            if (!(src instanceof Window)) {
+                Component compTo = src.getParent();
+                Component compFrom = src.getHWAncestor();
+
+                if ((compTo != null) && (compFrom != null)) {
+                    loc = MouseDispatcher.convertPoint(compFrom, loc, compTo);
+                }
+            } else {
+                int windowState = event.getWindowState();
+
+                if ((windowState >= 0) && (src instanceof Frame)) {
+                    ((Frame) src).updateExtendedState(windowState);
+                }
+            }
+            src.setBounds(loc.x, loc.y, rect.width, rect.height, mask, false);
+            */
+            
+            return false;
+        }
+
+    }
+
+    /**
+     * The dispatcher of the keyboard events
+     */
+    final class KeyDispatcher {
+
+        /**
+         * Handle the keyboard event using the KeyboardFocusManager
+         * @param src - the component receiving the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+            int modifiers = event.getInputModifiers();
+            int location = event.getKeyLocation();
+            int code = event.getVKey();
+            StringBuffer chars = event.getKeyChars();
+            int charsLength = chars.length();
+            long time = event.getTime();
+            char keyChar = event.getLastChar();
+
+            //???AWT
+            /*
+            if (src == null) {
+                //retarget focus proxy key events to focusOwner:
+                Window focusProxyOwner = toolkit.getFocusProxyOwnerById(event
+                        .getWindowId());
+                if (focusProxyOwner == null) {
+                    return false;
+                }
+                src = KeyboardFocusManager.actualFocusOwner;
+            }
+            */
+
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+            
+            if (src != null) {
+                eventQueue.postEvent(new KeyEvent(src, id, time, modifiers,
+                        code, keyChar, location));
+                // KEY_TYPED goes after KEY_PRESSED
+                if (id == KeyEvent.KEY_PRESSED) {
+                    for (int i = 0; i < charsLength; i++) {
+                        keyChar = chars.charAt(i);
+                        if (keyChar != KeyEvent.CHAR_UNDEFINED) {
+                            eventQueue.postEvent(new KeyEvent(src,
+                                    KeyEvent.KEY_TYPED, time, modifiers,
+                                    KeyEvent.VK_UNDEFINED, keyChar,
+                                    KeyEvent.KEY_LOCATION_UNKNOWN));
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+    }
+
+    /**
+     * Retargets the mouse events to the grab owner when mouse is grabbed,
+     * grab and ungrab mouse when mouse buttons are pressed and released
+     */
+
+    static final class MouseGrabManager {
+
+        /** 
+         * The top-level window holding the mouse grab 
+         * that was explicitly started by startGrab() method
+         */
+        //???AWT: private Window nativeGrabOwner = null;
+        /** 
+         * The component that owns the synthetic 
+         * mouse grab while at least one of the
+         * mouse buttons is pressed
+         */
+        private Component syntheticGrabOwner = null;
+
+        /**
+         * Previous value of syntheticGrabOwner
+         */
+        private Component lastSyntheticGrabOwner = null;
+
+        /**
+         * Number of mouse buttons currently pressed
+         */
+        private int syntheticGrabDepth = 0;
+
+        /**
+         * The callback to be called when the explicit mouse grab ends
+         */
+        private Runnable whenCanceled;
+
+        /**
+         * Explicitly start the mouse grab
+         * @param grabWindow - the window that will own the grab
+         * @param whenCanceled - the callback to call when the grab ends. 
+         * This parameter can be null
+         */
+        //???AWT
+        /*
+        void startGrab(Window grabWindow, Runnable whenCanceled) {
+
+            if (nativeGrabOwner != null) {
+                // awt.12F=Attempt to start nested mouse grab
+                throw new RuntimeException(Messages.getString("awt.12F")); //$NON-NLS-1$
+            }
+
+            NativeWindow win = grabWindow.getNativeWindow();
+            if (win == null) {
+                // awt.130=Attempt to grab mouse in not displayable window
+                throw new RuntimeException(Messages.getString("awt.130")); //$NON-NLS-1$
+            }
+
+            nativeGrabOwner = grabWindow;
+            this.whenCanceled = whenCanceled;
+            win.grabMouse();
+        }
+        */
+
+        /**
+         * Ends the explicit mouse grab. If the non-null callback was provided
+         * in the startGrab() method, this callback is called 
+         */
+        void endGrab() {
+            //???AWT
+            /*
+            if (nativeGrabOwner == null) {
+                return;
+            }
+
+            Window grabWindow = nativeGrabOwner;
+            nativeGrabOwner = null;
+            NativeWindow win = grabWindow.getNativeWindow();
+
+            if (win != null) {
+                win.ungrabMouse();
+                if (whenCanceled != null) {
+                    whenCanceled.run();
+                    whenCanceled = null;
+                }
+            }
+            */
+        }
+
+        /**
+         * Ends both explicit and synthetic grans 
+         * @return - always returns false
+         */
+        boolean onGrabCanceled() {
+            endGrab();
+            resetSyntheticGrab();
+
+            return false;
+        }
+
+        /**
+         * Starts the synthetic mouse grab, increases the counter 
+         * of currently pressed mouse buttons
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab
+         */
+        Component onMousePressed(Component source) {
+            if (syntheticGrabDepth == 0) {
+                syntheticGrabOwner = source;
+                lastSyntheticGrabOwner = source;
+            }
+            syntheticGrabDepth++;
+
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * Decreases the counter of currently pressed mouse buttons,
+         * ends the synthetic mouse grab, when this counter becomes zero
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab, 
+         * or source parameter if mouse grab was released
+         */
+        Component onMouseReleased(Component source) {
+            Component ret = source;
+
+            //???AWT
+            /*
+            if (syntheticGrabOwner != null && nativeGrabOwner == null) {
+                ret = syntheticGrabOwner;
+            }
+            */
+            syntheticGrabDepth--;
+            if (syntheticGrabDepth <= 0) {
+                resetSyntheticGrab();
+                lastSyntheticGrabOwner = null;
+            }
+
+            return ret;
+        }
+
+        /**
+         * Update the state of synthetic ouse gram 
+         * when the mouse is moved/dragged
+         * @param event - the native event
+         */
+        void preprocessEvent(NativeEvent event) {
+            int id = event.getEventId();
+            switch (id) {
+            case MouseEvent.MOUSE_MOVED:
+                if (syntheticGrabOwner != null) {
+                    syntheticGrabOwner = null;
+                    syntheticGrabDepth = 0;
+                }
+                if (lastSyntheticGrabOwner != null) {
+                    lastSyntheticGrabOwner = null;
+                }
+            case MouseEvent.MOUSE_DRAGGED:
+                if (syntheticGrabOwner == null
+                        && lastSyntheticGrabOwner != null) {
+                    syntheticGrabOwner = lastSyntheticGrabOwner;
+                    syntheticGrabDepth = 0;
+                    int mask = event.getInputModifiers();
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON1_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON2_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON3_DOWN_MASK) != 0 ? 1
+                            : 0;
+                }
+            }
+        }
+
+        /**
+         * @return the component that currently owns the synthetic grab 
+         */
+        Component getSyntheticGrabOwner() {
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * ends synthetic grab
+         */
+        private void resetSyntheticGrab() {
+            syntheticGrabOwner = null;
+            syntheticGrabDepth = 0;
+        }
+
+    }
+    
+    /**
+     * Dispatches native events related to the pop-up boxes 
+     * (the non-component windows such as menus and drop lists)
+     */
+//    final class PopupDispatcher {
+//
+//        private PopupBox activePopup;
+//
+//        private PopupBox underCursor;
+//
+//        private final MouseGrab grab = new MouseGrab();
+//
+//        /**
+//         * Handles the mouse grab for pop-up boxes
+//         */
+//        private final class MouseGrab {
+//            private int depth;
+//
+//            private PopupBox owner;
+//
+//            private final Point start = new Point();
+//
+//            /**
+//             * Starts the grab when mouse is pressed
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner
+//             */
+//            PopupBox mousePressed(PopupBox src, Point where) {
+//                if (depth == 0) {
+//                    owner = src;
+//                    start.setLocation(where);
+//                }
+//                depth++;
+//                return owner;
+//            }
+//
+//            /**
+//             * Ends the grab when all mousebuttons are released
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner, or src parameter if the grab has ended
+//             */
+//            PopupBox mouseReleased(PopupBox src, Point where) {
+//                PopupBox ret = (owner != null) ? owner : src;
+//                if (depth == 0) {
+//                    return ret;
+//                }
+//                depth--;
+//                if (depth == 0) {
+//                    PopupBox tgt = owner;
+//                    owner = null;
+//                    if (tgt != null && src == null) {
+//                        Point a = new Point(start);
+//                        Point b = new Point(where);
+//                        Point pos = tgt.getScreenLocation();
+//                        a.translate(-pos.x, -pos.y);
+//                        b.translate(-pos.x, -pos.y);
+//                        if (tgt.closeOnUngrab(a, b)) {
+//                            return null;
+//                        }
+//                    }
+//                }
+//                return ret;
+//            }
+//
+//            /**
+//             * Set the grab owner to null
+//             */
+//            void reset() {
+//                depth = 0;
+//                owner = null;
+//                start.setLocation(0, 0);
+//            }
+//
+//            /**
+//             * @return - the pop-up box currently owning the grab
+//             */
+//            public PopupBox getOwner() {
+//                return owner;
+//            }
+//        }
+//
+//        /**
+//         * Call the mouse event handler of the pop-up box
+//         * @param src - the pop-up box where the mouse event occured
+//         * @param eventId - the event ID, one of MouseEvent.MOUSE_* constants
+//         * @param where - the mouse pointer location
+//         * @param event - native event
+//         */
+//        private void mouseEvent(PopupBox src, int eventId, Point where,
+//                NativeEvent event) {
+//            Point pos = src.getScreenLocation();
+//            pos.setLocation(where.x - pos.x, where.y - pos.y);
+//
+//            src.onMouseEvent(eventId, pos, event.getMouseButton(), event
+//                    .getTime(), event.getInputModifiers(), event
+//                    .getWheelRotation());
+//        }
+//
+//        /**
+//         * Handle the native event targeted by a pop-up box. This could be 
+//         * paint event, mouse or keyboard event.
+//         * @param event - the native event
+//         * @return - false if the event was handled and doesn't 
+//         * need the further processing; true when the further 
+//         * processing is needed
+//         */
+//        boolean onEvent(NativeEvent event) {
+//            PopupBox src = toolkit.getPopupBoxById(event.getWindowId());
+//            int id = event.getEventId();
+//
+//            if ((id == PaintEvent.PAINT)) {
+//                if (src != null) {
+//                    src.paint(event.getClipRects());
+//                    return true;
+//                }
+//                Component c = toolkit.getComponentById(event.getWindowId());
+//                if ((c != null) && (c instanceof Frame)) {
+//                    ((Frame) c).paintMenuBar(event.getClipRects());
+//                }
+//                return false;
+//            }
+//
+//            if ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST)) {
+//                Point where = event.getScreenPos();
+//
+//                if (src != underCursor) {
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_EXITED, where,
+//                                event);
+//                    }
+//                    underCursor = src;
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_ENTERED,
+//                                where, event);
+//                        underCursor.setDefaultCursor();
+//                    }
+//                }
+//                if (id == MouseEvent.MOUSE_EXITED) {
+//                    underCursor = null;
+//                }
+//
+//                if ((activePopup == null) && (src == null || !src.isMenuBar())) {
+//                    return false;
+//                }
+//
+//                if (id == MouseEvent.MOUSE_PRESSED) {
+//                    src = grab.mousePressed(src, where);
+//                } else if (id == MouseEvent.MOUSE_RELEASED) {
+//                    src = grab.mouseReleased(src, where);
+//                } else if (src == null) {
+//                    src = grab.getOwner();
+//                }
+//
+//                PopupBox wasActive = activePopup;
+//
+//                if (src != null) {
+//                    mouseEvent(src, id, where, event);
+//                    return src.isMenu() || src.contains(where);
+//                }
+//
+//                if (wasActive != null && activePopup == null) {
+//                    return wasActive.isMenu();
+//                }
+//
+//                if ((id == MouseEvent.MOUSE_PRESSED)
+//                        || (id == MouseEvent.MOUSE_RELEASED)) {
+//                    boolean isMenu = activePopup.isMenu();
+//                    deactivateAll();
+//                    return !isMenu;
+//                }
+//                return true;
+//            }
+//
+//            if (activePopup == null) {
+//                return false;
+//            }
+//
+//            if ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST)) {
+//                boolean isMenu = activePopup.isMenu();
+//                activePopup.dispatchKeyEvent(id, event.getVKey(), event
+//                        .getTime(), event.getInputModifiers());
+//
+//                return isMenu;
+//            }
+//
+//            return false;
+//        }
+//
+//        /**
+//         * Remember the pop-up as active and grab the mouse on it
+//         * @param popup - the pop-up box to activate
+//         */
+//        void activate(final PopupBox popup) {
+//            if (activePopup == null) {
+//
+//                activePopup = popup;
+//                mouseGrabManager.startGrab(popup.getOwner(), new Runnable() {
+//                    public void run() {
+//                        deactivate(popup);
+//                    }
+//                });
+//            }
+//        }
+//
+//        /**
+//         * Deactivate the currently active pop-up box
+//         */
+//        void deactivateAll() {
+//            deactivate(activePopup);
+//        }
+//
+//        /**
+//         * Deactivate the pop-up box, end the mouse grab
+//         */
+//        void deactivate(PopupBox popup) {
+//            grab.reset();
+//
+//            if (activePopup != null && activePopup == popup) {
+//                activePopup = null;
+//                mouseGrabManager.endGrab();
+//                popup.hide();
+//                underCursor = null;
+//            }
+//        }
+//
+//        /**
+//         * Check that the pop-up box is currently active
+//         * @param popup - the pop-up box to check
+//         * @return - true if active
+//         */
+//        boolean isActive(PopupBox popup) {
+//            return (popup == activePopup) && (popup != null);
+//        }
+//    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/DisplayMode.java b/awt/java/awt/DisplayMode.java
new file mode 100644
index 0000000..082c7b8
--- /dev/null
+++ b/awt/java/awt/DisplayMode.java
@@ -0,0 +1,147 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The DisplayMode class containes the bit depth, height, width and 
+ * refresh rate of a GraphicsDevice.
+ */
+public final class DisplayMode {
+    
+    /** The width. */
+    private final int width;
+
+    /** The height. */
+    private final int height;
+
+    /** The bit depth. */
+    private final int bitDepth;
+
+    /** The refresh rate. */
+    private final int refreshRate;
+
+   /** The Constant Value BIT_DEPTH_MULTI indicates the bit depth */
+
+    public static final int BIT_DEPTH_MULTI = -1;
+
+    /** The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate. */
+    public static final int REFRESH_RATE_UNKNOWN = 0;
+
+   /**
+    * Creates a new DisplayMode object with the specified parameters.
+    *  
+    * @param width the width of the display.
+    * @param height the height of the display.
+    * @param bitDepth the bit depth of the display.
+    * @param refreshRate the refresh rate of the display.
+    */
+
+    public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
+        this.width = width;
+        this.height = height;
+        this.bitDepth = bitDepth;
+        this.refreshRate = refreshRate;
+    }
+
+
+   /**
+    * Compares if this DisplayMode is equal to the specified object or not.
+    * 
+    * @param dm the Object to be compared.
+    * 
+    * @return true, if the specified object is a DisplayMode with the same
+    * data values as this DisplayMode, false otherwise.
+    */
+
+    @Override
+    public boolean equals(Object dm) {
+        if (dm instanceof DisplayMode) {
+            return equals((DisplayMode)dm);
+        }
+        return false;
+    }
+
+    /**
+    * Compares if this DisplayMode is equal to the specified DisplayMode object
+    * or not.
+    * 
+    * @param dm the DisplayMode to be compared.
+    * 
+    * @return true, if all of the data values of this DisplayMode are equal 
+    * to the values of the specified DisplayMode object, false otherwise.
+     */
+    public boolean equals(DisplayMode dm) {
+        if (dm == null) {
+            return false;
+        }
+        if (dm.bitDepth != bitDepth) {
+            return false;
+        }
+        if (dm.refreshRate != refreshRate) {
+            return false;
+        }
+        if (dm.width != width) {
+            return false;
+        }
+        if (dm.height != height) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value
+     * if multiple bit depths are supported in this display mode.
+     * 
+     * @return the bit depth of the DisplayMode.
+     */
+    public int getBitDepth() {
+        return bitDepth;
+    }
+
+    /**
+     * Gets the height of the DisplayMode.
+     * 
+     * @return the height of the DisplayMode.
+     */
+    public int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
+     * value if the information is not available.
+     * 
+     * @return the refresh rate of the DisplayMode.
+     */
+    public int getRefreshRate() {
+        return refreshRate;
+    }
+
+    /**
+     * Gets the width of the DisplayMode.
+     * 
+     * @return the width of the DisplayMode.
+     */
+    public int getWidth() {
+        return width;
+    }
+}
diff --git a/awt/java/awt/Event.java b/awt/java/awt/Event.java
new file mode 100644
index 0000000..f074258
--- /dev/null
+++ b/awt/java/awt/Event.java
@@ -0,0 +1,479 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * The Event Class is obsolete and has been replaced by AWTEvent class.
+ * 
+ */
+public class Event implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5488922509400504703L;
+    
+    /** 
+     * The Constant SHIFT_MASK indicates that the Shift key is down when 
+     * the event occurred.
+     */
+    public static final int SHIFT_MASK = 1;
+
+    /** 
+     * The Constant CTRL_MASK indicates that the Control key is down when 
+     * the event occurred.
+     */
+    public static final int CTRL_MASK = 2;
+
+    /** The Constant META_MASK indicates that the Meta key is down when t
+     * he event occurred (or the right mouse button). */
+    public static final int META_MASK = 4;
+
+    /** 
+     * The Constant ALT_MASK indicates that the Alt key is down when 
+     * the event occurred (or the middle mouse button). 
+     */
+    public static final int ALT_MASK = 8;
+
+    /** The Constant HOME indicates Home key. */
+    public static final int HOME = 1000;
+
+    /** The Constant END indicates End key. */
+    public static final int END = 1001;
+
+    /** The Constant PGUP indicates Page Up key. */
+    public static final int PGUP = 1002;
+
+    /** The Constant PGDN indicates Page Down key. */
+    public static final int PGDN = 1003;
+
+    /** The Constant UP indicates Up key. */
+    public static final int UP = 1004;
+
+    /** The Constant DOWN indicates Down key. */
+    public static final int DOWN = 1005;
+
+    /** The Constant LEFT indicates Left key. */
+    public static final int LEFT = 1006;
+
+    /** The Constant RIGHT indicates Right key. */
+    public static final int RIGHT = 1007;
+
+    /** The Constant F1 indicates F1 key. */
+    public static final int F1 = 1008;
+
+    /** The Constant F2 indicates F2 key. */
+    public static final int F2 = 1009;
+
+    /** The Constant F3 indicates F3 key. */
+    public static final int F3 = 1010;
+
+    /** The Constant F4 indicates F4 key. */
+    public static final int F4 = 1011;
+
+    /** The Constant F5 indicates F5 key. */
+    public static final int F5 = 1012;
+
+    /** The Constant F6 indicates F6 key. */
+    public static final int F6 = 1013;
+
+    /** The Constant F7 indicates F7 key. */
+    public static final int F7 = 1014;
+
+    /** The Constant F8 indicates F8 key. */
+    public static final int F8 = 1015;
+
+    /** The Constant F9 indicates F9 key. */
+    public static final int F9 = 1016;
+
+    /** The Constant F10 indicates F10 key. */
+    public static final int F10 = 1017;
+
+    /** The Constant F11 indicates F11 key. */
+    public static final int F11 = 1018;
+
+    /** The Constant F12 indicates F12 key. */
+    public static final int F12 = 1019;
+
+    /** The Constant PRINT_SCREEN  indicates Print Screen key. */
+    public static final int PRINT_SCREEN = 1020;
+
+    /** The Constant SCROLL_LOCK indicates Scroll Lock key. */
+    public static final int SCROLL_LOCK = 1021;
+
+    /** The Constant CAPS_LOCK indicates Caps Lock key. */
+    public static final int CAPS_LOCK = 1022;
+
+    /** The Constant NUM_LOCK indicates Num Lock key. */
+    public static final int NUM_LOCK = 1023;
+
+    /** The Constant PAUSE indicates Pause key. */
+    public static final int PAUSE = 1024;
+
+    /** The Constant INSERT indicates Insert key. */
+    public static final int INSERT = 1025;
+
+    /** The Constant ENTER indicates Enter key. */
+    public static final int ENTER = 10;
+
+    /** The Constant BACK_SPACE indicates Back Space key. */
+    public static final int BACK_SPACE = 8;
+
+    /** The Constant TAB indicates TAb key. */
+    public static final int TAB = 9;
+
+    /** The Constant ESCAPE indicates Escape key. */
+    public static final int ESCAPE = 27;
+
+    /** The Constant DELETE indicates Delete key. */
+    public static final int DELETE = 127;
+
+    /** 
+     * The Constant WINDOW_DESTROY indicates an event when the user has asked the
+     * window manager to kill the window.
+     */
+    public static final int WINDOW_DESTROY = 201;
+
+    /** 
+     * The Constant WINDOW_EXPOSE indicates an event when the user has asked the
+     * window manager to expose the window.
+     */
+    public static final int WINDOW_EXPOSE = 202;
+
+    /** 
+     * The Constant WINDOW_ICONIFY indicates an event when the user has asked the
+     * window manager to inconify the window.
+     */
+    public static final int WINDOW_ICONIFY = 203;
+
+    /** 
+     * The Constant WINDOW_DEICONIFY indicates an event when the user has asked the
+     * window manager to deinconify the window. 
+     */
+    public static final int WINDOW_DEICONIFY = 204;
+
+    /** 
+     * The Constant WINDOW_MOVED indicates an event when the user has asked the
+     * window manager to move the window. 
+     */
+    public static final int WINDOW_MOVED = 205;
+
+    /** 
+     * The Constant KEY_PRESS indicates an event when the user presses 
+     * a normal key. 
+     */
+    public static final int KEY_PRESS = 401;
+
+    /** 
+     * The Constant KEY_RELEASE indicates an event when the user releases 
+     * a normal key.
+     */
+    public static final int KEY_RELEASE = 402;
+
+    /** 
+     * The Constant KEY_ACTION indicates an event when the user pressed 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION = 403;
+
+    /**
+     * The Constant KEY_ACTION_RELEASE indicates an event when the user released 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION_RELEASE = 404;
+
+    /** 
+     * The Constant MOUSE_DOWN indicates an event when the user has pressed 
+     * the mouse button. 
+     */
+    public static final int MOUSE_DOWN = 501;
+
+    /** 
+     * The Constant MOUSE_UP indicates an event when the user has released 
+     * the mouse button. 
+     */
+    public static final int MOUSE_UP = 502;
+
+    /** 
+     * The Constant MOUSE_MOVE indicates an event when the user has moved
+     * the mouse with no button pressed.
+     */
+    public static final int MOUSE_MOVE = 503;
+
+    /** 
+     * The Constant MOUSE_ENTER indicates an event when the mouse
+     * has entered a component.
+     */
+    public static final int MOUSE_ENTER = 504;
+
+    /** 
+     * The Constant MOUSE_EXIT indicates an event when the mouse
+     * has exited a component. 
+     */
+    public static final int MOUSE_EXIT = 505;
+
+    /** The Constant MOUSE_DRAG indicates an event when the user
+     * has moved a mouse with the pressed button. 
+     */
+    public static final int MOUSE_DRAG = 506;
+
+    /** 
+     * The Constant SCROLL_LINE_UP indicates an event when the user has
+     * activated line-up area of scrollbar.
+     */
+    public static final int SCROLL_LINE_UP = 601;
+
+    /**
+     * The Constant SCROLL_LINE_DOWN indicates an event when the user has
+     * activated line-down area of scrollbar. 
+     */
+    public static final int SCROLL_LINE_DOWN = 602;
+
+    /**
+     * The Constant SCROLL_PAGE_UP indicates an event when the user has
+     * activated page up area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_UP = 603;
+
+    /**
+     * The Constant SCROLL_PAGE_DOWN indicates an event when the user has
+     * activated page down area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_DOWN = 604;
+
+    /**
+     * The Constant SCROLL_ABSOLUTE indicates an event when the user 
+     * has moved the bubble in a scroll bar. 
+     */
+    public static final int SCROLL_ABSOLUTE = 605;
+
+    /** The Constant SCROLL_BEGIN indicates a scroll begin event. */
+    public static final int SCROLL_BEGIN = 606;
+
+    /** The Constant SCROLL_END indicates a scroll end event. */
+    public static final int SCROLL_END = 607;
+
+    /** 
+     * The Constant LIST_SELECT indicates that an item in a list 
+     * has been selected.
+     */
+    public static final int LIST_SELECT = 701;
+
+    /** 
+     * The Constant LIST_DESELECT indicates that an item in a list 
+     * has been deselected. 
+     */
+    public static final int LIST_DESELECT = 702;
+
+    /** 
+     * The Constant ACTION_EVENT indicates that the user wants some 
+     * action to occur.
+     */
+    public static final int ACTION_EVENT = 1001;
+
+    /** The Constant LOAD_FILE indicates a file loading event. */
+    public static final int LOAD_FILE = 1002;
+
+    /** The Constant SAVE_FILE indicates a file saving event. */
+    public static final int SAVE_FILE = 1003;
+
+    /** The Constant GOT_FOCUS indicates that a component got the focus. */
+    public static final int GOT_FOCUS = 1004;
+
+    /** The Constant LOST_FOCUS indicates that the component lost the focus. */
+    public static final int LOST_FOCUS = 1005;
+
+    /** The target is the component with which the event is associated. */
+    public Object target;
+
+    /** The when is timestamp when event has occured. */
+    public long when;
+
+    /** The id indicates the type of the event. */
+    public int id;
+
+    /** The x coordinate of event. */
+    public int x;
+
+    /** The y coordinate of event. */
+    public int y;
+
+    /** The key code of key event. */
+    public int key;
+
+    /** The state of the modifier keys (given by a bitmask). */
+    public int modifiers;
+
+    /** The click count indicates the number of consecutive clicks. */
+    public int clickCount;
+
+    /** The argument of the event. */
+    public Object arg;
+
+    /** The next event. */
+    public Event evt;
+
+    /**
+     * Instantiates a new event with the specified target component, 
+     * event type, and argument.
+     * 
+     * @param target the target component.
+     * @param id the event type.
+     * @param arg the argument.
+     */
+    public Event(Object target, int id, Object arg) {
+        this(target, 0l, id, 0, 0, 0, 0, arg);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument set to null.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
+        this(target, when, id, x, y, key, modifiers, null);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     * @param arg the specified argument.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg) {
+        this.target = target;
+        this.when = when;
+        this.id = id;
+        this.x = x;
+        this.y = y;
+        this.key = key;
+        this.modifiers = modifiers;
+        this.arg = arg;
+    }
+
+    /**
+     * Returns a string representation of this Event.
+     * 
+     * @return a string representation of this Event.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Event e = new Event(new Button(), 0l, Event.KEY_PRESS, 
+         *                     0, 0, Event.TAB, Event.SHIFT_MASK, "arg");
+         * System.out.println(e);
+         */
+
+        return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns a string representing the state of this Event.
+     * 
+     * @return a string representing the state of this Event.
+     */
+    protected String paramString() {
+        return "id=" + id + ",x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        (key != 0 ? ",key=" + key  + getModifiersString() : "") + //$NON-NLS-1$ //$NON-NLS-2$
+        ",target=" + target + //$NON-NLS-1$
+        (arg != null ? ",arg=" + arg : ""); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets a string representation of the modifiers.
+     * 
+     * @return a string representation of the modifiers
+     */
+    private String getModifiersString() {
+        String strMod = ""; //$NON-NLS-1$
+        if (shiftDown()) {
+            strMod += ",shift"; //$NON-NLS-1$
+        }
+        if (controlDown()) {
+            strMod += ",control"; //$NON-NLS-1$
+        }
+        if (metaDown()) {
+            strMod += ",meta"; //$NON-NLS-1$
+        }
+        return strMod;
+    }
+
+    /**
+     * Translates x and y coordinates of his event to the x+dx and x+dy 
+     * coordinates.
+     * 
+     * @param dx the dx - the distance by which the event's x coordinate
+     * is increased 
+     * @param dy the dy - the distance by which the event's y coordinate
+     * is increased 
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+    /**
+     * Checks if Control key is down or not.
+     * 
+     * @return true, if Control key is down; false otherwise.
+     */
+    public boolean controlDown() {
+        return (modifiers & CTRL_MASK) != 0;
+    }
+
+    /**
+     * Checks if Meta key is down or not.
+     * 
+     * @return true, if Meta key is down; false otherwise.
+     */
+    public boolean metaDown() {
+        return (modifiers & META_MASK) != 0;
+    }
+
+    /**
+     * Checks if Shift key is down or not.
+     * 
+     * @return true, if Shift key is down; false otherwise.
+     */
+    public boolean shiftDown() {
+        return (modifiers & SHIFT_MASK) != 0;
+    }
+
+}
+
diff --git a/awt/java/awt/EventDispatchThread.java b/awt/java/awt/EventDispatchThread.java
new file mode 100644
index 0000000..442c8a2
--- /dev/null
+++ b/awt/java/awt/EventDispatchThread.java
@@ -0,0 +1,118 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+
+class EventDispatchThread extends Thread  {
+    
+    private static final class MarkerEvent extends AWTEvent {
+        MarkerEvent(Object source, int id) {
+            super(source, id);
+        }
+    }
+
+    final Dispatcher dispatcher;
+    final Toolkit toolkit;
+    private NativeEventQueue nativeQueue;
+
+    protected volatile boolean shutdownPending = false;
+
+    /**
+     * Initialise and run the main event loop
+     */
+    @Override
+    public void run() {
+        nativeQueue = toolkit.getNativeEventQueue();
+
+        try {
+            runModalLoop(null);
+        } finally {
+            toolkit.shutdownWatchdog.forceShutdown();
+        }
+    }
+
+    void runModalLoop(ModalContext context) {
+        long lastPaintTime = System.currentTimeMillis();
+        while (!shutdownPending && (context == null || context.isModalLoopRunning())) {
+            try {
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+
+            NativeEvent ne = nativeQueue.getNextEvent();
+            if (ne != null) {
+                dispatcher.onEvent(ne);
+                MarkerEvent marker = new MarkerEvent(this, 0);
+                eventQueue.postEvent(marker);
+                for (AWTEvent ae = eventQueue.getNextEventNoWait(); 
+                        (ae != null) && (ae != marker); 
+                        ae = eventQueue.getNextEventNoWait()) {
+                    eventQueue.dispatchEvent(ae);
+                }
+            } else {
+                toolkit.shutdownWatchdog.setNativeQueueEmpty(true);
+                AWTEvent ae = eventQueue.getNextEventNoWait();
+                if (ae != null) {
+                    eventQueue.dispatchEvent(ae);
+                    long curTime = System.currentTimeMillis();
+                    if (curTime - lastPaintTime > 10) {
+                        toolkit.onQueueEmpty();
+                        lastPaintTime = System.currentTimeMillis();
+                    }
+                } else {
+                    toolkit.shutdownWatchdog.setAwtQueueEmpty(true);
+                    toolkit.onQueueEmpty();
+                    lastPaintTime = System.currentTimeMillis();
+                    waitForAnyEvent();
+                }
+            }
+            } catch (Throwable t) {
+                // TODO: Exception handler should be implemented
+                // t.printStackTrace();
+            }
+        }
+    }
+    
+    private void waitForAnyEvent() {
+        EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+        if (!eventQueue.isEmpty() || !nativeQueue.isEmpty()) {
+            return;
+        }
+        Object eventMonitor = nativeQueue.getEventMonitor();
+        synchronized(eventMonitor) {
+            try {
+                eventMonitor.wait();
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    void shutdown() {
+        shutdownPending = true;
+    }
+
+    EventDispatchThread(Toolkit toolkit, Dispatcher dispatcher ) {
+        this.toolkit = toolkit;
+        this.dispatcher = dispatcher;
+        setName("AWT-EventDispatchThread"); //$NON-NLS-1$
+        setDaemon(true);
+    }
+
+}
diff --git a/awt/java/awt/EventQueue.java b/awt/java/awt/EventQueue.java
new file mode 100644
index 0000000..3997546
--- /dev/null
+++ b/awt/java/awt/EventQueue.java
@@ -0,0 +1,310 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.InvocationEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EmptyStackException;
+
+/**
+ * The EventQueue class manages events. It is a platform-independent class 
+ * that queues events both from the underlying peer classes and from trusted 
+ * application classes.
+ */
+public class EventQueue {
+    
+    /** The core ref. */
+    private final EventQueueCoreAtomicReference coreRef = 
+            new EventQueueCoreAtomicReference();
+    
+    /**
+     * The Class EventQueueCoreAtomicReference.
+     */
+    private static final class EventQueueCoreAtomicReference {
+        
+        /** The core. */
+        private EventQueueCore core;
+
+        /*synchronized*/ /**
+         * Gets the.
+         * 
+         * @return the event queue core
+         */
+        EventQueueCore get() { 
+            return core;
+        }
+
+        /*synchronized*/ /**
+         * Sets the.
+         * 
+         * @param newCore the new core
+         */
+        void set(EventQueueCore newCore) { 
+            core = newCore;
+        }
+    }
+
+    /**
+     * Returns true if the calling thread is the current 
+     * AWT EventQueue's dispatch thread. 
+     * 
+     * @return true, if the calling thread is the current 
+     * AWT EventQueue's dispatch thread; false otherwise.
+     */
+    public static boolean isDispatchThread() {
+        return Thread.currentThread() instanceof EventDispatchThread;
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     */
+    public static void invokeLater(Runnable runnable) {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        InvocationEvent event = new InvocationEvent(toolkit, runnable);
+        toolkit.getSystemEventQueueImpl().postEvent(event);
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread and the 
+     * notifyAll method is called on it immediately after run returns.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     * 
+     * @throws InterruptedException if another thread has interrupted 
+     * this thread.
+     * @throws InvocationTargetException if a throwable is thrown 
+     * when running the runnable. 
+     */
+    public static void invokeAndWait(Runnable runnable)
+            throws InterruptedException, InvocationTargetException {
+
+        if (isDispatchThread()) {
+            throw new Error();
+        }
+
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        final Object notifier = new Object();  //$NON-LOCK-1$
+        InvocationEvent event = new InvocationEvent(
+                toolkit, runnable, notifier, true);
+
+        synchronized (notifier) {
+            toolkit.getSystemEventQueueImpl().postEvent(event);
+            notifier.wait();
+        }
+
+        Exception exception = event.getException();
+
+        if (exception != null) {
+            throw new InvocationTargetException(exception);
+        }
+    }
+
+    /**
+     * Gets the system event queue.
+     * 
+     * @return the system event queue
+     */
+    private static EventQueue getSystemEventQueue() {
+        Thread th = Thread.currentThread();
+        if (th instanceof EventDispatchThread) {
+            return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
+        }
+        return null;
+    }
+    
+    /**
+     * Gets the most recent event's timestamp.
+     * This event was dispatched from the EventQueue associated with the 
+     * calling thread.
+     * 
+     * @return the timestamp of the last Event to be dispatched, 
+     * or System.currentTimeMillis() if this method is invoked from 
+     * a thread other than an event-dispatching thread.
+     */
+    public static long getMostRecentEventTime() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
+    }
+    
+    /**
+     * Gets the most recent event time impl.
+     * 
+     * @return the most recent event time impl
+     */
+    private long getMostRecentEventTimeImpl() {
+        return getCore().getMostRecentEventTime();
+    }
+
+    /**
+     * Returns the the currently dispatched event by the EventQueue 
+     * associated with the calling thread.
+     * 
+     * @return the currently dispatched event or null if this method 
+     * is invoked from a thread other than an event-dispatching thread.
+     */
+    public static AWTEvent getCurrentEvent() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getCurrentEventImpl() : null;
+    }
+
+    /**
+     * Gets the current event impl.
+     * 
+     * @return the current event impl
+     */
+    private AWTEvent getCurrentEventImpl() {
+        return getCore().getCurrentEvent();
+    }
+
+    /**
+     * Instantiates a new event queue.
+     */
+    public EventQueue() {
+        setCore(new EventQueueCore(this));
+    }
+
+    /**
+     * Instantiates a new event queue.
+     * 
+     * @param t the t
+     */
+    EventQueue(Toolkit t) {
+        setCore(new EventQueueCore(this, t));
+    }
+
+    /**
+     * Posts a event to the EventQueue.
+     * 
+     * @param event AWTEvent.
+     */
+    public void postEvent(AWTEvent event) {
+        event.isPosted = true;
+        getCore().postEvent(event);
+    }
+
+    /**
+     * Returns an event from the EventQueue and removes it from this queue. 
+     *  
+     * @return the next AWTEvent.
+     * 
+     * @throws InterruptedException is thrown if another thread 
+     * interrupts this thread.
+     */
+    public AWTEvent getNextEvent() throws InterruptedException {
+        return getCore().getNextEvent();
+    }
+    
+    /**
+     * Gets the next event no wait.
+     * 
+     * @return the next event no wait
+     */
+    AWTEvent getNextEventNoWait() {
+        return getCore().getNextEventNoWait();
+    }
+
+    /**
+     * Returns the first event of the EventQueue (without removing it 
+     * from the queue).
+     * 
+     * @return the the first AWT event of the EventQueue.
+     */
+    public AWTEvent peekEvent() {
+        return getCore().peekEvent();
+    }
+
+    /**
+     * Returns the first event of the EventQueue with the specified ID
+     * (without removing it from the queue).
+     * 
+     * @param id the type ID of event.
+     * 
+     * @return the first event of the EventQueue with the specified ID.
+     */
+    public AWTEvent peekEvent(int id) {
+        return getCore().peekEvent(id);
+    }
+
+    /**
+     * Replaces the existing EventQueue with the specified EventQueue. 
+     * Any pending events are transferred to the new EventQueue. 
+     * 
+     * @param newEventQueue the new event queue.
+     */
+    public void push(EventQueue newEventQueue) {
+        getCore().push(newEventQueue);
+    }
+    
+    /**
+     * Stops dispatching events using this EventQueue. 
+     * Any pending events are transferred to the previous EventQueue.
+     * 
+     * @throws EmptyStackException is thrown if no previous push 
+     * was made on this EventQueue.
+     */
+    protected void pop() throws EmptyStackException {
+        getCore().pop();
+    }
+
+    /**
+     * Dispatches the specified event.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void dispatchEvent(AWTEvent event) {
+        getCore().dispatchEventImpl(event);
+    }
+
+    /**
+     * Checks if the queue is empty.
+     * 
+     * @return true, if is empty
+     */
+    boolean isEmpty() {
+        return getCore().isEmpty();
+    }
+
+    /**
+     * Gets the core.
+     * 
+     * @return the core
+     */
+    EventQueueCore getCore() {
+        return coreRef.get();
+    }
+    
+    /**
+     * Sets the core.
+     * 
+     * @param newCore the new core
+     */
+    void setCore(EventQueueCore newCore) {
+        coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
+    }
+}
diff --git a/awt/java/awt/EventQueueCore.java b/awt/java/awt/EventQueueCore.java
new file mode 100644
index 0000000..ffc7c46
--- /dev/null
+++ b/awt/java/awt/EventQueueCore.java
@@ -0,0 +1,253 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InvocationEvent;
+import java.awt.event.MouseEvent;
+import java.util.LinkedList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The events storage for EventQueue
+ */
+final class EventQueueCore {
+    
+    private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>();
+    private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>();
+    
+    private Toolkit toolkit;
+    private EventQueue activeQueue;
+    private Thread dispatchThread;
+    
+    AWTEvent currentEvent;
+    long mostRecentEventTime = System.currentTimeMillis();
+    
+    EventQueueCore(EventQueue eq) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+        }
+    }
+
+    EventQueueCore(EventQueue eq, Toolkit t) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+            setToolkit(t);
+        }
+    }
+
+    synchronized long getMostRecentEventTime() {
+        return mostRecentEventTime;
+    }
+    
+    synchronized AWTEvent getCurrentEvent() {
+        return currentEvent;
+    }
+    
+    synchronized boolean isSystemEventQueue() {
+        return toolkit != null;
+    }
+    
+    private void setToolkit(Toolkit t) {
+        toolkit = t;
+        if (toolkit != null) {
+            toolkit.setSystemEventQueueCore(this);
+            dispatchThread = toolkit.dispatchThread;
+        }
+    }
+
+    synchronized void postEvent(AWTEvent event) {
+        //???AWT
+        /*
+        events.addLast(event);
+        if ((toolkit == null) && (dispatchThread == null)) {
+            dispatchThread = new EventQueueThread(this);
+            dispatchThread.start();
+        }
+        // TODO: add event coalescing
+        if (toolkit != null) {
+            toolkit.shutdownWatchdog.setAwtQueueEmpty(false);
+            if (!GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
+                notifyEventMonitor(toolkit);
+            }
+        }
+        notifyAll();
+        */
+    }
+    
+    void notifyEventMonitor(Toolkit t) {
+        Object em = t.getNativeEventQueue().getEventMonitor();
+        synchronized (em) {
+            em.notifyAll();
+        }
+    }
+    
+    synchronized AWTEvent getNextEvent() throws InterruptedException {
+        while (events.isEmpty()) {
+            wait();
+        }
+        AWTEvent event = events.removeFirst();
+        // TODO: add event coalescing
+        return event;
+    }    
+    
+    synchronized AWTEvent peekEvent() {
+        return events.isEmpty() ? null : events.getFirst();
+    }
+    
+    synchronized AWTEvent peekEvent(int id) {
+        for (AWTEvent event : events) {
+            if (event.getID() == id) {
+                return event;
+            }
+        }
+        return null;
+    }
+    
+    synchronized void dispatchEvent(AWTEvent event) {
+        updateCurrentEventAndTime(event);
+        try {
+            activeQueue.dispatchEvent(event);
+        } finally {
+            currentEvent = null;
+        }
+    }
+    
+    void dispatchEventImpl(AWTEvent event) {
+        if (event instanceof ActiveEvent) {
+            updateCurrentEventAndTime(event);
+            try {
+                ((ActiveEvent) event).dispatch();
+            } finally {
+                currentEvent = null;
+            }
+            return;
+        }
+
+        Object src = event.getSource();
+
+        if (src instanceof Component) {
+            if (preprocessComponentEvent(event)) {
+                ((Component) src).dispatchEvent(event);
+            }
+        } else {
+            if (toolkit != null) {
+                toolkit.dispatchAWTEvent(event);
+            }
+            if (src instanceof MenuComponent) {
+                ((MenuComponent) src).dispatchEvent(event);
+            }
+        }
+    }
+
+    private final boolean preprocessComponentEvent(AWTEvent event) {
+      if (event instanceof MouseEvent) {
+          return preprocessMouseEvent((MouseEvent)event);
+      }
+      return true;
+    }
+
+    private final boolean preprocessMouseEvent(MouseEvent event) {
+        //???AWT
+        /*
+      if (toolkit != null && toolkit.mouseEventPreprocessor != null) {
+          toolkit.lockAWT();
+          try {
+              return toolkit.mouseEventPreprocessor.preprocess(event);
+          } finally {
+              toolkit.unlockAWT();
+          }
+      }
+      return true;
+        */
+        return true;
+    }
+    
+    private void updateCurrentEventAndTime(AWTEvent event) {
+        currentEvent = event;
+        long when = 0;
+        if (event instanceof ActionEvent) {
+            when = ((ActionEvent) event).getWhen();
+        } else if (event instanceof InputEvent) {
+            when = ((InputEvent) event).getWhen();
+        } else if (event instanceof InputMethodEvent) {
+            when = ((InputMethodEvent) event).getWhen();
+        } else if (event instanceof InvocationEvent) {
+            when = ((InvocationEvent) event).getWhen();
+        }
+        if (when != 0) {
+            mostRecentEventTime = when;
+        }
+    }
+    
+    synchronized void push(EventQueue newEventQueue) {
+        // TODO: handle incorrect situations
+        if (queueStack.isEmpty()) {
+            // awt.6B=Queue stack is empty
+            throw new IllegalStateException(Messages.getString("awt.6B")); //$NON-NLS-1$
+        }
+        
+        queueStack.addLast(newEventQueue);
+        activeQueue = newEventQueue;
+        activeQueue.setCore(this);
+    }
+    
+    synchronized void pop() {
+        EventQueue removed = queueStack.removeLast();
+        if (removed != activeQueue) {
+            // awt.6C=Event queue stack is broken
+            throw new IllegalStateException(Messages.getString("awt.6C")); //$NON-NLS-1$
+        }
+        activeQueue = queueStack.getLast();
+        removed.setCore(null);
+    }
+
+    synchronized AWTEvent getNextEventNoWait() {
+        try {
+            return events.isEmpty() ? null : activeQueue.getNextEvent();
+        } catch (InterruptedException e) {
+            return null;
+        }
+    }
+
+    synchronized boolean isEmpty() {
+        return (currentEvent == null) && events.isEmpty();
+    }
+    
+    synchronized boolean isEmpty(long timeout) {
+        if (!isEmpty()) {
+            return false;
+        }
+        try {
+            wait(timeout);
+        } catch (InterruptedException e) {}
+        return isEmpty();
+    }
+    
+    synchronized EventQueue getActiveEventQueue() {
+        return activeQueue;
+    }
+}
diff --git a/awt/java/awt/Font.java b/awt/java/awt/Font.java
new file mode 100644
index 0000000..139ae68
--- /dev/null
+++ b/awt/java/awt/Font.java
@@ -0,0 +1,1500 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TransformAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Font class represents fonts for rendering text. 
+ * This class allow to map characters to glyphs.
+ * <p> 
+ * A glyph is a shape used to render a character or a sequence of 
+ * characters. For example one character of Latin writing system 
+ * represented by one glyth, but in complex writing system such as 
+ * South and South-East Asian there is more complicated correspondence 
+ * between characters and glyphs.
+ * <p>
+ * The Font object is identified by two types of names. The logical font name 
+ * is the name that is used to construct the font. The font name
+ * is the name of a particular font face (for example, Arial Bold). 
+ * The family name is the font's family name that specifies 
+ * the typographic design across several faces (for example, Arial). In 
+ * all the Font is identified by three attributes: the family name, 
+ * the style (such as bold or italic), and the size.
+ */
+public class Font implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4206021311591459213L;
+
+    // Identity Transform attribute
+    /** The Constant IDENTITY_TRANSFORM. */
+    private static final TransformAttribute IDENTITY_TRANSFORM = new TransformAttribute(
+            new AffineTransform());
+
+    /** The Constant PLAIN indicates font's plain style. */
+    public static final int PLAIN = 0;
+
+    /** The Constant BOLD indicates font's bold style. */
+    public static final int BOLD = 1;
+
+    /** The Constant ITALIC indicates font's italic style. */
+    public static final int ITALIC = 2;
+
+    /** The Constant ROMAN_BASELINE indicated roman baseline. */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** The Constant CENTER_BASELINE indicates center baseline. */
+    public static final int CENTER_BASELINE = 1;
+
+    /** The Constant HANGING_BASELINE indicates hanging baseline. */
+    public static final int HANGING_BASELINE = 2;
+
+    /** 
+     * The Constant TRUETYPE_FONT indicates a font resource of 
+     * type TRUETYPE. 
+     */
+    public static final int TRUETYPE_FONT = 0;
+
+    /** 
+     * The Constant TYPE1_FONT indicates a font resource of
+     * type TYPE1. 
+     */
+    public static final int TYPE1_FONT = 1;
+
+    /** 
+     * The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is
+     * left to right. 
+     */
+    public static final int LAYOUT_LEFT_TO_RIGHT = 0;
+
+    /** 
+     * The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is
+     * right to left. 
+     */
+    public static final int LAYOUT_RIGHT_TO_LEFT = 1;
+
+    /** 
+     * The Constant LAYOUT_NO_START_CONTEXT indicates that the text
+     * in the char array before the indicated start should not be examined. 
+     */
+    public static final int LAYOUT_NO_START_CONTEXT = 2;
+
+    /** The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in 
+     * the char array after the indicated limit should not be examined. */
+    public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+
+    /** The Constant DEFAULT_FONT. */
+    static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
+
+    /** The name of the Font. */
+    protected String name;
+
+    /** The style of the Font. */
+    protected int style;
+
+    /** The size of the Font. */
+    protected int size;
+
+    /** The point size of the Font. */
+    protected float pointSize;
+
+    // Flag if the Font object transformed
+    /** The transformed. */
+    private boolean transformed;
+
+    // Set of font attributes
+    /** The requested attributes. */
+    private Hashtable<Attribute, Object> fRequestedAttributes;
+
+    // font peer object corresponding to this Font
+    /** The font peer. */
+    private transient FontPeerImpl fontPeer;
+
+    // number of glyphs in this Font
+    /** The num glyphs. */
+    private transient int numGlyphs = -1;
+
+    // code for missing glyph for this Font
+    /** The missing glyph code. */
+    private transient int missingGlyphCode = -1;
+
+    /**
+     * Writes object to ObjectOutputStream.
+     * 
+     * @param out ObjectOutputStream
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Reads object from ObjectInputStream object and set native platform
+     * dependent fields to default values.
+     * 
+     * @param in ObjectInputStream object
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException,
+            ClassNotFoundException {
+        in.defaultReadObject();
+
+        numGlyphs = -1;
+        missingGlyphCode = -1;
+
+    }
+
+    /**
+     * Instantiates a new Font with the specified attributes. 
+     * The Font will be created with default attributes 
+     * if the attribute's parameter is null. 
+     * 
+     * @param attributes the attributes to be assigned to the new Font, or null.
+     */
+    public Font(Map<? extends Attribute, ?> attributes) {
+        Object currAttr;
+
+        // Default values are taken from the documentation of the Font class.
+        // See Font constructor, decode and getFont sections.
+
+        this.name = "default"; //$NON-NLS-1$
+        this.size = 12;
+        this.pointSize = 12;
+        this.style = Font.PLAIN;
+
+        if (attributes != null) {
+
+            fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
+
+            currAttr = attributes.get(TextAttribute.SIZE);
+            if (currAttr != null) {
+                this.pointSize = ((Float) currAttr).floatValue();
+                this.size = (int) Math.ceil(this.pointSize);
+            }
+
+            currAttr = attributes.get(TextAttribute.POSTURE);
+            if (currAttr != null
+                    && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
+                this.style |= Font.ITALIC;
+            }
+
+            currAttr = attributes.get(TextAttribute.WEIGHT);
+            if ((currAttr != null)
+                    && (((Float) currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD)
+                            .floatValue())) {
+                this.style |= Font.BOLD;
+            }
+
+            currAttr = attributes.get(TextAttribute.FAMILY);
+            if (currAttr != null) {
+                this.name = (String) currAttr;
+            }
+
+            currAttr = attributes.get(TextAttribute.TRANSFORM);
+            if (currAttr != null) {
+                if (currAttr instanceof TransformAttribute) {
+                    this.transformed = !((TransformAttribute) currAttr)
+                            .getTransform().isIdentity();
+                } else if (currAttr instanceof AffineTransform) {
+                    this.transformed = !((AffineTransform) currAttr)
+                            .isIdentity();
+                }
+            }
+
+        } else {
+            fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+            fRequestedAttributes.put(TextAttribute.TRANSFORM,
+                    IDENTITY_TRANSFORM);
+
+            this.transformed = false;
+
+            fRequestedAttributes.put(TextAttribute.FAMILY, name);
+
+            fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+            if ((this.style & Font.BOLD) != 0) {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_BOLD);
+            } else {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_REGULAR);
+            }
+            if ((this.style & Font.ITALIC) != 0) {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_OBLIQUE);
+            } else {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_REGULAR);
+            }
+
+        }
+    }
+
+    /**
+     * Instantiates a new Font with the specified name, style and size.
+     * 
+     * @param name the name of font.
+     * @param style the style of font.
+     * @param size the size of font.
+     */
+    public Font(String name, int style, int size) {
+
+        this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
+        this.size = (size >= 0) ? size : 0;
+        this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
+        this.pointSize = this.size;
+
+        fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+
+        fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
+
+        this.transformed = false;
+
+        fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
+        fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+        if ((this.style & Font.BOLD) != 0) {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_REGULAR);
+        }
+        if ((this.style & Font.ITALIC) != 0) {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_REGULAR);
+        }
+    }
+
+    /**
+     * Returns true if this Font has a glyph for the specified character.
+     * 
+     * @param c the character.
+     * 
+     * @return true if this Font has a glyph for the specified character,
+     * false otherwise.
+     */
+    public boolean canDisplay(char c) {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.canDisplay(c);
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified text from the specified start position 
+     * to the specified limit position. 
+     * 
+     * @param text the text.
+     * @param start the start offset (in the character array).
+     * @param limit the limit offset (in the character array).
+     * 
+     * @return the a character's position in the text that this Font 
+     * can not display, or -1 if this Font can display all characters 
+     * in this text.
+     */
+    public int canDisplayUpTo(char[] text, int start, int limit) {
+        int st = start;
+        int result;
+        while ((st < limit) && canDisplay(text[st])) {
+            st++;
+        }
+
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified CharacterIterator from the specified start position 
+     * and the specified limit position. 
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param limit the limit offset.
+     * 
+     * @return the a character's position in the CharacterIterator
+     * that this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+        int st = start;
+        char c = iter.setIndex(start);
+        int result;
+
+        while ((st < limit) && (canDisplay(c))) {
+            st++;
+            c = iter.next();
+        }
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if this Font can display a specified String.
+     * 
+     * @param str the String.
+     * 
+     * @return the a character's position in the String that 
+     * this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(String str) {
+        char[] chars = str.toCharArray();
+        return canDisplayUpTo(chars, 0, chars.length);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the characters array.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
+        return new AndroidGlyphVector(chars, frc, this, 0);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param iter the CharacterIterator.
+     * 
+     * @return the GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc,
+            CharacterIterator iter) {
+    	throw new RuntimeException("Not implemented!"); //$NON-NLS-1$    
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param glyphCodes the specified integer array of glyph codes.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, int[] glyphCodes)
+            throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param str the specified String.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, String str) {
+        return new AndroidGlyphVector(str.toCharArray(), frc, this, 0);
+
+    }
+
+    /**
+     * Returns the font style constant value corresponding to one of the font style
+     * names ("BOLD", "ITALIC", "BOLDITALIC"). This method returns Font.PLAIN if
+     * the argument is not one of the predefined style names.
+     * 
+     * @param fontStyleName font style name
+     * 
+     * @return font style constant value corresponding to the font style name
+     * specified.
+     */
+    private static int getFontStyle(String fontStyleName) {
+        int result = Font.PLAIN;
+
+        if (fontStyleName.toUpperCase().equals("BOLDITALIC")) { //$NON-NLS-1$
+            result = Font.BOLD | Font.ITALIC;
+        } else if (fontStyleName.toUpperCase().equals("BOLD")) { //$NON-NLS-1$
+            result = Font.BOLD;
+        } else if (fontStyleName.toUpperCase().equals("ITALIC")) { //$NON-NLS-1$
+            result = Font.ITALIC;
+        }
+
+        return result;
+    }
+
+    /**
+     * Decodes the specified string which described the Font. The string 
+     * should have the following format: fontname-style-pointsize. 
+     * The style can be PLAIN, BOLD, BOLDITALIC, or ITALIC.
+     * 
+     * @param str the string which describes the font.
+     * 
+     * @return the Font from the specified string.
+     */
+    public static Font decode(String str) {
+        // XXX: Documentation doesn't describe all cases, e.g. fonts face names
+        // with
+        // symbols that are suggested as delimiters in the documentation.
+        // In this decode implementation only ***-***-*** format is used with
+        // '-'
+        // as the delimiter to avoid unexpected parse results of font face names
+        // with spaces.
+
+        if (str == null) {
+            return DEFAULT_FONT;
+        }
+
+        StringTokenizer strTokens;
+        String delim = "-"; //$NON-NLS-1$
+        String substr;
+
+        int fontSize = DEFAULT_FONT.size;
+        int fontStyle = DEFAULT_FONT.style;
+        String fontName = DEFAULT_FONT.name;
+
+        strTokens = new StringTokenizer(str.trim(), delim);
+
+        // Font Name
+        if (strTokens.hasMoreTokens()) {
+            fontName = strTokens.nextToken(); // first token is the font name
+        }
+
+        // Font Style or Size (if the style is undefined)
+        if (strTokens.hasMoreTokens()) {
+            substr = strTokens.nextToken();
+
+            try {
+                // if second token is the font size
+                fontSize = Integer.parseInt(substr);
+            } catch (NumberFormatException e) {
+                // then second token is the font style
+                fontStyle = getFontStyle(substr);
+            }
+
+        }
+
+        // Font Size
+        if (strTokens.hasMoreTokens()) {
+            try {
+                fontSize = Integer.parseInt(strTokens.nextToken());
+            } catch (NumberFormatException e) {
+            }
+        }
+
+        return new Font(fontName, fontStyle, fontSize);
+    }
+
+    /**
+     * Perfoms the specified affine transform to the Font and returns 
+     * a new Font.
+     * 
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     * 
+     * @throws IllegalArgumentException if affine transform parameter
+     * is null.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size is the specified size.
+     * 
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the style is the specified style.
+     * 
+     * @param style the style of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & Font.BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & Font.ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font
+     * modified to match the specified style and with the specified
+     * affine transform applied to its glyphs.
+     * 
+     * @param style the style of font.
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size and style are the specified 
+     * size and style.
+     * 
+     * @param style the style of font.
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font object with a new set of font attributes.
+     * 
+     * @param attributes the map of attributes.
+     * 
+     * @return the Font.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(Map<? extends Attribute, ?> attributes) {
+        Attribute[] avalAttributes = this.getAvailableAttributes();
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        Object currAttribute;
+        for (Attribute element : avalAttributes) {
+            currAttribute = attributes.get(element);
+            if (currAttribute != null) {
+                derivefRequestedAttributes.put(element, currAttribute);
+            }
+        }
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Compares the specified Object with the current Font.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is an instance of Font
+     * with the same family, size, and style as this Font, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                Font font = (Font) obj;
+
+                return ((this.style == font.style) && (this.size == font.size)
+                        && this.name.equals(font.name)
+                        && (this.pointSize == font.pointSize) && (this
+                        .getTransform()).equals(font.getTransform()));
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Gets the map of font's attributes.
+     * 
+     * @return the map of font's attributes.
+     */
+    @SuppressWarnings("unchecked")
+    public Map<TextAttribute, ?> getAttributes() {
+        return (Map<TextAttribute, ?>) fRequestedAttributes.clone();
+    }
+
+    /**
+     * Gets the keys of all available attributes.
+     * 
+     * @return the keys array of all available attributes.
+     */
+    public Attribute[] getAvailableAttributes() {
+        Attribute[] attrs = { TextAttribute.FAMILY, TextAttribute.POSTURE,
+                TextAttribute.SIZE, TextAttribute.TRANSFORM,
+                TextAttribute.WEIGHT, TextAttribute.SUPERSCRIPT,
+                TextAttribute.WIDTH };
+        return attrs;
+    }
+
+    /**
+     * Gets the baseline for this character.
+     * 
+     * @param c the character.
+     * 
+     * @return the baseline for this character.
+     */
+    public byte getBaselineFor(char c) {
+        // TODO: implement using TT BASE table data
+        return 0;
+    }
+
+    /**
+     * Gets the family name of the Font.
+     * 
+     * @return the family name of the Font.
+     */
+    public String getFamily() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the family name of this Font associated with 
+     * the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the family name of this Font associated with 
+     * the specified locale.
+     */
+    public String getFamily(Locale l) {
+        if (l == null) {
+            // awt.01='{0}' parameter is null
+            throw new NullPointerException(Messages.getString(
+                    "awt.01", "Locale")); //$NON-NLS-1$ //$NON-NLS-2$ 
+        }
+        return getFamily();
+    }
+
+    /**
+     * Gets a Font with the specified attribute set.
+     * 
+     * @param attributes the attributes to be assigned to the new Font.
+     * 
+     * @return the Font.
+     */
+    public static Font getFont(Map<? extends Attribute, ?> attributes) {
+        Font fnt = (Font) attributes.get(TextAttribute.FONT);
+        if (fnt != null) {
+            return fnt;
+        }
+        return new Font(attributes);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name
+     * or returns the specified Font if there is no such property.
+     * 
+     * @param sp the specified property name.
+     * @param f the Font.
+     * 
+     * @return the Font object from the system properties list  with the specified name
+     * or the specified Font if there is no such property.
+     */
+    public static Font getFont(String sp, Font f) {
+        String pr = System.getProperty(sp);
+        if (pr == null) {
+            return f;
+        }
+        return decode(pr);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name.
+     * 
+     * @param sp the system property name.
+     * 
+     * @return the Font, or null if there is no shuch property
+     * with the specified name. 
+     */
+    public static Font getFont(String sp) {
+        return getFont(sp, null);
+    }
+
+    /**
+     * Gets the font name.
+     * 
+     * @return the font name.
+     */
+    public String getFontName() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the font name associated with the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the font name associated with the specified locale.
+     */
+    public String getFontName(Locale l) {
+        return getFamily();
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param chars the chars array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()}; 
+        return new LineMetricsImpl(chars.length, fmet, null);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator iter, int start,
+            int end, FontRenderContext frc) {
+
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        String resultString;
+        int iterCount;
+
+        iterCount = end - start;
+        if (iterCount < 0) {
+            resultString = ""; //$NON-NLS-1$
+        } else {
+            char[] chars = new char[iterCount];
+            int i = 0;
+            for (char c = iter.setIndex(start); c != CharacterIterator.DONE
+                    && (i < iterCount); c = iter.next()) {
+                chars[i] = c;
+                i++;
+            }
+            resultString = new String(chars);
+        }
+        return this.getLineMetrics(resultString, frc);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc) {
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()};
+        //Log.i("FONT FMET", fmet.toString());
+        return new LineMetricsImpl(str.length(), fmet, null);
+
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, int start, int end,
+            FontRenderContext frc) {
+        return this.getLineMetrics(str.substring(start, end), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param ci the specified CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int start,
+            int end, FontRenderContext frc) {
+        int first = ci.getBeginIndex();
+        int finish = ci.getEndIndex();
+        char[] chars;
+
+        if (start < first) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > finish) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        chars = new char[end - start];
+
+        ci.setIndex(start);
+        for (int i = 0; i < chars.length; i++) {
+            chars[i] = ci.current();
+            ci.next();
+        }
+
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, FontRenderContext frc) {
+        char[] chars = str.toCharArray();
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, int start, int end,
+            FontRenderContext frc) {
+
+        return this.getStringBounds((str.substring(start, end)), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param chars the specified character array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > chars.length) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        final int TRANSFORM_MASK = AffineTransform.TYPE_GENERAL_ROTATION
+                | AffineTransform.TYPE_GENERAL_TRANSFORM;
+        Rectangle2D bounds;
+
+        AffineTransform transform = getTransform();
+
+        // XXX: for transforms where an angle between basis vectors is not 90
+        // degrees Rectanlge2D class doesn't fit as Logical bounds.
+        if ((transform.getType() & TRANSFORM_MASK) == 0) {
+            int width = 0;
+            for (int i = start; i < end; i++) {
+                width += peer.charWidth(chars[i]);
+            }
+            //LineMetrics nlm = peer.getLineMetrics();
+            
+            LineMetrics nlm = getLineMetrics(chars, start, end, frc);
+            
+            bounds = transform.createTransformedShape(
+                    new Rectangle2D.Float(0, -nlm.getAscent(), width, nlm
+                            .getHeight())).getBounds2D();
+        } else {
+            int len = end - start;
+            char[] subChars = new char[len];
+            System.arraycopy(chars, start, subChars, 0, len);
+            bounds = createGlyphVector(frc, subChars).getLogicalBounds();
+        }
+        return bounds;
+    }
+
+    /**
+     * Gets the character's maximum bounds as defined in 
+     * the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * 
+     * @return the character's maximum bounds.
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$ 
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        Rectangle2D bounds = peer.getMaxCharBounds(frc);
+        AffineTransform transform = getTransform();
+        // !! Documentation doesn't describe meaning of max char bounds
+        // for the fonts that have rotate transforms. For all transforms
+        // returned bounds are the bounds of transformed maxCharBounds
+        // Rectangle2D that corresponds to the font with identity transform.
+        // TODO: resolve this issue to return correct bounds
+        bounds = transform.createTransformedShape(bounds).getBounds2D();
+
+        return bounds;
+    }
+
+    /**
+     * Returns a new GlyphVector object performing full layout of
+     * the text.
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the character array to be layout.
+     * @param start the start offset of the text to use for 
+     * the GlyphVector.
+     * @param count the count of characters to use for 
+     * the GlyphVector.
+     * @param flags the flag indicating text direction: 
+     * LAYOUT_RIGHT_TO_LEFT, LAYOUT_LEFT_TO_RIGHT.
+     * 
+     * @return the GlyphVector.
+     */
+    public GlyphVector layoutGlyphVector(FontRenderContext frc, char[] chars,
+            int start, int count, int flags) {
+        // TODO: implement method for bidirectional text.
+        // At the moment only LTR and RTL texts supported.
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.95", //$NON-NLS-1$
+                    start));
+        }
+
+        if (count < 0) {
+            // awt.98=Wrong count value, can not be negative: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.98", //$NON-NLS-1$
+                    count));
+        }
+
+        if (start + count > chars.length) {
+            // awt.99=Wrong [start + count] is out of range: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.99", //$NON-NLS-1$
+                    (start + count)));
+        }
+
+        char[] out = new char[count];
+        System.arraycopy(chars, start, out, 0, count);
+
+        return new CommonGlyphVector(out, frc, this, flags);
+    }
+
+    /**
+     * Returns the String representation of this Font.
+     * 
+     * @return the String representation of this Font.
+     */
+    @Override
+    public String toString() {
+        String stl = "plain"; //$NON-NLS-1$
+        String result;
+
+        if (this.isBold() && this.isItalic()) {
+            stl = "bolditalic"; //$NON-NLS-1$
+        }
+        if (this.isBold() && !this.isItalic()) {
+            stl = "bold"; //$NON-NLS-1$
+        }
+
+        if (!this.isBold() && this.isItalic()) {
+            stl = "italic"; //$NON-NLS-1$
+        }
+
+        result = this.getClass().getName() + "[family=" + this.getFamily() + //$NON-NLS-1$
+                ",name=" + this.name + //$NON-NLS-1$
+                ",style=" + stl + //$NON-NLS-1$
+                ",size=" + this.size + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        return result;
+    }
+
+    /**
+     * Gets the postscript name of this Font.
+     * 
+     * @return the postscript name of this Font.
+     */
+    public String getPSName() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getPSName();
+    }
+
+    /**
+     * Gets the logical name of this Font.
+     * 
+     * @return the logical name of this Font.
+     */
+    public String getName() {
+        return (this.name);
+    }
+
+    /**
+     * Gets the peer of this Font.
+     * 
+     * @return the peer of this Font.
+     * 
+     * @deprecated Font rendering is platform independent now.
+     */
+    @Deprecated
+    public java.awt.peer.FontPeer getPeer() {
+        if (fontPeer == null) {
+            fontPeer = (FontPeerImpl) Toolkit.getDefaultToolkit()
+                    .getGraphicsFactory().getFontPeer(this);
+        }
+        return fontPeer;
+
+    }
+
+    /**
+     * Gets the transform acting on this Font (from the Font's 
+     * attributes).
+     * 
+     * @return the transformation of this Font. 
+     */
+    public AffineTransform getTransform() {
+        Object transform = fRequestedAttributes.get(TextAttribute.TRANSFORM);
+
+        if (transform != null) {
+            if (transform instanceof TransformAttribute) {
+                return ((TransformAttribute) transform).getTransform();
+            }
+            if (transform instanceof AffineTransform) {
+                return new AffineTransform((AffineTransform) transform);
+            }
+        } else {
+            transform = new AffineTransform();
+        }
+        return (AffineTransform) transform;
+
+    }
+
+    /**
+     * Checks if this font is transformed or not.
+     * 
+     * @return true, if this font is transformed, false otherwise.
+     */
+    public boolean isTransformed() {
+        return this.transformed;
+    }
+
+    /**
+     * Checks if this font has plain style or not.
+     * 
+     * @return true, if this font has plain style, false otherwise.
+     */
+    public boolean isPlain() {
+        return (this.style == PLAIN);
+    }
+
+    /**
+     * Checks if this font has italic style or not.
+     * 
+     * @return true, if this font has italic style, false otherwise.
+     */
+    public boolean isItalic() {
+        return (this.style & ITALIC) != 0;
+    }
+
+    /**
+     * Checks if this font has bold style or not.
+     * 
+     * @return true, if this font has bold style, false otherwise.
+     */
+    public boolean isBold() {
+        return (this.style & BOLD) != 0;
+    }
+
+    /**
+     * Returns true if this Font has uniform line metrics. 
+     * 
+     * @return true if this Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns hash code of this Font object.
+     * 
+     * @return the hash code of this Font object.
+
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(this.name);
+        hash.append(this.style);
+        hash.append(this.size);
+
+        return hash.hashCode();
+    }
+
+    /**
+     * Gets the style of this Font.
+     * 
+     * @return the style of this Font.
+     */
+    public int getStyle() {
+        return this.style;
+    }
+
+    /**
+     * Gets the size of this Font.
+     * 
+     * @return the size of this Font.
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Gets the number of glyphs for this Font.
+     * 
+     * @return the number of glyphs for this Font.
+     */
+    public int getNumGlyphs() {
+        if (numGlyphs == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.numGlyphs = peer.getNumGlyphs();
+        }
+        return this.numGlyphs;
+    }
+
+    /**
+     * Gets the glyphCode which is used as default glyph when this Font
+     * does not have a glyph for a specified unicode.
+     * 
+     * @return the missing glyph code.
+     */
+    public int getMissingGlyphCode() {
+        if (missingGlyphCode == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.missingGlyphCode = peer.getMissingGlyphCode();
+        }
+        return this.missingGlyphCode;
+    }
+
+    /**
+     * Gets the float value of font's size.
+     * 
+     * @return the float value of font's size.
+     */
+    public float getSize2D() {
+        return this.pointSize;
+    }
+
+    /**
+     * Gets the italic angle of this Font.
+      * 
+     * @return the italic angle of this Font.
+     */
+    public float getItalicAngle() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getItalicAngle();
+    }
+
+    /**
+     * Creates the font with the specified font format and font file.
+     * 
+     * @param fontFormat the font format.
+     * @param fontFile the file object represented the input data 
+     * for the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, File fontFile)
+            throws FontFormatException, IOException {
+        // ???AWT not supported
+        InputStream is = new FileInputStream(fontFile);
+        try {
+            return createFont(fontFormat, is);
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * Creates the font with the specified font format and input stream.
+     * 
+     * @param fontFormat the font format.
+     * @param fontStream the input stream represented input data for 
+     * the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, InputStream fontStream)
+            throws FontFormatException, IOException {
+
+        // ???AWT not supported
+
+        BufferedInputStream buffStream;
+        int bRead = 0;
+        int size = 8192;
+        // memory page size, for the faster reading
+        byte buf[] = new byte[size];
+
+        if (fontFormat != TRUETYPE_FONT) { // awt.9A=Unsupported font format
+            throw new IllegalArgumentException(Messages.getString("awt.9A")); //$NON-NLS-1$ 
+        }
+        
+        /* Get font file in system-specific directory */
+
+        File fontFile = Toolkit.getDefaultToolkit().getGraphicsFactory()
+                .getFontManager().getTempFontFile();
+
+                // BEGIN android-modified
+        buffStream = new BufferedInputStream(fontStream, 8192);
+                // END android-modified
+        FileOutputStream fOutStream = new FileOutputStream(fontFile);
+
+        bRead = buffStream.read(buf, 0, size);
+
+        while (bRead != -1) {
+            fOutStream.write(buf, 0, bRead);
+            bRead = buffStream.read(buf, 0, size);
+        }
+
+        buffStream.close();
+        fOutStream.close();
+
+        Font font = null;
+
+        font = Toolkit.getDefaultToolkit().getGraphicsFactory().embedFont(
+                fontFile.getAbsolutePath());
+        if (font == null) { // awt.9B=Can't create font - bad font data
+            throw new FontFormatException(Messages.getString("awt.9B")); //$NON-NLS-1$
+        }
+        return font;
+    }
+
+}
diff --git a/awt/java/awt/FontFormatException.java b/awt/java/awt/FontFormatException.java
new file mode 100644
index 0000000..c017fd2
--- /dev/null
+++ b/awt/java/awt/FontFormatException.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The FontFormatException class is used to provide notification
+ * and information that font can't be created.
+ */
+public class FontFormatException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4481290147811361272L;
+
+    /**
+     * Instantiates a new font format exception with detailed message.
+     * 
+     * @param reason the detailed message.
+     */
+    public FontFormatException(String reason) {
+        super(reason);
+    }
+
+}
diff --git a/awt/java/awt/FontMetrics.java b/awt/java/awt/FontMetrics.java
new file mode 100644
index 0000000..3948d73
--- /dev/null
+++ b/awt/java/awt/FontMetrics.java
@@ -0,0 +1,456 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The FontMetrics class contains information about the rendering 
+ * of a particular font on a particular screen.
+ * <p>
+ * Each character in the Font has three values that help define where 
+ * to place it: an ascent, a descent, and an advance. The ascent is the 
+ * distance the character extends above the baseline. The descent is
+ * the distance the character extends below the baseline. 
+ * The advance width defines the position at which the next character
+ * should be placed.
+ * <p>
+ * An array of characters or a string has an ascent, a descent,
+ *  and an advance width too. The ascent or descent of the array 
+ *  is specified by the maximum ascent or descent of the characters 
+ *  in the array. The advance width is the sum of the advance widths 
+ *  of each of the characters in the character array.
+ */
+public abstract class FontMetrics implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1681126225205050147L;
+
+    /** The font from which the FontMetrics is created. */
+    protected Font font;
+
+    /**
+     * Instantiates a new font metrics from the specified Font.
+     * 
+     * @param fnt the Font.
+     */
+    protected FontMetrics(Font fnt) {
+        this.font = fnt;
+    }
+
+    /**
+     * Returns the String representation of this FontMetrics.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return this.getClass().getName() +
+                "[font=" + this.getFont() + //$NON-NLS-1$
+                "ascent=" + this.getAscent() + //$NON-NLS-1$
+                ", descent=" + this.getDescent() + //$NON-NLS-1$
+                ", height=" + this.getHeight() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the font associated with this FontMetrics.
+     * 
+     * @return the font associated with this FontMetrics.
+     */
+    public Font getFont() {
+        return font;
+    }
+
+    /**
+     * Gets the height of the text line in this Font.
+     * 
+     * @return the height of the text line in this Font.
+     */
+    public int getHeight() {
+        return this.getAscent() + this.getDescent() + this.getLeading();
+    }
+
+    /**
+     * Gets the font ascent of the Font associated with this FontMetrics.
+     * The font ascent is the distance from the font's baseline to 
+     * the top of most alphanumeric characters.
+     * 
+     * @return the ascent of the Font associated with this FontMetrics.
+     */
+    public int getAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the font descent of the Font associated with this FontMetrics.
+     * The font descent is the distance from the font's baseline to 
+     * the bottom of most alphanumeric characters with descenders.
+     * 
+     * @return the descent of the Font associated with this FontMetrics.
+     */
+    public int getDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the leading of the Font associated with this FontMetrics.
+     * 
+     * @return the leading of the Font associated with this FontMetrics.
+     */
+    public int getLeading() {
+        return 0;
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex,
+                                        int limit, Graphics context) {
+        return font.getLineMetrics(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, Graphics context) {
+        return font.getLineMetrics(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     * 
+     * @param chars the character array.
+     * @param beginIndex the offset of array.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Returns the character's maximum bounds in the specified 
+     * Graphics context.
+     * 
+     * @param context the Graphics context.
+     * 
+     * @return the character's maximum bounds in the specified 
+     * Graphics context.
+     */
+    public Rectangle2D getMaxCharBounds(Graphics context) {
+        return this.font.getMaxCharBounds(this.getFRCFromGraphics(context));
+    }
+    
+    /**
+     * Gets the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex,
+            int limit, Graphics context) {
+        return font.getStringBounds(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+
+    /**
+     * Gets the bounds of the specified characters array 
+     * in the specified Graphics context.
+     * 
+     * @param chars the characters array.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified characters array 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, Graphics context) {
+        return font.getStringBounds(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Checks if the Font has uniform line metrics or not. 
+     * The Font can contain characters of other fonts for 
+     * covering character set. In this case the Font isn't
+     * uniform. 
+     *  
+     * @return true, if the Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        return this.font.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of bytes in this Font.   
+     * 
+     * @param data the array of bytes to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int bytesWidth(byte[] data, int off, int len) {
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of characters in this Font.   
+     * 
+     * @param data the array of characters to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int charsWidth(char[] data, int off , int len){
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified unicode point code of 
+     * character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(int ch) {
+        return 0;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(char ch) {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum advance width of character in this Font.
+     * 
+     * @return the maximum advance width of character in this Font.
+     */
+    public int getMaxAdvance() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     * 
+     * @return the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     */
+    public int getMaxAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     * 
+     * @deprecated Replaced by getMaxDescent() method.
+     */
+    @Deprecated
+    public int getMaxDecent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     */
+    public int getMaxDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the advance widths of the characters in the Font.
+     * 
+     * @return the advance widths of the characters in the Font.
+     */
+    public int[] getWidths() {
+        return null;
+    }
+
+    /**
+     * Returns the advance width for the specified String in this Font.
+     * 
+     * @param str String to be measured. 
+     * 
+     * @return the the advance width for the specified String 
+     * in this Font.
+     */
+    public int stringWidth(String str) {
+        return 0;
+    }
+    
+    /**
+     * Returns FontRenderContext instanse of the Graphics context specified.
+     * 
+     * @param context the specified Graphics context
+     * 
+     * @return a FontRenderContext of the specified Graphics context.
+     */
+    private FontRenderContext getFRCFromGraphics(Graphics context){
+        FontRenderContext frc;
+        if (context instanceof Graphics2D) {
+            frc = ((Graphics2D)context).getFontRenderContext();
+        } else {
+            frc = new FontRenderContext(null, false, false);
+        }
+
+        return frc;
+    }
+}
+
diff --git a/awt/java/awt/GradientPaint.java b/awt/java/awt/GradientPaint.java
new file mode 100644
index 0000000..0e06528
--- /dev/null
+++ b/awt/java/awt/GradientPaint.java
@@ -0,0 +1,219 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GradientPaint class defines a way to fill a Shape with a linear color
+ * gradient pattern. 
+ * <p>
+ * The GradientPaint's fill pattern is determined by two points and two colors, 
+ * plus the cyclic mode option.
+ * Each of the two points is painted with its corresponding color, and on 
+ * the line segment connecting the two points, the color is proportionally
+ * changed between the two colors. For points on the same line which are not 
+ * between the two specified points (outside of the connecting segment) their
+ * color is determined by the cyclic mode option. If the mode is cyclic, then
+ * the rest of the line repeats the color pattern of the connecting segment, 
+ * cycling back and forth between the two colors. If not, the mode is acyclic 
+ * which means that all points 
+ * on the line outside the connecting line segment are given the same 
+ * color as the closest of the two specified points.
+ * <p>
+ * The color of points that are not on the line connecting the two 
+ * specified points are given by perpendicular projection: by taking 
+ * the set of lines perpendicular to the connecting line and for each 
+ * one, the whole line is colored with the same color.
+ */
+public class GradientPaint implements Paint {
+    
+    /** The start point color. */
+    Color color1;
+
+    /** The end color point. */
+    Color color2;
+
+    /** The location of the start point. */
+    Point2D point1;
+
+    /** The location of the end point. */
+    Point2D point2;
+
+    /** The indicator of cycle filling. If TRUE filling 
+     * repeated outside points stripe, if FALSE solid color filling outside. */
+    boolean cyclic;
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2,
+            Color color2, boolean cyclic) {
+        if (point1 == null || point2 == null) {
+            // awt.6D=Point is null
+            throw new NullPointerException(Messages.getString("awt.6D")); //$NON-NLS-1$
+        }
+        if (color1 == null || color2 == null) {
+            // awt.6E=Color is null
+            throw new NullPointerException(Messages.getString("awt.6E")); //$NON-NLS-1$
+        }
+
+        this.point1 = point1;
+        this.point2 = point2;
+        this.color1 = color1;
+        this.color2 = color2;
+        this.cyclic = cyclic;
+    }
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2,
+            boolean cyclic) {
+        this(new Point2D.Float(x1, y1), color1, new Point2D.Float(x2, y2), color2, cyclic);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2) {
+        this(x1, y1, color1, x2, y2, color2, false);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2) {
+        this(point1, color1, point2, color2, false);
+    }
+
+    /**
+     * Creates PaintContext for a color pattern generating. 
+     * 
+     * @param cm the ColorModel of the Paint data.
+     * @param deviceBounds the bounding Rectangle of graphics primitives
+     * being rendered in the device space. 
+     * @param userBounds tthe bounding Rectangle of graphics primitives
+     * being rendered in the user space. 
+     * @param t the AffineTransform from user space into device space.
+     * @param hints the RrenderingHints object.
+     * 
+     * @return the PaintContext for color pattern generating.
+     * 
+     * @see java.awt.Paint#createContext(java.awt.image.ColorModel, java.awt.Rectangle, java.awt.geom.Rectangle2D, java.awt.geom.AffineTransform, java.awt.RenderingHints)
+     */
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform t, RenderingHints hints) {
+        return new GradientPaintContext(cm, t, point1, color1, point2, color2, cyclic);
+    }
+
+    /**
+     * Gets the color of the first point.
+     * 
+     * @return the color of the first point.
+     */
+    public Color getColor1() {
+        return color1;
+    }
+
+    /**
+     * Gets the color of the second point.
+     * 
+     * @return the color of the second point.
+     */
+    public Color getColor2() {
+        return color2;
+    }
+
+    /**
+     * Gets the first point.
+     * 
+     * @return the Point object - the first point. 
+     */
+    public Point2D getPoint1() {
+        return point1;
+    }
+
+    /**
+     * Gets the second point.
+     * 
+     * @return the Point object - the second point.
+     */
+    public Point2D getPoint2() {
+        return point2;
+    }
+
+    /**
+     * Gets the transparency mode for the GradientPaint.
+     * 
+     * @return the transparency mode for the GradientPaint.
+     * 
+     * @see java.awt.Transparency#getTransparency()
+     */
+    public int getTransparency() {
+        int a1 = color1.getAlpha();
+        int a2 = color2.getAlpha();
+        return (a1 == 0xFF && a2 == 0xFF) ? OPAQUE : TRANSLUCENT;
+    }
+
+    /**
+     * Returns the GradientPaint mode: true for cyclic mode, false for
+     * acyclic mode.
+     * 
+     * @return true if the gradient cycles repeatedly between the two colors; 
+     * false otherwise.
+     */
+    public boolean isCyclic() {
+        return cyclic;
+    }
+}
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java
new file mode 100644
index 0000000..74575f5
--- /dev/null
+++ b/awt/java/awt/GradientPaintContext.java
@@ -0,0 +1,204 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+class GradientPaintContext implements PaintContext {
+
+    /**
+     * The size of noncyclic part of color lookup table
+     */
+    static int LOOKUP_SIZE = 256;
+    
+    /**
+     * The index mask to lookup color in the table
+     */
+    static int LOOKUP_MASK = 0x1FF;
+    
+    /**
+     * The min value equivalent to zero. If absolute value less then ZERO it considered as zero.  
+     */
+    static double ZERO = 1E-10;
+
+    /**
+     * The ColorModel user defined for PaintContext
+     */
+    ColorModel cm;
+    
+    /**
+     * The indicator of cycle filling.
+     */
+    boolean cyclic;
+    
+    /**
+     * The integer color value of the start point
+     */
+    int c1;
+    
+    /**
+     * The integer color value of the end point
+     */
+    int c2;
+    
+    /**
+     * The lookup gradient color table 
+     */
+    int[] table;
+
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dx;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dy;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int delta;
+    
+    /**
+     * Constructs a new GradientPaintcontext
+     * @param cm - not used
+     * @param t - the fill transformation
+     * @param point1 - the start fill point
+     * @param color1 - color of the start point 
+     * @param point2 - the end fill point
+     * @param color2 - color of the end point
+     * @param cyclic - the indicator of cycle filling
+     */
+    GradientPaintContext(ColorModel cm, AffineTransform t, Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
+        this.cyclic = cyclic;
+        this.cm = ColorModel.getRGBdefault();
+
+        c1 = color1.getRGB();
+        c2 = color2.getRGB();
+
+        double px = point2.getX() - point1.getX();
+        double py = point2.getY() - point1.getY();
+
+        Point2D p = t.transform(point1, null);
+        Point2D bx = new Point2D.Double(px, py);
+        Point2D by = new Point2D.Double(py, -px);
+
+        t.deltaTransform(bx, bx);
+        t.deltaTransform(by, by);
+
+        double vec = bx.getX() * by.getY() - bx.getY() * by.getX();
+
+        if (Math.abs(vec) < ZERO) {
+            dx = dy = delta = 0;
+            table = new int[1];
+            table[0] = c1;
+        } else {
+            double mult = LOOKUP_SIZE * 256 / vec;
+            dx = (int)(by.getX() * mult);
+            dy = (int)(by.getY() * mult);
+            delta = (int)((p.getX() * by.getY() - p.getY() * by.getX()) * mult);
+            createTable();
+        }
+    }
+
+    /**
+     * Create color index lookup table. Calculate 256 step trasformation from 
+     * the start point color to the end point color. Colors multiplied by 256 to do integer calculations. 
+     */
+    void createTable() {
+        double ca = (c1 >> 24) & 0xFF;
+        double cr = (c1 >> 16) & 0xFF;
+        double cg = (c1 >> 8) & 0xFF;
+        double cb = c1 & 0xFF;
+
+        double k = 1.0 / LOOKUP_SIZE;
+        double da = (((c2 >> 24) & 0xFF) - ca) * k;
+        double dr = (((c2 >> 16) & 0xFF) - cr) * k;
+        double dg = (((c2 >> 8) & 0xFF) - cg) * k;
+        double db = ((c2 & 0xFF) - cb) * k;
+
+        table = new int[cyclic ? LOOKUP_SIZE + LOOKUP_SIZE : LOOKUP_SIZE];
+        for(int i = 0; i < LOOKUP_SIZE; i++) {
+            table[i] =
+                (int)ca << 24 |
+                (int)cr << 16 |
+                (int)cg << 8 |
+                (int)cb;
+            ca += da;
+            cr += dr;
+            cg += dg;
+            cb += db;
+        }
+        if (cyclic) {
+            for(int i = 0; i < LOOKUP_SIZE; i++) {
+                table[LOOKUP_SIZE + LOOKUP_SIZE - 1 - i] = table[i];
+            }
+        }
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    public void dispose() {
+    }
+
+    public Raster getRaster(int x, int y, int w, int h) {
+        WritableRaster rast = cm.createCompatibleWritableRaster(w, h);
+
+        int[] buf = ((DataBufferInt)rast.getDataBuffer()).getData();
+
+        int c = x * dy - y * dx - delta;
+        int cx = dy;
+        int cy = - w * dy - dx;
+        int k = 0;
+
+        if (cyclic) {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    buf[k++] = table[(c >> 8) & LOOKUP_MASK];
+                    c += cx;
+                }
+                c += cy;
+            }
+        } else {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    int index = c >> 8;
+                    buf[k++] = index < 0 ? c1 : index >= LOOKUP_SIZE ? c2 : table[index];
+                    c += cx;
+                }
+                c += cy;
+            }
+        }
+
+        return rast;
+    }
+
+}
+
diff --git a/awt/java/awt/Graphics.java b/awt/java/awt/Graphics.java
new file mode 100644
index 0000000..c20f6bc
--- /dev/null
+++ b/awt/java/awt/Graphics.java
@@ -0,0 +1,737 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * The abstract Graphics class allows applications to draw on a screen
+ * or other rendering target. There are several properties which 
+ * define rendering options: origin point, clipping area, color, font.
+ * <br><br>
+ * The origin point specifies the beggining of the clipping area coordinate 
+ * system. All coordinates used in rendering operations are computed with 
+ * respect to this point. The clipping area defines the boundaries where 
+ * rendering operations can be performed. Rendering operations can't modify 
+ * pixels outside of the clipping area.
+ * <br><br>
+ * The draw and fill methods allow applications to drawing shapes, text, 
+ * images with specified font and color options in the specified part 
+ * of the screen.
+ *    
+ */
+public abstract class Graphics {
+
+    // Constructors
+
+    /**
+     * Instantiates a new Graphics. This constructor is default for Graphics and
+     * can not be called directly. 
+     */
+    protected Graphics() {
+    }
+
+    // Public methods
+
+    /**
+     * Creates a copy of the Graphics object with a new origin and a new 
+     * specified clip area. The new clip area is the rectangle defined by 
+     * the origin point with coordinates X,Y and the given width and height. 
+     * The coordinates of all subsequent rendering operations will be computed
+     * with respect to the new origin and can be performed only within the 
+     * range of the clipping area dimentions. 
+     *  
+     * @param x the X coordinate of the original point
+     * @param y the Y coordinate of the original point
+     * @param width the width of clipping area
+     * @param height the height of clipping area
+     * 
+     * @return the Graphics object with new origin point and clipping area. 
+     */
+    public Graphics create(int x, int y, int width, int height) {
+        Graphics res = create();
+        res.translate(x, y);
+        res.clipRect(0, 0, width, height);
+        return res;
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width+1)x(height+1). Stroke and paint attributes of
+        // the Graphics2D should be reset to the default values.
+        // fillRect is used instead of drawLine to bypass stroke
+        // reset/set and rasterization.
+
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Draws the text represented by byte array. This method uses the current 
+     * font and color for rendering.
+     * 
+     * @param bytes the byte array which contains the text to be drawn. 
+     * @param off the offset within the byte array of the text to be drawn.
+     * @param len the number of bytes of text to draw. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawBytes(byte[] bytes, int off, int len, int x, int y) {
+        drawString(new String(bytes, off, len), x, y);
+    }
+
+    /**
+     * Draws the text represented by character array. This method uses the 
+     * current font and color for rendering.
+     * 
+     * @param chars the character array. 
+     * @param off the offset within the character array of the text to be drawn.
+     * @param len the number of characters which will be drawn. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawChars(char[] chars, int off, int len, int x, int y) {
+        drawString(new String(chars, off, len), x, y);
+    }
+
+    /**
+     * Draws the outline of a polygon which is defined by Polygon object.
+     * 
+     * @param p the Polygon object.
+     */
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Draws the rectangle with the specified width and length and top left 
+     * corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public void drawRect(int x, int y, int width, int height) {
+        int []xpoints = {x, x, x+width, x+width};
+        int []ypoints = {y, y+height, y+height, y};
+
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    /**
+     * Fills the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width)x(height), same as fillRect.
+        // Stroke and paint attributes of the Graphics2D should be reset
+        // to the default values. fillRect is used instead of drawLine to
+        // bypass stroke reset/set and line rasterization.
+        
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x+1, y+1, width-1, height-1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Fills the polygon with the current color.
+     * 
+     * @param p the Polygon object.
+     */
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Disposes of the Graphics.
+     */
+    @Override
+    public void finalize() {
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle 
+     * and copies it to an existing rectangle.
+     *  
+     * @param r a Rectangle object where the current clipping area 
+     * bounds are to be copied.
+     * 
+     * @return the bounds of the current clipping area.
+     */
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+
+        if (clip != null) {
+            // TODO: Can we get shape bounds without creating Rectangle object?
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+
+        return r;
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     * 
+     * @return a Rectangle object 
+     * 
+     * @deprecated Use {@link #getClipBounds()}
+     */
+    @Deprecated
+    public Rectangle getClipRect() {
+        return getClipBounds();
+    }
+
+    /**
+     * Gets the font metrics of the current font. 
+     * The font metrics object contains information about the rendering 
+     * of a particular font.
+     * 
+     * @return the font metrics of current font.
+     */
+    public FontMetrics getFontMetrics() {
+        return getFontMetrics(getFont());
+    }
+
+    /**
+     * Determines whether or not the specified rectangle intersects the 
+     * current clipping area.
+     *  
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * 
+     * @return true, if the specified rectangle intersects the current clipping area, 
+     * overwise false. 
+     */
+    public boolean hitClip(int x, int y, int width, int height) {
+        // TODO: Create package private method Rectangle.intersects(int, int, int, int);
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+
+    /**
+     * Returns string which represents this Graphics object.
+     * 
+     * @return the string which represents this Graphics object.
+     */
+    @Override
+    public String toString() {
+        // TODO: Think about string representation of Graphics.
+        return "Graphics"; //$NON-NLS-1$
+    }
+
+    // Abstract methods
+
+    /**
+     * Clears the specified rectangle. This method fills specified rectangle 
+     * with background color.  
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public abstract void clearRect(int x, int y, int width, int height);
+
+    /**
+     * Intersects the current clipping area with a new rectangle. 
+     * If the current clipping area is not defined, the rectangle 
+     * becomes a new clipping area. Rendering operations are only allowed 
+     * within the new the clipping area.    
+     *          
+     * @param x the X coordinate of the rectangle for intersection. 
+     * @param y the Y coordinate of the rectangle for intersection.
+     * @param width the width of the rectangle for intersection.
+     * @param height the height of the rectangle for intersection.
+     */
+    public abstract void clipRect(int x, int y, int width, int height);
+
+    /**
+     * Copies the rectangle area to another area specified by 
+     * a distance (dx, dy) from the original rectangle's location. 
+     * Positive dx and dy values give a new location defined by 
+     * translation to the right and down from the original location, 
+     * negative dx and dy values - to the left and up.
+     * <br><br>
+     * 
+     * @param sx the X coordinate of the rectangle which will be copied. 
+     * @param sy the Y coordinate of the rectangle which will be copied.
+     * @param width the width of the rectangle which will be copied.
+     * @param height the height of the rectangle which will be copied.
+     * @param dx the horizontal distance from the source rectangle's 
+     * location to the copy's location. 
+     * @param dy the vertical distance from the source rectangle's 
+     * location to the copy's location. 
+     */
+    public abstract void copyArea(int sx, int sy, int width, int height, int dx, int dy);
+
+    /**
+     * Creates a new copy of this Graphics.
+     * 
+     * @return a new Graphics context which is a copy of this Graphics.
+     */
+    public abstract Graphics create();
+
+    /**
+     * Disposes of the Graphics. This Graphics object can not be used after 
+     * calling this method.  
+     */
+    public abstract void dispose();
+
+    /**
+     * Draws the arc covering the specified rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions 
+     * (width and height). The arc center is the the center of specified rectangle. 
+     * The angle origin is 3 o'clock position, the positive angle is counted as a 
+     * counter-clockwise rotation, the negotive angle is counted as clockwise rotation.   
+     * 
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void drawArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Draws the specified image with the defined background color. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false.       
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Draws the specified image. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it with the defined background color. The top left corner 
+     * of the image will be drawn at the point (x, y) in current coordinate 
+     * system. The non-opaque pixels will be drawn in the background color. 
+     * The image loading process notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image's top left corner.
+     * @param y the Y coordinate of the image's top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it. The top left corner of the image will be drawn at the 
+     * point (x, y) in current coordinate system. The image loading process 
+     * notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image top left corner.
+     * @param y the Y coordinate of the image top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image with the specified 
+     * background color. The sub-image to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The non opaque pixels will be drawn in the background color. The 
+     * image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image. The sub-image 
+     * to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer);
+    
+    /**
+     * Draws a line from the point (x1, y1) to the point (x2, y2). 
+     * This method draws the line with current color 
+     * which can be changed by setColor(Color c) method.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     */
+    public abstract void drawLine(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws the ouline of an oval to fit in the rectangle defined
+     * by the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate
+     * @param y the Y top left corner oval coordinate
+     * @param width the oval width
+     * @param height the oval height
+     */
+    public abstract void drawOval(int x, int y, int width, int height);
+
+    /**
+     * Draws the outline of a polygon. The polygon vertices are defined by points 
+     * with xpoints[i], ypoints[i]  as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void drawPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws a set of connected lines which are defined by the x and y coordinate arrays.  
+     * The polyline is closed if coordinates of the first point are the same as 
+     * coordinates of the last point.
+     * 
+     * @param xpoints the array of X point coordinates.
+     * @param ypoints the array of Y point coordinates.
+     * @param npoints the number of points.
+     */
+    public abstract void drawPolyline(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws the outline of a rectangle with round corners.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param arcWidth the arc width for the corners.
+     * @param arcHeight the arc height for the corners.
+     */
+    public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Draws a text defined by an iterator. The iterator should specify the font 
+     * for every character. 
+     *  
+     * @param iterator the iterator.
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws a text defined by a string. This method draws the text with current
+     * font and color.
+     * 
+     * @param str the string. 
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the arc covering the rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions (width and height). 
+     * The arc center is the the center of specified rectangle. 
+     * The angle origin is at the 3 o'clock position, and a positive angle gives  
+     * counter-clockwise rotation, a negative angle gives clockwise rotation.
+     *  
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void fillArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Fills an oval with the current color where the oval is defined by the 
+     * bounding rectangle with the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate.
+     * @param y the Y top left corner oval coordinate.
+     * @param width the oval width.
+     * @param height the oval height.
+     */
+    public abstract void fillOval(int x, int y, int width, int height);
+
+    /**
+     * Fills a polygon with the current color. The polygon vertices are defined by the points 
+     * with xpoints[i], ypoints[i] as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void fillPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Fills a rectangle with the current color. 
+     * The rectangle is defined by its width and length and top left corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     */
+    public abstract void fillRect(int x, int y, int width, int height);
+
+    /**
+     * Fills a round cornered rectangle with the current color.
+     * 
+     * @param x the X coordinate of the top left corner of the bounding rectangle.
+     * @param y the Y coordinate of the top left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * @param arcWidth the arc width at the corners.
+     * @param arcHeight the arc height at the corners.
+     */
+    public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Gets the clipping area.
+     * <br> <br>
+     *  
+     * @return a Shape object of the clipping area or null if it is not set.
+     */
+    public abstract Shape getClip();
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     *  
+     * @return a Rectangle object which represents the bounds of the current clipping area. 
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Gets the current color of Graphics.
+     * 
+     * @return the current color.
+     */
+    public abstract Color getColor();
+
+    /**
+     * Gets the current font of Graphics.
+     * 
+     * @return the current font.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets the font metrics of the specified font. 
+     * The font metrics object contains information about the rendering of a particular font.
+     * 
+     * @param font the specified font
+     * 
+     * @return the font metrics for the specified font.
+     */
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Sets the new clipping area specified by rectangle. The new clipping area 
+     * doesn't depend on the window's visibility. Rendering operations can't be performed 
+     * outside new clipping area.
+     * 
+     * @param x the X coordinate of the new clipping rectangle.
+     * @param y the Y coordinate of the new clipping rectangle.
+     * @param width the width of the new clipping rectangle.
+     * @param height the height of the new clipping rectangle.
+     */
+    public abstract void setClip(int x, int y, int width, int height);
+
+    /**
+     * Sets the new clipping area to be the area specified by Shape object. 
+     * The new clipping area doesn't depend on the window's visibility. 
+     * Rendering operations can't be performed outside new clipping area.
+     * 
+     * @param clip a Shape object which representes new clipping area.
+     */
+    public abstract void setClip(Shape clip);
+
+    /**
+     * Sets the current Graphics color. All rendering operations with this Graphics
+     * will use this color.
+     * 
+     * @param c the new color.
+     */
+    public abstract void setColor(Color c);
+
+    /**
+     * Sets the current Graphics font. All rendering operations with this Graphics
+     * will use this font.
+     * 
+     * @param font the new font.
+     */
+    public abstract void setFont(Font font);
+
+    /**
+     * Sets the paint mode for the Graphics which overwrites all rendering 
+     * operations with the current color.
+     *  
+     */
+    public abstract void setPaintMode();
+
+    /**
+     * Sets the XOR mode for the Graphics which changes a pixel from
+     * the current color to the specified XOR color.
+     * <br> <br>
+     * 
+     * @param color the new XOR mode
+     */
+    public abstract void setXORMode(Color color);
+
+    /**
+     * Translates the origin of Graphics current coordinate system 
+     * to the point with X, Y coordinates in the current coordinate system.
+     * All rendering operation in this Graphics will be related to the new origin.
+     * 
+     * @param x the X coordinate of the origin
+     * @param y the Y coordinate of the origin
+     */
+    public abstract void translate(int x, int y);
+}
diff --git a/awt/java/awt/Graphics2D.java b/awt/java/awt/Graphics2D.java
new file mode 100644
index 0000000..2ff5e0c
--- /dev/null
+++ b/awt/java/awt/Graphics2D.java
@@ -0,0 +1,456 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.font.GlyphVector;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * The Graphics2D class extends Graphics class and provides more capabilities
+ * for rendering text, images, shapes. This provides methods to peform 
+ * transformation of coordinate system, color management, and text layout. 
+ * The following attributes exist for rendering:
+ * <ul>
+ * <li>Color - current Graphics2D color;</li>
+ * <li>Font - current Graphics2D font;</li>
+ * <li>Stroke - pen with a width of 1 pixel;</li>  
+ * <li>Transform - current Graphics2D Transformation;</li>
+ * <li>Composite - alpha compositing rules for combining source and destination colors.</li>
+ * </ul> 
+ */
+public abstract class Graphics2D extends Graphics {
+    
+    /**
+     * Instantiates a new Graphics2D object. This constructor should never be
+     * called directly.
+     */
+    protected Graphics2D() {
+        super();
+    }
+
+    /**
+     * Adds preferences for the rendering algorithms. The preferences
+     * are arbitrary and specified by Map objects. All specified by Map object
+     * preferencies can be modified. 
+     * 
+     * @param hints the rendering hints.
+     */
+    public abstract void addRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Intersects the current clipping area with the specified Shape 
+     * and the result becomes a new clipping area. 
+     * If current clipping area is not defined, the Shape 
+     * becomes the new clipping area. No rendering operations 
+     * are allowed outside the clipping area.  
+     * 
+     * @param s the specified Shape object which will be intersected 
+     * with current clipping area.
+     */
+    public abstract void clip(Shape s);
+
+    /**
+     * Draws the outline of the specified Shape.
+     * 
+     * @param s the Shape which ouline is drawn.
+     */
+    public abstract void draw(Shape s);
+
+    /**
+     * Draws the specified GlyphVector object's text at the point x, y. 
+     * 
+     * @param g the GlyphVector object to be drawn.
+     * @param x the X position where the GlyphVector's text should 
+     * be rendered.  
+     * @param y the Y position where the GlyphVector's text should 
+     * be rendered.
+     */
+    public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+
+    /**
+     * Draws the BufferedImage -- modified according to the operation
+     * BufferedImageOp -- at the point x, y.
+     * 
+     * @param img the BufferedImage to be rendered.
+     * @param op the filter to be applied to the image before rendering. 
+     * @param x the X coordinate of the point where the image's upper left corner
+     * will be placed.
+     * @param y the Y coordinate of the point where the image's upper left corner
+     * will be placed.
+     */
+    public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y);
+
+    /**
+     * Draws BufferedImage transformed from image space into user space 
+     * according to the AffineTransform xform and notifies the ImageObserver.
+     *  
+     * @param img the BufferedImage to be rendered.
+     * @param xform the affine transformation from the image to the user space.
+     * @param obs the ImageObserver to be notified about the image conversion.
+     * 
+     * @return true, if the image is successfully loaded and rendered, 
+     * or it's null, otherwise false.
+     */
+    public abstract boolean drawImage(Image img, AffineTransform xform, ImageObserver obs);
+
+    /**
+     * Draws a RenderableImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderableImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderableImage(RenderableImage img, AffineTransform xform);
+
+    /**
+     * Draws a RenderedImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderedImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderedImage(RenderedImage img, AffineTransform xform);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, float x, float y);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     * 
+     * @see java.awt.Graphics#drawString(AttributedCharacterIterator, int, int)
+     */
+    @Override
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws the String whose the first character position is specified 
+     * by the parameters X, Y.   
+     * 
+     * @param s the String to be drawn.
+     * @param x the X position of the first character. 
+     * @param y the Y position of the first character.
+     */
+    public abstract void drawString(String s, float x, float y);
+
+    /**
+     * Draws the String whose the first character coordinates are specified 
+     * by the parameters X, Y.   
+     * 
+     * @param str the String to be drawn.
+     * @param x the X coordinate of the first character. 
+     * @param y the Y coordinate of the first character.
+     * 
+     * @see java.awt.Graphics#drawString(String, int, int)
+     */
+    @Override
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the interior of the specified Shape.
+     * 
+     * @param s the Shape to be filled.
+     */
+    public abstract void fill(Shape s);
+
+    /**
+     * Gets the background color.
+     * 
+     * @return the current background color.
+     */
+    public abstract Color getBackground();
+
+    /**
+     * Gets the current composite of the Graphics2D.
+     * 
+     * @return the current composite which specifies the compositing style.
+     */
+    public abstract Composite getComposite();
+
+    /**
+     * Gets the device configuration.
+     * 
+     * @return the device configuration
+     */
+    public abstract GraphicsConfiguration getDeviceConfiguration();
+
+    /**
+     * Gets the rendering context of the Font.
+     * 
+     * @return the FontRenderContext.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets the current Paint of Graphics2D.
+     * 
+     * @return the current Paint of Graphics2D.
+     */
+    public abstract Paint getPaint();
+
+    /**
+     * Gets the value of single preference for specified key. 
+     * 
+     * @param key the specified key of the rendering hint.
+     * 
+     * @return the value of rendering hint for specified key.
+     */
+    public abstract Object getRenderingHint(RenderingHints.Key key);
+
+    /**
+     * Gets the set of the rendering preferences as a collection of 
+     * key/value pairs.
+     * 
+     * @return the RenderingHints which contains the rendering preferences.
+     */
+    public abstract RenderingHints getRenderingHints();
+
+    /**
+     * Gets current stroke of the Graphics2D.
+     * 
+     * @return current stroke of the Graphics2D.
+     */
+    public abstract Stroke getStroke();
+
+    /**
+     * Gets current affine transform of the Graphics2D.
+     * 
+     * @return current AffineTransform of the Graphics2D.
+     */
+    public abstract AffineTransform getTransform();
+
+    /**
+     * Determines wether or not the specified Shape intersects the specified 
+     * Rectangle. If the onStroke parameter is true, this method 
+     * checks whether or not the specified Shape outline intersects the specified 
+     * Rectangle, otherwise this method checks whether or not the specified 
+     * Shape's interior intersects the specified Rectangle.   
+     * 
+     * @param rect the specified Rectangle.
+     * @param s the Shape to check for intersection.
+     * @param onStroke the parameter determines whether or not this method checks
+     * for intersection of the Shape outline or of the Shape interior with 
+     * the Rectangle. 
+     * 
+     * @return true, if there is a hit, otherwise false.
+     */
+    public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
+
+    /**
+     * Performs a rotation transform relative to current Graphics2D Transform.
+     * The coordinate system is rotated by the specified angle in radians relative to 
+     * current origin.
+     * 
+     * @param theta the angle of rotation in radians.
+     */
+    public abstract void rotate(double theta);
+
+    /**
+     * Performs a translated rotation transform relative to current Graphics2D 
+     * Transform. The coordinate system is rotated by the specified angle in radians 
+     * relative to current origin and then moved to point (x, y).
+     * 
+     * Is this right?
+     * 
+     * @param theta the angle of rotation in radians.
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     */
+    public abstract void rotate(double theta, double x, double y);
+
+    /**
+     * Performs a linear scale transform relative to current Graphics2D Transform.
+     * The coordinate system is rescaled vertically and horizontally 
+     * by the specified parameters.
+     * 
+     * @param sx the scaling factor by which the X coordinate is multiplied.   
+     * @param sy the scaling factor by which the Y coordinate is multiplied.   
+     */
+    public abstract void scale(double sx, double sy);
+
+    /**
+     * Sets a new background color for clearing rectangular areas. 
+     * The clearRect method uses the current background color. 
+     * 
+     * @param color the new background color.
+     */
+    public abstract void setBackground(Color color);
+
+    /**
+     * Sets the current composite for Graphics2D. 
+     * 
+     * @param comp the Composite object.
+     */
+    public abstract void setComposite(Composite comp);
+
+    /**
+     * Sets the paint for Graphics2D.
+     * 
+     * @param paint the Paint object.
+     */
+    public abstract void setPaint(Paint paint);
+
+    /**
+     * Sets a key-value pair in the current RenderingHints map.
+     * 
+     * @param key the key of the rendering hint to set.
+     * @param value the value to set for the rendering hint.
+     */
+    public abstract void setRenderingHint(RenderingHints.Key key, Object value);
+
+    /**
+     * Replaces the current rendering hints with the specified rendering preferences.
+     * 
+     * @param hints the new Map of rendering hints.
+     */
+    public abstract void setRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Sets the stroke for the Graphics2D.
+     * 
+     * @param s the Stroke object.
+     */
+    public abstract void setStroke(Stroke s);
+
+    /**
+     * Overwrite the current Transform of the Graphics2D. The specified Transform 
+     * should be received from the getTransform() method and should be used 
+     * only for restoring the original Graphics2D transform after calling
+     * draw or fill methods. 
+     * 
+     * @param Tx the specified Transform.
+     */
+    public abstract void setTransform(AffineTransform Tx);
+
+    /**
+     * Performs a shear transform relative to current Graphics2D Transform.
+     * The coordinate system is shifted by the specified multipliers relative to 
+     * current position.
+     * 
+     * @param shx the multiplier by which the X coordinates shift position
+     * along X axis as a function of Y coordinates.   
+     * @param shy the multiplier by which the Y coordinates shift position
+     * along Y axis as a function of X coordinates.   
+     */
+    public abstract void shear(double shx, double shy);
+
+    /**
+     * Concatenates the AffineTransform object with current Transform 
+     * of this Graphics2D. The transforms are applied in reverse order
+     * with the last specified transform applied first and the next
+     * transformation applied to the result of previous transformation. 
+     * More precisely, if Cx is the current Graphics2D transform, the 
+     * transform method's result with Tx as the parameter
+     * is the transformation Rx, where Rx(p) = Cx(Tx(p)), for p - a point
+     * in current coordinate system. Rx becomes the current Transform   
+     * for this Graphics2D.
+     * 
+     * @param Tx the AffineTransform object to be concatenated with 
+     * current Transform.
+     */
+    public abstract void transform(AffineTransform Tx);
+
+    /**
+     * Performs a translate transform relative to current Graphics2D Transform.
+     * The coordinate system is moved by the specified distance relative 
+     * to current position.
+     * 
+     * @param tx the translation distance along the X axis.
+     * @param ty the translation distance along the Y axis.
+     */
+    public abstract void translate(double tx, double ty);
+
+    /**
+     * Moves the origin Graphics2D Transform to the point with x, y
+     * coordinates in current coordinate system. The new origin of coordinate 
+     * system is moved to the (x, y) point accordingly. All rendering and 
+     * transform operations are performed relative to this new origin.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     * 
+     * @see java.awt.Graphics#translate(int, int)
+     */
+    @Override
+    public abstract void translate(int x, int y);
+
+    /**
+     * Fills a 3D rectangle with the current color. 
+     * The rectangle is specified by its width, height, and top left corner 
+     * coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     * 
+     * @see java.awt.Graphics#fill3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.fill3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.fill3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     *       
+     * @see java.awt.Graphics#draw3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.draw3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.draw3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/GraphicsConfiguration.java b/awt/java/awt/GraphicsConfiguration.java
new file mode 100644
index 0000000..8bec253
--- /dev/null
+++ b/awt/java/awt/GraphicsConfiguration.java
@@ -0,0 +1,217 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsConfiguration class contains the characteristics of graphics
+ * devices such as a printer or monitor, and represents device's capabilities
+ * and modes. Many GraphicsConfiguration objects can be associated with
+ * single graphics device.
+ */
+public abstract class GraphicsConfiguration {
+   
+   /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+    */
+
+    protected GraphicsConfiguration() {
+    }
+
+
+   /**
+    * Creates BufferedImage image object with a data layout and color model 
+    * compatible with this GraphicsConfiguration with specified width 
+    * and height parameters.
+    * 
+    * @param width the width of BufferedImage.
+    * @param height the height of BufferedImage.
+    * 
+    * @return the BufferedImage object with specified width and height 
+    * parameters.
+    */
+    public abstract BufferedImage createCompatibleImage(int width, int height);
+
+    /**
+     * Creates a BufferedImage that has the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height  of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the BufferedImage object.
+     */
+    public abstract BufferedImage createCompatibleImage(int width, int height, int transparency);
+
+    /**
+     * Creates a VolatileImage that has the specified width and height 
+     * and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height);
+
+    /**
+     * Creates a VolatileImage that supports the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height, int transparency);
+
+    /**
+     * Gets the bounds of area covered by the GraphicsConfiguration in the
+     * device coordinates space.
+     * 
+     * @return the Rectangle of GraphicsConfiguration's bounds.
+     */
+    public abstract Rectangle getBounds();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration.
+     * 
+     * @return the ColorModel object of the GraphicsConfiguration.
+     */
+    public abstract ColorModel getColorModel();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     * 
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     */
+    public abstract ColorModel getColorModel(int transparency);
+
+    /**
+     * Gets the default AffineTransform of the GraphicsConfiguration.
+     * This method translates user coordinates to device coordinates.
+     * 
+     * @return the default AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getDefaultTransform();
+
+    /**
+     * Gets the GraphicsDevice of the GraphicsConfiguration.
+     * 
+     * @return the GraphicsDevice of the GraphicsConfiguration.
+     */
+    public abstract GraphicsDevice getDevice();
+
+    /**
+     * Gets the normalizing AffineTransform of the GraphicsConfiguration.
+     * 
+     * @return the normalizing AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getNormalizingTransform();
+
+
+    /**
+     * Creates VolatileImage with specified width, height, ImageCapabilities;
+     * a data layout and color model compatible with this GraphicsConfiguration. 
+     *  
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Creates a VolatileImage with specified width, height, transparency 
+     * and ImageCapabilities; a data layout and color model compatible with 
+     * this GraphicsConfiguration.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps, int transparency) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height, transparency);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Gets the buffering capabilities of the GraphicsConfiguration.
+     * 
+     * @return the BufferCapabilities object. 
+     */
+    public BufferCapabilities getBufferCapabilities() {
+        return new BufferCapabilities(new ImageCapabilities(false), new ImageCapabilities(false),
+                BufferCapabilities.FlipContents.UNDEFINED);
+    }
+
+    /**
+     * Gets the image capabilities of the GraphicsConfiguration.
+     * 
+     * @return the ImageCapabilities object.
+     */
+    public ImageCapabilities getImageCapabilities() {
+        return new ImageCapabilities(false);
+    }
+}
diff --git a/awt/java/awt/GraphicsDevice.java b/awt/java/awt/GraphicsDevice.java
new file mode 100644
index 0000000..8cf700a
--- /dev/null
+++ b/awt/java/awt/GraphicsDevice.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsDevice class describes the graphics devices (such as screens 
+ * or printers) which are available in a particular graphics environment. 
+ * Many GraphicsDevice instances can be associated with a single
+ * GraphicsEnvironment. Each GraphicsDevice has one or more GraphicsConfiguration
+ * objects which specify the different configurations and modes of GraphicsDevice.
+ */
+public abstract class GraphicsDevice {
+    
+    /** The display mode. */
+    private DisplayMode displayMode;
+
+    //???AWT
+//    private Window fullScreenWindow = null;
+
+   /** The Constant TYPE_IMAGE_BUFFER indicates a image buffer device. */
+
+    public static final int TYPE_IMAGE_BUFFER = 2;
+
+    /** The Constant TYPE_PRINTER indicates a printer device. */
+    public static final int TYPE_PRINTER = 1;
+
+    /** The Constant TYPE_RASTER_SCREEN indicates a raster screen device. */
+    public static final int TYPE_RASTER_SCREEN = 0;
+
+   /**
+    * Constructor is not to be used directly as this class is abstract. 
+    */
+    protected GraphicsDevice() {
+        displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN);
+    }
+
+
+   /**
+    * Returns an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.  
+    * 
+    * @return an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.
+    */
+    public abstract GraphicsConfiguration[] getConfigurations();
+
+    /**
+     * Gets the default configuration for the GraphicsDevice.
+     * 
+     * @return the default GraphicsConfiguration object for the GraphicsDevice.
+     */
+    public abstract GraphicsConfiguration getDefaultConfiguration();
+
+    /**
+     * Gets the String identifier which associated with the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     * 
+     * @return the String identifier of the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     */
+    public abstract String getIDstring();
+
+    /**
+     * Gets the type of this GraphicsDevice: 
+     * TYPE_IMAGE_BUFFER, TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     * 
+     * @return the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, 
+     * TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     */
+    public abstract int getType();
+
+
+
+   /**
+	* Returns the number of bytes available in accelerated 
+	* memory on this device. 
+    * 
+    * @return the number of bytes available accelerated memory.
+    */
+    public int getAvailableAcceleratedMemory() {
+        return 0;
+    }
+
+    /* ???AWT
+    public GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate gct) {
+        return gct.getBestConfiguration(getConfigurations());
+    }
+    */
+    
+    /**
+     * Gets the current display mode of the GraphicsDevice.
+     * 
+     * @return the current display mode of the GraphicsDevice.
+     */
+    public DisplayMode getDisplayMode() {
+        return displayMode;
+    }
+
+    /**
+     * Gets an array of display modes available in this GraphicsDevice.
+     * 
+     * @return an array of display modes available in this GraphicsDevice.
+     */
+    public DisplayMode[] getDisplayModes() {
+        DisplayMode []dms = {displayMode};
+        return  dms;
+    }
+
+    /* ???AWT
+    public Window getFullScreenWindow() {
+        return fullScreenWindow;
+    }
+    */
+    
+    /**
+     * Returns true if this GraphicsDevice supports low-level 
+     * display changes.
+     * 
+     * @return true, if this GraphicsDevice supports low-level 
+     * display changes; false otherwise.
+     */
+    public boolean isDisplayChangeSupported() {
+        return false;
+    }
+
+    /**
+     * Returns true if this GraphicsDevice supports full screen
+     * mode.
+     * 
+     * @return true, if this GraphicsDevice supports full screen
+     * mode; otherwise false.
+     */
+    public boolean isFullScreenSupported() {
+        return false;
+    }
+    //an array of display modes available in this GraphicsDevice.
+    
+    /**
+     * Sets the display mode of this GraphicsDevice.
+     * 
+     * @param dm the new display mode of this GraphicsDevice. 
+     */
+    public void setDisplayMode(DisplayMode dm) {
+        if (!isDisplayChangeSupported()) {
+            // awt.122=Does not support display mode changes
+            throw new UnsupportedOperationException(Messages.getString("awt.122")); //$NON-NLS-1$
+        }
+
+        DisplayMode []dms = getDisplayModes();
+        for (DisplayMode element : dms) {
+            if (element.equals(dm)) {
+                displayMode = dm;
+                return;
+            }
+        }
+        // awt.123=Unsupported display mode: {0}
+        throw new IllegalArgumentException(Messages.getString("awt.123", dm)); //$NON-NLS-1$
+    }
+
+    /* ???AWT
+    public void setFullScreenWindow(Window w) {
+        if (w == null) {
+            fullScreenWindow = null;
+            return;
+        }
+
+        fullScreenWindow = w;
+
+        if (isFullScreenSupported()) {
+            w.enableInputMethods(false);
+        } else {
+            w.setSize(displayMode.getWidth(), displayMode.getHeight());
+            w.setLocation(0, 0);
+        }
+        w.setVisible(true);
+        w.setAlwaysOnTop(true);
+    }
+    */
+}
diff --git a/awt/java/awt/GraphicsEnvironment.java b/awt/java/awt/GraphicsEnvironment.java
new file mode 100644
index 0000000..3b14f55
--- /dev/null
+++ b/awt/java/awt/GraphicsEnvironment.java
@@ -0,0 +1,209 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+/**
+ * The GraphicsEnvironment class defines a collection of GraphicsDevice 
+ * objects and Font objects which are available for Java application on
+ * current platform.
+ */
+public abstract class GraphicsEnvironment {
+    
+    /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+     */
+    protected GraphicsEnvironment() {}
+
+    /**
+     * Gets the local GraphicsEnvironment.
+     * 
+     * @return the local GraphicsEnvironment.
+     */
+    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
+        synchronized(ContextStorage.getContextLock()) {
+            if (ContextStorage.getGraphicsEnvironment() == null) {
+                if (isHeadless()) {                    
+                    ContextStorage.setGraphicsEnvironment(new HeadlessGraphicsEnvironment());                    
+                } else {
+                    CommonGraphics2DFactory g2df =
+                            (CommonGraphics2DFactory) Toolkit.getDefaultToolkit().getGraphicsFactory();
+                    
+                    ContextStorage.setGraphicsEnvironment( 
+                            g2df.createGraphicsEnvironment(ContextStorage.getWindowFactory())
+                    );
+                }
+            }
+
+            return ContextStorage.getGraphicsEnvironment();
+        }
+    }
+
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    public boolean isHeadlessInstance() {
+        return false;
+    }
+
+    /**
+     * Checks whether or not a display, keyboard, and mouse are supported 
+     * in this environment. 
+     * 
+     * @return true, if a HeadlessException is thrown from areas of 
+     * the Toolkit and GraphicsEnvironment that are dependent on 
+     * a display, keyboard, or mouse; false otherwise.
+     */
+    public static boolean isHeadless() {
+        return "true".equals(System.getProperty("java.awt.headless"));
+    }
+
+    /**
+     * Gets the maximum bounds of system centered windows.
+     * 
+     * @return the maximum bounds of system centered windows.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Rectangle getMaximumWindowBounds() throws HeadlessException {
+        return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+    }
+
+    /**
+     * Gets the Point which should defines the center of system window.
+     * 
+     * @return the Point where the system window should be centered.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Point getCenterPoint() throws HeadlessException {
+        Rectangle mwb = getMaximumWindowBounds();
+        return new Point(mwb.width >> 1, mwb.height >> 1);
+    }
+
+    /**
+     * Indicates that the primary font should be used. 
+     * Primary font is specified by initial system locale or default encoding).
+     * 
+     */
+    public void preferLocaleFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Indicates that a proportional preference of the font should be used.
+     */
+    public void preferProportionalFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Creates the Graphics2D object for rendering to the specified
+     * BufferedImage.
+     * 
+     * @param bufferedImage the BufferedImage object.
+     * 
+     * @return the Graphics2D object which allows to render to the specified 
+     * BufferedImage.
+     */
+    public abstract Graphics2D createGraphics(BufferedImage bufferedImage);
+
+    /**
+     * Gets the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     * 
+     * @return the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     */
+    public abstract Font[] getAllFonts();
+
+    /**
+     * Gets the array of all available font family names.
+     * 
+     * @return the array of all available font family names.
+     */
+    public abstract String[] getAvailableFontFamilyNames();
+
+    /**
+     * Gets the array of all available font family names for the specified
+     * locale.
+     * 
+     * @param locale the Locale object which represents geographical
+     * region. The default locale is used if locale is null.
+     * 
+     * @return the array of available font family names for the specified 
+     * locale.
+     */
+    public abstract String[] getAvailableFontFamilyNames(Locale locale);
+
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice getDefaultScreenDevice() throws HeadlessException;
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice obgects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice[] getScreenDevices() throws HeadlessException;
+}
diff --git a/awt/java/awt/HeadlessException.java b/awt/java/awt/HeadlessException.java
new file mode 100644
index 0000000..28e463b
--- /dev/null
+++ b/awt/java/awt/HeadlessException.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The HeadlessException class provides notifications and error messages 
+ * when code that is dependent on a keyboard, display, or mouse is called 
+ * in an environment that does not support a keyboard, display, or mouse.
+ */
+public class HeadlessException extends UnsupportedOperationException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 167183644944358563L;
+
+    /**
+     * Instantiates a new headless exception.
+     */
+    public HeadlessException() {
+        super();
+    }
+
+    /**
+     * Instantiates a new headless exception with the specified message.
+     * 
+     * @param msg the String which represents error message. 
+     */
+    public HeadlessException(String msg) {
+        super(msg);
+    }
+}
diff --git a/awt/java/awt/HeadlessGraphicsEnvironment.java b/awt/java/awt/HeadlessGraphicsEnvironment.java
new file mode 100644
index 0000000..97f88d1
--- /dev/null
+++ b/awt/java/awt/HeadlessGraphicsEnvironment.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package java.awt;
+
+import java.awt.GraphicsDevice;
+import java.awt.HeadlessException;
+
+import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
+
+/**
+ * The HeadlessGraphicsEnvironment class is the CommonGraphicsEnvironment
+ * implementation to use in the case where the environment lacks display, 
+ * keyboard, and mouse support.
+ */
+public class HeadlessGraphicsEnvironment extends CommonGraphicsEnvironment {
+    
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    @Override
+    public boolean isHeadlessInstance() {
+        return true;
+    }
+    
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice objects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+}
diff --git a/awt/java/awt/HeadlessToolkit.java b/awt/java/awt/HeadlessToolkit.java
new file mode 100644
index 0000000..a7dd557
--- /dev/null
+++ b/awt/java/awt/HeadlessToolkit.java
@@ -0,0 +1,301 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+//???AWT
+//import java.awt.datatransfer.Clipboard;
+//import java.awt.dnd.DragGestureEvent;
+//import java.awt.dnd.DragGestureListener;
+//import java.awt.dnd.DragGestureRecognizer;
+//import java.awt.dnd.DragSource;
+//import java.awt.dnd.InvalidDnDOperationException;
+//import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+//import java.awt.peer.*;
+//import java.beans.PropertyChangeSupport;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.ComponentInternals;
+//import org.apache.harmony.awt.datatransfer.DTK;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+/**
+ * The HeadlessToolkit class is a subclass of ToolkitImpl to 
+ * be used for graphical environments that lack keyboard and 
+ * mouse capabilities.
+ */
+public final class HeadlessToolkit extends ToolkitImpl {
+    
+    //???AWT
+    /*
+    @Override
+    protected ButtonPeer createButton(Button a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected CheckboxPeer createCheckbox(Checkbox a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected ChoicePeer createChoice(Choice a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+    throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected DialogPeer createDialog(Dialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> recognizerAbstractClass, DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl) {
+        return null;
+    }
+
+    @Override
+    public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge)
+    throws InvalidDnDOperationException {
+        throw new InvalidDnDOperationException();
+    }
+
+    @Override
+    protected FileDialogPeer createFileDialog(FileDialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected FramePeer createFrame(Frame a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected LabelPeer createLabel(Label a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ListPeer createList(List a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuPeer createMenu(Menu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuBarPeer createMenuBar(MenuBar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuItemPeer createMenuItem(MenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected PopupMenuPeer createPopupMenu(PopupMenu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollbarPeer createScrollbar(Scrollbar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollPanePeer createScrollPane(ScrollPane a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextAreaPeer createTextArea(TextArea a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextFieldPeer createTextField(TextField a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected WindowPeer createWindow(Window a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public ColorModel getColorModel() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMaximumCursorColors() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    NativeEventQueue getNativeEventQueue() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, JobAttributes jobAttributes, 
+            PageAttributes pageAttributes) throws IllegalArgumentException {
+        throw new IllegalArgumentException();        
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) throws NullPointerException  {
+        throw new NullPointerException();
+    }
+    */
+
+    @Override
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+
+    @Override
+    public Dimension getScreenSize() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    public Clipboard getSystemClipboard() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+    
+    @Override
+    public Clipboard getSystemSelection() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    WindowFactory getWindowFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            //???AWT: new EventQueue(this); // create the system EventQueue
+            //???AWT: dispatcher = new Dispatcher(this);
+            desktopProperties = new HashMap<String, Object>();
+            //???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
+//          ???AWT: awtEventsManager = new AWTEventsManager();
+//          ???AWT: dispatchThread = new HeadlessEventDispatchThread(this, dispatcher);            
+//          ???AWT: dtk = DTK.getDTK();
+            dispatchThread.start();            
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected void loadSystemColors(int[] systemColors) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+}
diff --git a/awt/java/awt/IllegalComponentStateException.java b/awt/java/awt/IllegalComponentStateException.java
new file mode 100644
index 0000000..21dc35f
--- /dev/null
+++ b/awt/java/awt/IllegalComponentStateException.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The IllegalComponentStateException class is used to provide 
+ * notification that AWT component is not in an appropriate state 
+ * for the requested operation.
+ */
+public class IllegalComponentStateException extends IllegalStateException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1889339587208144238L;
+
+    /**
+     * Instantiates a new IllegalComponentStateException with
+     * the specified message.
+     * 
+     * @param s the String message which describes the exception.
+     */
+    public IllegalComponentStateException(String s) {
+        super(s);
+    }
+
+    /**
+     * Instantiates a new IllegalComponentStateException without
+     * detailed message.
+     */
+    public IllegalComponentStateException() {
+    }
+
+}
+
diff --git a/awt/java/awt/Image.java b/awt/java/awt/Image.java
new file mode 100644
index 0000000..c217e38
--- /dev/null
+++ b/awt/java/awt/Image.java
@@ -0,0 +1,203 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.AreaAveragingScaleFilter;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageFilter;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.ReplicateScaleFilter;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Image abstract class represents the graphic images. 
+ */
+public abstract class Image {
+
+    /** 
+     * The UndefinedProperty object should be returned if
+     * property is not defined for a particular image. 
+     */
+    public static final Object UndefinedProperty = new Object();  //$NON-LOCK-1$
+
+    /** 
+     * The Constant SCALE_DEFAULT indicates the default image
+     * scaling algorithm. 
+     */
+    public static final int SCALE_DEFAULT = 1;
+
+    /** 
+     * The Constant SCALE_FAST indicates an image scaling algorithm which 
+     * places a higher priority on scaling speed than on the image's smoothness. 
+     */
+    public static final int SCALE_FAST = 2;
+
+    /** 
+     * The Constant SCALE_SMOOTH indicates an image scaling algorithm which 
+     * places a higher priority on image smoothness than on scaling speed. 
+     */
+    public static final int SCALE_SMOOTH = 4;
+
+    /** 
+     * The Constant SCALE_REPLICATE indicates the image scaling 
+     * algorithm in the ReplicateScaleFilter class. 
+     */
+    public static final int SCALE_REPLICATE = 8;
+
+    /** 
+     * The Constant SCALE_AREA_AVERAGING indicates  
+     * the area averaging image scaling algorithm. 
+     */
+    public static final int SCALE_AREA_AVERAGING = 16;
+
+    /** 
+     * The acceleration priority indicates image acceleration.   
+     */
+    protected float accelerationPriority = 0.5f;
+
+    /** The Constant capabilities. */
+    private static final ImageCapabilities capabilities = new ImageCapabilities(false);
+
+    /**
+     * Gets the image property with the specified name.
+     * The UndefinedProperty object should be return if the property is 
+     * not specified for this image.  The return value should be null if the
+     * property is currently unknown yet and the specified ImageObserver is
+     * to be notified later. 
+     * 
+     * @param name the name of image's property.
+     * @param observer the ImageObserver.
+     * 
+     * @return the Object which represents value of the specified property.
+     */
+    public abstract Object getProperty(String name, ImageObserver observer);
+
+    /**
+     * Gets the ImageProducer object which represents data of this Image.
+     * 
+     * @return the ImageProducer object which represents data of this Image.
+     */
+    public abstract ImageProducer getSource();
+
+    /**
+     * Gets the width of this image. The specified ImageObserver object 
+     * is notified when the width of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the width of this image is available.
+     * 
+     * @return the width of image, or -1 if the width of this image 
+     * is not available.
+     */
+    public abstract int getWidth(ImageObserver observer);
+
+    /**
+     * Gets the height of this image. The specified ImageObserver object 
+     * is notified when the height of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the height of this image is available.
+     * 
+     * @return the height of image, or -1 if the height of this image 
+     * is not available.
+     */
+    public abstract int getHeight(ImageObserver observer);
+
+    /**
+     * Gets the scaled instance of this Image. This method returns 
+     * an Image object constructed from the source of this image 
+     * with the specified width, height, and applied scaling
+     * alghorithm.
+     * 
+     * @param width the width of scaled Image. 
+     * @param height the height of scaled Image.
+     * @param hints the constant which indicates scaling algorithm. 
+     * 
+     * @return the scaled Image.
+     */
+    public Image getScaledInstance(int width, int height, int hints) {
+        ImageFilter filter;
+        if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
+            filter = new AreaAveragingScaleFilter(width, height);
+        } else {
+            filter = new ReplicateScaleFilter(width, height);
+        }
+        ImageProducer producer = new FilteredImageSource(getSource(), filter);
+        return Toolkit.getDefaultToolkit().createImage(producer);
+    }
+
+    /**
+     * Gets a Graphics object for rendering this image. 
+     * This method can be used for off-screen images.
+     * 
+     * @return a Graphics object for rendering to this image.
+     */
+    public abstract Graphics getGraphics();
+
+    /**
+     * Flushes resources which are used by this Image object. 
+     * This method resets the image to the reconstructered state
+     * from the image's source.
+     */
+    public abstract void flush();
+
+    /**
+     * Gets the acceleration priority of this image.
+     * 
+     * @return the acceleration priority of this image.
+     */
+    public float getAccelerationPriority() {
+        return accelerationPriority;
+    }
+
+    /**
+     * Sets the acceleration priority for this image.  
+     *  
+     * @param priority the new acceleration priority (value in the
+     * range 0-1).
+     */
+    public void setAccelerationPriority(float priority) {
+        if (priority < 0 || priority > 1) {
+            // awt.10A=Priority must be a value between 0 and 1, inclusive
+            throw new IllegalArgumentException(Messages.getString("awt.10A")); //$NON-NLS-1$
+        }
+        accelerationPriority = priority;
+    }
+
+    /**
+     * Gets an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration. 
+     * 
+     * @param gc the specified GraphicsConfiguration object 
+     * (null value means default GraphicsConfiguration).
+     * 
+     * @return an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration.
+     */
+    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+        // Note: common image is not accelerated.
+        return capabilities;
+    }
+}
+
+
diff --git a/awt/java/awt/ImageCapabilities.java b/awt/java/awt/ImageCapabilities.java
new file mode 100644
index 0000000..6e9ecfc
--- /dev/null
+++ b/awt/java/awt/ImageCapabilities.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The ImageCapabilities class gives information about an image's capabilities.
+ */
+public class ImageCapabilities implements Cloneable {
+    
+    /** The accelerated. */
+    private final boolean accelerated;
+
+    /**
+     * Instantiates a new ImageCapabilities with the specified
+     * acceleration flag which indicates whether acceleration
+     * is desired or not.
+     * 
+     * @param accelerated the accelerated flag.
+     */
+    public ImageCapabilities(boolean accelerated) {
+        this.accelerated = accelerated;
+    }
+
+    /**
+     * Returns a copy of this ImageCapabilities object.
+     * 
+     * @return the copy of this ImageCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new ImageCapabilities(accelerated);
+    }
+
+    /**
+     * Returne true if the Image of this ImageCapabilities is or can be
+     * accelerated.
+     *  
+     * @return true, if the Image of this ImageCapabilities is or can be
+     * accelerated, false otherwise.
+     */
+    public boolean isAccelerated() {
+        return accelerated;
+    }
+
+    /**
+     * Returns true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces.
+     * 
+     * @return true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces, 
+     * false otherwise.
+     */
+    public boolean isTrueVolatile() {
+        return true;
+    }
+}
diff --git a/awt/java/awt/Insets.java b/awt/java/awt/Insets.java
new file mode 100644
index 0000000..61f3fd8
--- /dev/null
+++ b/awt/java/awt/Insets.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Insets class represents the borders of a container. 
+ * This class describes the space that a container should leave at each edge:
+ * the top, the bottom, the right side, and the left side. 
+ * The space can be filled with a border, a blank space, or a title.
+ */
+public class Insets implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -2272572637695466749L;
+
+    /**
+     * The top inset indicates the size of the space added to the 
+     * top of the rectangle.
+     */
+    public int top;
+
+    /** 
+     * The left inset indicates the size of the space added to the 
+     * left side of the rectangle.
+     */
+    public int left;
+
+    /** 
+     * The bottom inset indicates the size of the space subtracted from 
+     * the bottom of the rectangle.
+     */
+    public int bottom;
+
+    /** The right inset indicates the size of the space subtracted from 
+     * the right side of the rectangle. 
+     */
+    public int right;
+
+    /**
+     * Instantiates a new Inset object with the specified top, left, bottom,
+     * right parameters.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public Insets(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Returns a hash code of the Insets object.
+     * 
+     * @return a hash code of the Insets object.
+     */
+    @Override
+    public int hashCode() {
+        int hashCode = HashCode.EMPTY_HASH_CODE;
+        hashCode = HashCode.combine(hashCode, top);
+        hashCode = HashCode.combine(hashCode, left);
+        hashCode = HashCode.combine(hashCode, bottom);
+        hashCode = HashCode.combine(hashCode, right);
+        return hashCode;
+    }
+
+    /**
+     * Returns a copy of this Insets object.
+     * 
+     * @return a copy of this Insets object.
+     */
+    @Override
+    public Object clone() {
+        return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * Checks if this Insets object is equal to the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is an Insets object whose data values
+     * are equal to those of this object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof Insets) {
+            Insets i = (Insets) o;
+            return ((i.left == left) && (i.bottom == bottom) &&
+                    (i.right == right) && (i.top == top));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a String representation of this Insets object.
+     * 
+     * @return a String representation of this Insets object.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * System.out.println(new Insets(1, 2, 3, 4));
+         */
+
+        return (getClass().getName() +
+                "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
+                ",right=" + right + ",bottom="  + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets top, left, bottom, and right insets to the specified values.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public void set(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Sets the values.
+     * 
+     * @param top the top
+     * @param left the left
+     * @param bottom the bottom
+     * @param right the right
+     */
+    private void setValues(int top, int left, int bottom, int right) {
+        this.top = top;
+        this.left = left;
+        this.bottom = bottom;
+        this.right = right;
+    }
+}
+
diff --git a/awt/java/awt/ItemSelectable.java b/awt/java/awt/ItemSelectable.java
new file mode 100644
index 0000000..a46364b
--- /dev/null
+++ b/awt/java/awt/ItemSelectable.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ItemListener;
+
+/**
+ * The ItemSelectable interface represents a set of items which can be selected.
+ */
+public interface ItemSelectable {
+
+    /**
+     * Adds an ItemListener for receiving item events when the state of an item 
+     * is changed by the user. 
+     * 
+     * @param l the ItemListener.
+     */
+    public void addItemListener(ItemListener l);
+
+    /**
+     * Gets an array of the selected objects or null if there is no selected object.
+     * 
+     * @return an array of the selected objects or null if there is no selected 
+     * object.
+     */
+    public Object[] getSelectedObjects();
+
+    /**
+     * Removes the specified ItemListener.
+     * 
+     * @param l the ItemListener which will be removed.
+     */
+    public void removeItemListener(ItemListener l);
+
+}
diff --git a/awt/java/awt/MenuComponent.java b/awt/java/awt/MenuComponent.java
new file mode 100644
index 0000000..9eb4f3d
--- /dev/null
+++ b/awt/java/awt/MenuComponent.java
@@ -0,0 +1,1041 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.awt.peer.MenuComponentPeer;
+import java.io.Serializable;
+import java.util.Locale;
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleSelection;
+//import javax.accessibility.AccessibleStateSet;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.state.MenuItemState;
+import org.apache.harmony.awt.state.MenuState;
+
+/**
+ * The MenuComponent abstract class is the superclass for menu 
+ * components. Menu components receive and process AWT events.
+ */
+public abstract class MenuComponent implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4536902356223894379L;
+
+    /** The name. */
+    private String name;
+
+    /** The font. */
+    private Font font;
+
+    /** The parent. */
+    MenuContainer parent;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The selected item index. */
+    private int selectedItemIndex;
+
+    //???AWT: private AccessibleContext accessibleContext;
+
+    /** The toolkit. */
+    final Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTMenuComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent, AccessibleSelection {
+        private static final long serialVersionUID = -4269533416223798698L;
+
+        public void addFocusListener(FocusListener listener) {
+        }
+
+        public boolean contains(Point pt) {
+            return false;
+        }
+
+        public Accessible getAccessibleAt(Point pt) {
+            return null;
+        }
+
+        public Color getBackground() {
+            return null;
+        }
+
+        public Rectangle getBounds() {
+            return null;
+        }
+
+        public Cursor getCursor() {
+            return null;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public FontMetrics getFontMetrics(Font font) {
+            return null;
+        }
+
+        public Color getForeground() {
+            return null;
+        }
+
+        public Point getLocation() {
+            return null;
+        }
+
+        public Point getLocationOnScreen() {
+            return null;
+        }
+
+        public Dimension getSize() {
+            return null;
+        }
+
+        public boolean isEnabled() {
+            return true; // always enabled
+        }
+
+        public boolean isFocusTraversable() {
+            return true; // always focus traversable
+        }
+
+        public boolean isShowing() {
+            return true;// always showing
+        }
+
+        public boolean isVisible() {
+            return true; // always visible
+        }
+
+        public void removeFocusListener(FocusListener listener) {
+        }
+
+        public void requestFocus() {
+        }
+
+        public void setBackground(Color color) {
+        }
+
+        public void setBounds(Rectangle rect) {
+        }
+
+        public void setCursor(Cursor cursor) {
+        }
+
+        public void setEnabled(boolean enabled) {
+        }
+
+        public void setFont(Font font) {
+            MenuComponent.this.setFont(font);
+        }
+
+        public void setForeground(Color color) {
+        }
+
+        public void setLocation(Point pt) {
+        }
+
+        public void setSize(Dimension pt) {
+        }
+
+        public void setVisible(boolean visible) {
+        }
+
+        public void addAccessibleSelection(int index) {
+        }
+
+        public void clearAccessibleSelection() {
+        }
+
+        public Accessible getAccessibleSelection(int index) {
+            return null;
+        }
+
+        public int getAccessibleSelectionCount() {
+            return 0;
+        }
+
+        public boolean isAccessibleChildSelected(int index) {
+            return false;
+        }
+
+        public void removeAccessibleSelection(int index) {
+        }
+
+        public void selectAllAccessibleSelection() {
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int index) {
+            return null;
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            return 0;
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription();
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = getAccessibleParent();
+                int aIndex = -1;
+                if (aParent instanceof MenuComponent) {
+                    MenuComponent parent = (MenuComponent) aParent;
+                    int count = parent.getItemCount();
+                    for (int i = 0; i < count; i++) {
+                        MenuComponent comp = parent.getItem(i);
+                        if (comp instanceof Accessible) {
+                            aIndex++;
+                            if (comp == MenuComponent.this) {
+                                return aIndex;
+                            }
+                        }
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public String getAccessibleName() {
+            return super.getAccessibleName();
+        }
+
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                MenuContainer parent = getParent();
+                if (parent instanceof Accessible) {
+                    aParent = (Accessible) parent;
+                }
+                return aParent;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            return AccessibleRole.AWT_COMPONENT;
+        }
+
+        @Override
+        public AccessibleSelection getAccessibleSelection() {
+            return this;
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            return new AccessibleStateSet();
+        }
+
+        @Override
+        public Locale getLocale() {
+            return Locale.getDefault();
+        }
+    }
+    */
+
+    /**
+     * The accessor to MenuComponent internal state,
+     * utilized by the visual theme.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    //???AWT
+    /*
+    class State implements MenuState {
+        Dimension size;
+
+        Dimension getSize() {
+            if (size == null) {
+                calculate();
+            }
+            return size;
+        }
+
+        public int getWidth() {
+            return getSize().width;
+        }
+
+        public int getHeight() {
+            return getSize().height;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public int getItemCount() {
+            return MenuComponent.this.getItemCount();
+        }
+
+        public int getSelectedItemIndex() {
+            return MenuComponent.this.getSelectedItemIndex();
+        }
+
+        public boolean isFontSet() {
+            return MenuComponent.this.isFontSet();
+        }
+
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics(Font f) {
+            return MenuComponent.this.toolkit.getFontMetrics(f);
+        }
+
+        public Point getLocation() {
+            return MenuComponent.this.getLocation();
+        }
+
+        public MenuItemState getItem(int index) {
+            MenuItem item = MenuComponent.this.getItem(index);
+            return item.itemState;
+        }
+
+        public void setSize(int w, int h) {
+            this.size = new Dimension(w, h);
+        }
+
+        void calculate() {
+            size = new Dimension();
+            size.setSize(toolkit.theme.calculateMenuSize(this));
+        }
+
+        void reset() {
+            for (int i = 0; i < getItemCount(); i++) {
+                ((MenuItem.State) getItem(i)).reset();
+            }
+        }
+
+    }
+    */
+    
+    /**
+     * Pop-up box for menu. It transfers the paint events, 
+     * keyboard and mouse events to the menu component itself
+     */
+    //???AWT
+    /*
+    class MenuPopupBox extends PopupBox {
+        private final Point lastMousePos = new Point();
+
+        @Override
+        boolean isMenu() {
+            return true;
+        }
+
+        @Override
+        void paint(Graphics gr) {
+            MenuComponent.this.paint(gr);
+        }
+
+        @Override
+        void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+            MenuComponent.this.onKeyEvent(eventId, vKey, when, modifiers);
+        }
+
+        @Override
+        void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers,
+                int wheelRotation) {
+            // prevent conflict of mouse and keyboard
+            // when sub-menu drops down due to keyboard navigation
+            if (lastMousePos.equals(where)
+                    && (eventId == MouseEvent.MOUSE_MOVED || eventId == MouseEvent.MOUSE_ENTERED)) {
+                return;
+            }
+            lastMousePos.setLocation(where);
+            MenuComponent.this.onMouseEvent(eventId, where, mouseButton, when, modifiers);
+        }
+    }
+    */
+    
+    /**
+     * Instantiates a new MenuComponent object.
+     * 
+     * @throws HeadlessException if the graphical interface
+     * environment can't support MenuComponents
+     */
+    public MenuComponent() throws HeadlessException {
+        toolkit.lockAWT();
+        try {
+            Toolkit.checkHeadless();
+            name = autoName();
+            selectedItemIndex = -1;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the name of the MenuComponent object.
+     * 
+     * @return the name of the MenuComponent object.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns a String representation of the MenuComponent object.
+     * 
+     * @return a String representation of the MenuComponent object.
+     */
+    @Override
+    public String toString() {
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Parent menu Container .
+     * 
+     * @return the parent
+     */
+    public MenuContainer getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the name of the MenuComponent to the specified string.
+     * 
+     * @param name the new name of the MenuComponent object. 
+     */
+    public void setName(String name) {
+        toolkit.lockAWT();
+        try {
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatches AWT event.
+     * 
+     * @param event the AWTEvent.
+     */
+    public final void dispatchEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            processEvent(event);
+            if (deprecatedEventHandler) {
+                postDeprecatedEvent(event);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param event the event
+     */
+    void postDeprecatedEvent(AWTEvent event) {
+        Event evt = event.getEvent();
+        if (evt != null) {
+            postEvent(evt);
+        }
+    }
+
+    /**
+     * Gets the peer of the MenuComponent; an application must not
+     * use this method directly.
+     * 
+     * @return the MenuComponentPeer object.
+     *
+     * @deprecated an application must not use this method directly.
+     */
+    @Deprecated
+    public MenuComponentPeer getPeer() throws org.apache.harmony.luni.util.NotImplementedException {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Gets the locking object of this MenuComponent.
+     * 
+     * @return the locking object of this MenuComponent.
+     */
+    protected final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * Posts the Event to the MenuComponent.
+     * 
+     * @param e the Event.
+     * 
+     * @return true, if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced dispatchEvent method.
+     */
+    @SuppressWarnings("deprecation")
+    @Deprecated
+    public boolean postEvent(Event e) {
+        toolkit.lockAWT();
+        try {
+            if (parent != null) {
+                return parent.postEvent(e);
+            }
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the string representation of the MenuComponent state.
+     * 
+     * @return returns the string representation of the MenuComponent
+     * state.
+     */
+    protected String paramString() {
+        toolkit.lockAWT();
+        try {
+            return getName();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Gets the font of the MenuComponent object.
+     * 
+     * @return the Font of the MenuComponent object.
+     */
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            if (font == null && hasDefaultFont()) {
+                return toolkit.getDefaultFont();
+            }
+            if (font == null && parent != null) {
+                return parent.getFont();
+            }
+            return font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if is font set.
+     * 
+     * @return true, if is font set
+     */
+    boolean isFontSet() {
+        return font != null
+                || ((parent instanceof MenuComponent) && ((MenuComponent) parent).isFontSet());
+    }
+
+    /**
+     * Checks for default font.
+     * 
+     * @return true, if successful
+     */
+    boolean hasDefaultFont() {
+        return false;
+    }
+
+    /**
+     * Processes an AWTEevent on this menu component.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void processEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            // do nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the peer of the MenuComponent.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the Font for this MenuComponent object.
+     * 
+     * @param font the new Font to be used for this MenuComponent.
+     */
+    public void setFont(Font font) {
+        toolkit.lockAWT();
+        try {
+            this.font = font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the parent.
+     * 
+     * @param parent the new parent
+     */
+    void setParent(MenuContainer parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Gets the location.
+     * 
+     * @return the location
+     */
+    Point getLocation() {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    int getWidth() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    int getHeight() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Recursively find the menu item for a menu shortcut.
+     * 
+     * @param gr the gr
+     * 
+     * @return the menu item;
+     * or null if the item is not available for this shortcut
+     */
+    //???AWT
+    /*
+    MenuItem getShortcutMenuItemImpl(MenuShortcut ms) {
+        if (ms == null) {
+            return null;
+        }
+        for (int i = 0; i < getItemCount(); i++) {
+            MenuItem mi = getItem(i);
+            if (mi instanceof Menu) {
+                mi = ((Menu) mi).getShortcutMenuItemImpl(ms);
+                if (mi != null) {
+                    return mi;
+                }
+            } else if (ms.equals(mi.getShortcut())) {
+                return mi;
+            }
+        }
+        return null;
+    }
+    */
+
+    void paint(Graphics gr) {
+        gr.setColor(Color.LIGHT_GRAY);
+        gr.fillRect(0, 0, getWidth(), getHeight());
+        gr.setColor(Color.BLACK);
+    }
+
+    /**
+     * Mouse events handler.
+     * 
+     * @param eventId - one of the MouseEvent.MOUSE_* constants
+     * @param where - mouse location
+     * @param mouseButton - mouse button that was pressed or released
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Keyboard event handler.
+     * 
+     * @param eventId - one of the KeyEvent.KEY_* constants
+     * @param vKey - the key code
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Post the ActionEvent or ItemEvent,
+     * depending on type of the menu item.
+     * 
+     * @param index the index
+     * 
+     * @return the item rect
+     */
+    //???AWT
+    /*
+    void fireItemAction(int item, long when, int modifiers) {
+        MenuItem mi = getItem(item);
+        mi.itemSelected(when, modifiers);
+    }
+
+    MenuItem getItem(int index) {
+        // to be overridden
+        return null;
+    }
+
+    int getItemCount() {
+        return 0;
+    }
+    */
+
+    /**
+     * @return The sub-menu of currently selecetd item, 
+     * or null if such a sub-menu is not available 
+     */
+    //???AWT
+    /*
+    Menu getSelectedSubmenu() {
+        if (selectedItemIndex < 0) {
+            return null;
+        }
+        MenuItem item = getItem(selectedItemIndex);
+        return (item instanceof Menu) ? (Menu) item : null;
+    }
+    */
+
+    /**
+     * Convenience method for selectItem(index, true)
+     */
+    //???AWT
+    /*
+    void selectItem(int index) {
+        selectItem(index, true);
+    }
+    */
+
+    /**
+     * Change the selection in the menu 
+     * @param index - new selecetd item's index
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectItem(int index, boolean showSubMenu) {
+        if (selectedItemIndex == index) {
+            return;
+        }
+        if (selectedItemIndex >= 0 && getItem(selectedItemIndex) instanceof Menu) {
+            ((Menu) getItem(selectedItemIndex)).hide();
+        }
+        MultiRectArea clip = getUpdateClip(index, selectedItemIndex);
+        selectedItemIndex = index;
+        Graphics gr = getGraphics(clip);
+        if (gr != null) {
+            paint(gr);
+        }
+        if (showSubMenu) {
+            showSubMenu(selectedItemIndex);
+        }
+    }
+    */
+
+    /**
+     * Change the selected item to the next one in the requested direction
+     * moving cyclically, skipping separators
+     * @param forward - the direction to move the selection
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectNextItem(boolean forward, boolean showSubMenu) {
+        int selected = getSelectedItemIndex();
+        int count = getItemCount();
+        if (count == 0) {
+            return;
+        }
+        if (selected < 0) {
+            selected = (forward ? count - 1 : 0);
+        }
+        int i = selected;
+        do {
+            i = (forward ? (i + 1) : (i + count - 1)) % count;
+            i %= count;
+            MenuItem item = getItem(i);
+            if (!"-".equals(item.getLabel())) { //$NON-NLS-1$
+                selectItem(i, showSubMenu);
+                return;
+            }
+        } while (i != selected);
+    }
+
+    
+    void showSubMenu(int index) {
+        if ((index < 0) || !isActive()) {
+            return;
+        }
+        MenuItem item = getItem(index);
+        if (item instanceof Menu) {
+            Menu menu = ((Menu) getItem(index));
+            if (menu.getItemCount() == 0) {
+                return;
+            }
+            Point location = getSubmenuLocation(index);
+            menu.show(location.x, location.y, false);
+        }
+    }
+    */
+
+    /**
+     * @return - the menu bar which is the root of crrent menu's hierarchy;
+     * or null if the hierarchy root is not a menu bar 
+     */
+    //???AWT
+    /*
+    MenuBar getMenuBar() {
+        if (parent instanceof MenuBar) {
+            return (MenuBar) parent;
+        }
+        if (parent instanceof MenuComponent) {
+            return ((MenuComponent) parent).getMenuBar();
+        }
+        return null;
+    }
+
+    PopupBox getPopupBox() {
+        return null;
+    }
+    */
+
+    Rectangle getItemRect(int index) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * Determine the clip region when menu selection is changed
+     * from index1 to index2.
+     * 
+     * @param index1 - old selected intem
+     * @param index2 - new selected item
+     * 
+     * @return - the region to repaint
+     */
+    final MultiRectArea getUpdateClip(int index1, int index2) {
+        MultiRectArea clip = new MultiRectArea();
+        if (index1 >= 0) {
+            clip.add(getItemRect(index1));
+        }
+        if (index2 >= 0) {
+            clip.add(getItemRect(index2));
+        }
+        return clip;
+    }
+
+    /**
+     * Gets the submenu location.
+     * 
+     * @param index the index
+     * 
+     * @return the submenu location
+     */
+    Point getSubmenuLocation(int index) {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the selected item index.
+     * 
+     * @return the selected item index
+     */
+    int getSelectedItemIndex() {
+        return selectedItemIndex;
+    }
+
+    /**
+     * Hide.
+     */
+    void hide() {
+        selectedItemIndex = -1;
+        if (parent instanceof MenuComponent) {
+            ((MenuComponent) parent).itemHidden(this);
+        }
+    }
+
+    /**
+     * Item hidden.
+     * 
+     * @param mc the mc
+     */
+    void itemHidden(MenuComponent mc) {
+        // to be overridden
+    }
+
+    /**
+     * Checks if is visible.
+     * 
+     * @return true, if is visible
+     */
+    boolean isVisible() {
+        return true;
+    }
+
+    /**
+     * Checks if is active.
+     * 
+     * @return true, if is active
+     */
+    boolean isActive() {
+        return true;
+    }
+
+    /**
+     * Hide all menu hierarchy.
+     */
+    void endMenu() {
+        //???AWT: toolkit.dispatcher.popupDispatcher.deactivateAll();
+    }
+
+    /**
+     * Handle the mouse click or Enter key event on a menu's item.
+     * 
+     * @param when - the event time
+     * @param modifiers - input event modifiers
+     */
+    void itemSelected(long when, int modifiers) {
+        endMenu();
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT: int number = toolkit.autoNumber.nextMenuComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Creates the Graphics object for the pop-up box of this menu component.
+     * 
+     * @param clip - the clip to set on this Graphics
+     * 
+     * @return - the created Graphics object,
+     * or null if such object is not available.
+     */
+    Graphics getGraphics(MultiRectArea clip) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * @return accessible context specific for particular menu component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+    */
+}
diff --git a/awt/java/awt/MenuContainer.java b/awt/java/awt/MenuContainer.java
new file mode 100644
index 0000000..7a48f13
--- /dev/null
+++ b/awt/java/awt/MenuContainer.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The MenuContainer interface represents all menu containers.
+ */
+public interface MenuContainer {
+
+    /**
+     * Removes the specified MenuComponent from the MenuContainer.
+     * 
+     * @param c the MenuComponent.
+     */
+    public void remove(MenuComponent c);
+
+    /**
+     * Gets the Font of the MenuContainer.
+     * 
+     * @return the font of the MenuContainer.
+     */
+    public Font getFont();
+
+    /**
+     * Posts an Event.
+     * 
+     * @param e the Event.
+     * 
+     * @return true if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced by dispatchEvent method.
+     */
+    @Deprecated
+    public boolean postEvent(Event e);
+
+}
+
diff --git a/awt/java/awt/ModalContext.java b/awt/java/awt/ModalContext.java
new file mode 100644
index 0000000..32a5912
--- /dev/null
+++ b/awt/java/awt/ModalContext.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ *
+ * The context for nested event loop. It can be dialog, popup menu etc.
+ */
+class ModalContext {
+
+    private boolean running = false;
+
+    private final Toolkit toolkit;
+
+    ModalContext() {
+        toolkit = Toolkit.getDefaultToolkit();
+    }
+
+    /**
+     * Set up and run modal loop in this context
+     *
+     */
+    void runModalLoop() {
+        running = true;
+        toolkit.dispatchThread.runModalLoop(this);
+    }
+
+    /**
+     * Leave the modal loop running in this context
+     * This method doesn't stops the loop immediately,
+     * it just sets the flag that says the modal loop to stop
+     *
+     */
+    void endModalLoop() {
+        running = false;
+    }
+
+    /**
+     *
+     * @return modal loop is currently running in this context
+     */
+    boolean isModalLoopRunning() {
+        return running;
+    }
+
+}
diff --git a/awt/java/awt/MouseDispatcher.java b/awt/java/awt/MouseDispatcher.java
new file mode 100644
index 0000000..df48f9d
--- /dev/null
+++ b/awt/java/awt/MouseDispatcher.java
@@ -0,0 +1,418 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev, Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.Dispatcher.MouseGrabManager;
+import java.util.EventListener;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+class MouseDispatcher {
+
+    // Fields for synthetic mouse click events generation
+    private static final int clickDelta = 5;
+    private final long[] lastPressTime = new long[] {0l, 0l, 0l};
+    private final Point[] lastPressPos = new Point[] {null, null, null};
+    private final boolean[] buttonPressed = new boolean[] {false, false, false};
+    private final int[] clickCount = new int[] {0, 0, 0};
+
+    // Fields for mouse entered/exited support
+    private Component lastUnderPointer = null;
+    private final Point lastScreenPos = new Point(-1, -1);
+
+    // Fields for redundant mouse moved/dragged filtering
+    private Component lastUnderMotion = null;
+    private Point lastLocalPos = new Point(-1, -1);
+
+    private final MouseGrabManager mouseGrabManager;
+    private final Toolkit toolkit;
+
+    static Point convertPoint(Component src, int x, int y, Component dest) {
+        Point srcPoint = getAbsLocation(src);
+        Point destPoint = getAbsLocation(dest);
+
+        return new Point(x + (srcPoint.x - destPoint.x),
+                         y + (srcPoint.y - destPoint.y));
+    }
+
+    static Point convertPoint(Component src, Point p, Component dst) {
+        return convertPoint(src, p.x, p.y, dst);
+    }
+
+    private static Point getAbsLocation(Component comp) {
+        Point location = new Point(0, 0);
+// BEGIN android-changed: AWT components not supported
+//        for (Component parent = comp; parent != null; parent = parent.parent) {
+//            Point parentPos = (parent instanceof EmbeddedWindow ?
+//                               parent.getNativeWindow().getScreenPos() :
+//                               parent.getLocation());
+//
+//            location.translate(parentPos.x, parentPos.y);
+//
+//            if (parent instanceof Window) {
+//                break;
+//            }
+//        }
+// END android-changed
+
+        return location;
+    }
+
+    MouseDispatcher(MouseGrabManager mouseGrabManager,
+                    Toolkit toolkit) {
+        this.mouseGrabManager = mouseGrabManager;
+        this.toolkit = toolkit;
+    }
+
+    Point getPointerPos() {
+        return lastScreenPos;
+    }
+
+    boolean dispatch(Component src, NativeEvent event) {
+        int id = event.getEventId();
+
+        lastScreenPos.setLocation(event.getScreenPos());
+        checkMouseEnterExit(event.getInputModifiers(), event.getTime());
+
+        if (id == MouseEvent.MOUSE_WHEEL) {
+// BEGIN android-changed: AWT components not supported
+//            dispatchWheelEvent(src, event);
+// END android-changed
+        } else if ((id != MouseEvent.MOUSE_ENTERED) &&
+                   (id != MouseEvent.MOUSE_EXITED)) {
+            PointerInfo info = new PointerInfo(src, event.getLocalPos());
+
+            mouseGrabManager.preprocessEvent(event);
+            findEventSource(info);
+            if ((id == MouseEvent.MOUSE_PRESSED) ||
+                (id == MouseEvent.MOUSE_RELEASED)) {
+
+                dispatchButtonEvent(info, event);
+            } else if ((id == MouseEvent.MOUSE_MOVED) ||
+                       (id == MouseEvent.MOUSE_DRAGGED)) {
+
+                dispatchMotionEvent(info, event);
+            }
+        }
+
+        return false;
+    }
+
+    private void checkMouseEnterExit(int modifiers, long when) {
+// BEGIN android-changed: AWT components not supported
+//        PointerInfo info = findComponentUnderPointer();
+//        Component curUnderPointer =
+//                propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+//                               MouseListener.class, false).src;
+//
+//        if (curUnderPointer != lastUnderPointer) {
+//            Point pos = info.position;
+//            if ((lastUnderPointer != null) &&
+//                 lastUnderPointer.isMouseExitedExpected()) {
+//
+//                Point exitPos = convertPoint(null, lastScreenPos.x,
+//                                             lastScreenPos.y, lastUnderPointer);
+//
+//                postMouseEnterExit(MouseEvent.MOUSE_EXITED, modifiers, when,
+//                                   exitPos.x, exitPos.y, lastUnderPointer);
+//            }
+//            setCursor(curUnderPointer);
+//            if (curUnderPointer != null) {
+//                postMouseEnterExit(MouseEvent.MOUSE_ENTERED, modifiers, when,
+//                                   pos.x, pos.y, curUnderPointer);
+//            }
+//            lastUnderPointer = curUnderPointer;
+//        }
+// END android-changed
+    }
+
+    private void setCursor(Component comp) {
+        if (comp == null) {
+            return;
+        }
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+        Component cursorComp = ((grabOwner != null) &&
+                                 grabOwner.isShowing() ? grabOwner : comp);
+        cursorComp.setCursor();
+    }
+
+    private void postMouseEnterExit(int id, int mod, long when,
+                                    int x, int y, Component comp) {
+        if (comp.isIndirectlyEnabled()) {
+            toolkit.getSystemEventQueueImpl().postEvent(
+                    new MouseEvent(comp, id, when, mod, x, y, 0, false));
+            comp.setMouseExitedExpected(id == MouseEvent.MOUSE_ENTERED);
+        } else {
+            comp.setMouseExitedExpected(false);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private PointerInfo findComponentUnderPointer() {
+//        NativeWindow nativeWindow = toolkit.getWindowFactory().
+//        getWindowFromPoint(lastScreenPos);
+//
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                Window window = comp.getWindowAncestor();
+//                Point pointerPos = convertPoint(null, lastScreenPos.x,
+//                                                lastScreenPos.y, window);
+//
+//                if (window.getClient().contains(pointerPos)) {
+//                    PointerInfo info = new PointerInfo(window, pointerPos);
+//
+//                    fall2Child(info);
+//
+//                    return info;
+//                }
+//            }
+//        }
+//
+//        return new PointerInfo(null, null);
+//    }
+// END android-changed
+    
+    private void findEventSource(PointerInfo info) {
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+
+        if (grabOwner != null && grabOwner.isShowing()) {
+            info.position = convertPoint(info.src, info.position, grabOwner);
+            info.src = grabOwner;
+        } else {
+            //???AWT: rise2TopLevel(info);
+            //???AWT: fall2Child(info);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private void rise2TopLevel(PointerInfo info) {
+//        while (!(info.src instanceof Window)) {
+//            info.position.translate(info.src.x, info.src.y);
+//            info.src = info.src.parent;
+//        }
+//    }
+//
+//    private void fall2Child(PointerInfo info) {
+//        Insets insets = info.src.getInsets();
+//
+//        final Point pos = info.position;
+//        final int x = pos.x;
+//        final int y = pos.y;
+//        if ((x >= insets.left) && (y >= insets.top) &&
+//                (x < (info.src.w - insets.right)) &&
+//                (y < (info.src.h - insets.bottom)))
+//        {
+//            Component[] children = ((Container) info.src).getComponents();
+//
+//            for (Component child : children) {
+//                if (child.isShowing()) {
+//                    if (child.contains(x - child.getX(),
+//                            y - child.getY()))
+//                    {
+//                        info.src = child;
+//                        pos.translate(-child.x, -child.y);
+//
+//                        if (child instanceof Container) {
+//                            fall2Child(info);
+//                        }
+//
+//                        return;
+//                    }
+//                }
+//            }
+//        }
+//    }
+// END android-changed
+
+    private void dispatchButtonEvent(PointerInfo info, NativeEvent event) {
+        int button = event.getMouseButton();
+        long time = event.getTime();
+        int id = event.getEventId();
+        int index = button - 1;
+        boolean clickRequired = false;
+
+        propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+                       MouseListener.class, false);
+        if (id == MouseEvent.MOUSE_PRESSED) {
+            int clickInterval = toolkit.dispatcher.clickInterval;
+            mouseGrabManager.onMousePressed(info.src);
+            buttonPressed[index] = true;
+            clickCount[index] = (!deltaExceeded(index, info) &&
+                    ((time - lastPressTime[index]) <= clickInterval)) ?
+                    clickCount[index] + 1 : 1;
+            lastPressTime[index] = time;
+            lastPressPos[index] = info.position;
+        } else {
+            mouseGrabManager.onMouseReleased(info.src);
+            // set cursor back on synthetic mouse grab end:
+// BEGIN android-changed: AWT components not supported
+//            setCursor(findComponentUnderPointer().src);
+// END android-changed
+            if (buttonPressed[index]) {
+                buttonPressed[index] = false;
+                clickRequired = !deltaExceeded(index, info);
+            } else {
+                clickCount[index] = 0;
+            }
+        }
+        if (info.src.isIndirectlyEnabled()) {
+            final Point pos = info.position;
+            final int mod = event.getInputModifiers();
+            toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, id, time, mod, pos.x,
+                            pos.y, clickCount[index],
+                            event.getTrigger(), button));
+            if (clickRequired) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src,
+                            MouseEvent.MOUSE_CLICKED,
+                            time, mod, pos.x, pos.y,
+                            clickCount[index], false,
+                            button));
+            }
+        }
+    }
+
+    private boolean deltaExceeded(int index, PointerInfo info) {
+        final Point lastPos = lastPressPos[index];
+        if (lastPos == null) {
+            return true;
+        }
+        return ((Math.abs(lastPos.x - info.position.x) > clickDelta) ||
+                (Math.abs(lastPos.y - info.position.y) > clickDelta));
+    }
+
+    private void dispatchMotionEvent(PointerInfo info, NativeEvent event) {
+        propagateEvent(info, AWTEvent.MOUSE_MOTION_EVENT_MASK,
+                       MouseMotionListener.class, false);
+        final Point pos = info.position;
+        if ((lastUnderMotion != info.src) ||
+            !lastLocalPos.equals(pos)) {
+
+            lastUnderMotion = info.src;
+            lastLocalPos = pos;
+
+            if (info.src.isIndirectlyEnabled()) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, event.getEventId(),
+                            event.getTime(),
+                            event.getInputModifiers(),
+                            pos.x, pos.y, 0, false));
+            }
+        }
+    }
+
+    MouseWheelEvent createWheelEvent(Component src, NativeEvent event,
+                                     Point where) {
+
+        Integer scrollAmountProperty =
+            (Integer)toolkit.getDesktopProperty("awt.wheelScrollingSize"); //$NON-NLS-1$
+        int amount = 1;
+        int type = MouseWheelEvent.WHEEL_UNIT_SCROLL;
+
+        if (scrollAmountProperty != null) {
+            amount = scrollAmountProperty.intValue();
+            if (amount == -1) {
+                type = MouseWheelEvent.WHEEL_BLOCK_SCROLL;
+                amount = 1;
+            }
+        }
+        return new MouseWheelEvent(src, event.getEventId(),
+                event.getTime(), event.getInputModifiers(),
+                where.x, where.y, 0, false, type, amount,
+                event.getWheelRotation());
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    private void dispatchWheelEvent(Component src, NativeEvent event) {
+//        PointerInfo info = findComponentUnderPointer();
+//
+//        if (info.src == null) {
+//            info.src = src;
+//            info.position = event.getLocalPos();
+//        }
+//
+//        propagateEvent(info, AWTEvent.MOUSE_WHEEL_EVENT_MASK,
+//                       MouseWheelListener.class, true);
+//        if ((info.src != null) && info.src.isIndirectlyEnabled()) {
+//            toolkit.getSystemEventQueueImpl().postEvent(
+//                    createWheelEvent(info.src, event, info.position));
+//        }
+//    }
+// END android-changed
+
+    private PointerInfo propagateEvent(PointerInfo info, long mask,
+                                       Class<? extends EventListener> type, boolean pierceHW) {
+        Component src = info.src;
+        while ((src != null) &&
+               (src.isLightweight() || pierceHW) &&
+              !(src.isMouseEventEnabled(mask) ||
+               (src.getListeners(type).length > 0))) {
+
+            info.position.translate(src.x, src.y);
+// BEGIN android-changed: AWT components not supported
+//            src = src.parent;
+// END android-changed
+            info.src = src;
+        }
+
+        return info;
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    Window findWindowAt(Point p) {
+//        NativeWindow nativeWindow =
+//            toolkit.getWindowFactory().getWindowFromPoint(p);
+//
+//        Window window = null;
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                window = comp.getWindowAncestor();
+//            }
+//        }
+//        return window;
+//    }
+// END android-changed
+
+    private class PointerInfo {
+
+        Component src;
+        Point position;
+
+        PointerInfo(Component src, Point position) {
+            this.src = src;
+            this.position = position;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/Paint.java b/awt/java/awt/Paint.java
new file mode 100644
index 0000000..f8732c8
--- /dev/null
+++ b/awt/java/awt/Paint.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+/**
+ * The Paint interface provides possibility of generating 
+ * color patterns in device space for fill, draw, or stroke operations 
+ * in a Graphics2D.
+ */
+public interface Paint extends Transparency {
+    
+    /**
+     * Creates the PaintContext which is used to generate color 
+     * patterns for rendering operations of Graphics2D.
+     * 
+     * @param cm the ColorModel object, or null.
+     * @param deviceBounds the Rectangle represents the bounding box of
+     * device space for the graphics rendering operations.
+     * @param userBounds the Rectangle represents bounding box of
+     * user space for the graphics rendering operations.
+     * @param xform the AffineTransform for translation from user space 
+     * to device space.
+     * @param hints the RenderingHints preferences.
+     * 
+     * @return the PaintContext for generating color patterns.
+     */
+    PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform xform,
+            RenderingHints hints);
+}
diff --git a/awt/java/awt/PaintContext.java b/awt/java/awt/PaintContext.java
new file mode 100644
index 0000000..647de8b
--- /dev/null
+++ b/awt/java/awt/PaintContext.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * The PaintContext interface determines the specific environment for
+ * generating color patterns in device space for fill, draw, or stroke 
+ * rendering operations using Graphics2D. This interface provides colors
+ * through the Raster object associated with the specific ColorModel 
+ * for Graphics2D rendering operations.
+ */
+public interface PaintContext {
+    
+    /**
+     * Releases the resources allocated for the operation.
+     */
+    void dispose();
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel object.
+     */
+    ColorModel getColorModel();
+
+    /**
+     * Gets the Raster which defines the colors of the specified rectangular 
+     * area for Graphics2D rendering operations.
+     * 
+     * @param x the X coordinate of the device space area for which 
+     * colors are generated.
+     * @param y the Y coordinate of the device space area for which 
+     * colors are generated.
+     * @param w the width of the device space area for which 
+     * colors are generated.
+     * @param h the height of the device space area for which 
+     * colors are generated.
+     * 
+     * @return the Raster object which contains the colors of the specified 
+     * rectangular area for Graphics2D rendering operations.
+     */
+    Raster getRaster(int x, int y, int w, int h);
+}
diff --git a/awt/java/awt/Point.java b/awt/java/awt/Point.java
new file mode 100644
index 0000000..99418ed
--- /dev/null
+++ b/awt/java/awt/Point.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+/**
+ * The Point class represents a point location with coordinates X, Y in 
+ * current coordinate system.
+ */
+public class Point extends Point2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5276940640259749850L;
+
+    /** The X coordinate of Point. */
+    public int x;
+    
+    /** The Y coordinate of Point. */
+    public int y;
+
+    /**
+     * Instantiates a new point with (0, O) coordinates, the origin of 
+     * coordinate system.
+     */
+    public Point() {
+        setLocation(0, 0);
+    }
+
+    /**
+     * Instantiates a new point with (x, y) coordinates.
+     * 
+     * @param x the X coordinate of Point.
+     * @param y the Y coordinate of Point.
+     */
+    public Point(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Instantiates a new point, giving it the same locaion as
+     * the parameter p.
+     * 
+     * @param p the Point object giving the coordinates of the new point.
+     */
+    public Point(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Compares current Point with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object being compared is a Point 
+     * whose coordinates are equal to the coordinates of this 
+     * Point, otherwise false.
+     * 
+     * @see java.awt.geom.Point2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point) {
+            Point p = (Point)obj;
+            return x == p.x && y == p.y;
+        }
+        return false;
+    }
+
+    /**
+     * Returns string representation of the current Point object.
+     * 
+     * @return a string representation of the current Point object.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Gets X coordinate of Point as a double.
+     * 
+     * @return X coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets Y coordinate of Point as a double.
+     * 
+     * @return Y coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the location of the Point as a new Point object.
+     * 
+     * @return a copy of the Point.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the Point to the same coordinates as p.
+     * 
+     * @param p the Point that gives the new location.
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Sets the location of the Point to the coordinates X, Y.
+     * 
+     * @param x the X coordinate of the Point's new location.
+     * @param y the Y coordinate of the Point's new location.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of Point to the specified double coordinates.
+     * 
+     * @param x the X the Point's new location.
+     * @param y the Y the Point's new location.
+     *  
+     * @see java.awt.geom.Point2D#setLocation(double, double)
+     */
+    @Override
+    public void setLocation(double x, double y) {
+        x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE : x;
+        y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE : y;
+        setLocation((int)Math.round(x), (int)Math.round(y));
+    }
+
+    /**
+     * Moves the Point to the specified (x, y) location.
+     * 
+     * @param x the X coordinate of the new location.
+     * @param y the Y coordinate of the new location. 
+     */
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Translates current Point moving it from the position (x, y) 
+     * to the new position given by (x+dx, x+dy) coordinates.
+     * 
+     * @param dx the horizontal delta - the Point is moved to this distance along
+     * X axis.
+     * @param dy the vertical delta - the Point is moved to this distance along
+     * Y axis.
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+}
+
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
new file mode 100644
index 0000000..6f3fc97
--- /dev/null
+++ b/awt/java/awt/Polygon.java
@@ -0,0 +1,494 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Polygon class defines an closed area specified by n vertices and 
+ * n edges. The coordinates of the vertices are specified by x, y arrays.
+ * The edges are the line segments from the point (x[i], y[i]) to the point 
+ * (x[i+1], y[i+1]), for -1 < i < (n-1) plus the line segment from 
+ * the point (x[n-1], y[n-1]) to the point (x[0], y[0]) point. 
+ * The Polygon is empty if the number of vertices is zero.   
+ */
+public class Polygon implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6460061437900069969L;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 4;
+    
+    /** The number of Polygon vertices.*/
+    public int npoints;
+    
+    /** The array of X coordinates of the vertices. */
+    public int[] xpoints;
+    
+    /** The array of Y coordinates of the vertices. */
+    public int[] ypoints;
+    
+    /**  
+     * The smallest Rectangle that completely contains this Polygon. 
+     */
+    protected Rectangle bounds;
+
+    /*
+     * Polygon path iterator  
+     */
+    /**
+     * The internal Class Iterator.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source Polygon object. */
+        public Polygon p;
+        
+        /** The path iterator transformation. */
+        public AffineTransform t;
+        
+        /** The current segmenet index. */
+        public int index;
+
+        /**
+         * Constructs a new Polygon.Iterator for the given polygon and transformation
+         * 
+         * @param at - the AffineTransform object to apply rectangle path
+         * @param p the p
+         */
+        public Iterator(AffineTransform at, Polygon p) {
+            this.p = p;
+            this.t = at;
+            if (p.npoints == 0) {
+                index = 1;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_EVEN_ODD;
+        }
+
+        public boolean isDone() {
+            return index > p.npoints;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+    }
+
+    /**
+     * Instantiates a new empty polygon.
+     */
+    public Polygon() {
+        xpoints = new int[BUFFER_CAPACITY];
+        ypoints = new int[BUFFER_CAPACITY];
+    }
+
+    /**
+     * Instantiates a new polygon with the specified number of vertices,
+     * and the given arrays of x, y vertex coordinates. The length of 
+     * each coordinate array may not be less than the specified number of 
+     * vertices but may be greater. Only the first n elements are used from 
+     * each coordinate array.
+     * 
+     * @param xpoints the array of X vertex coordinates. 
+     * @param ypoints the array of Y vertex coordinates.
+     * @param npoints the number vertices of the polygon.
+     * @throws IndexOutOfBoundsException if the length of xpoints or ypoints
+     * is less than n.
+     * @throws NegativeArraySizeException if n is negative.
+     */
+    public Polygon(int[] xpoints, int[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            // awt.111=Parameter npoints is greater than array length
+            throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
+        }
+        if (npoints < 0) {
+            // awt.112=Negative number of points
+            throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
+        }
+        this.npoints = npoints;
+        this.xpoints = new int[npoints];
+        this.ypoints = new int[npoints];
+        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+    }
+
+    /**
+     * Resets the current Polygon to an empty Polygon. More precisely, 
+     * the number of Polygon vertices is set to zero, but x, y coordinates 
+     * arrays are not affected.  
+     */
+    public void reset() {
+        npoints = 0;
+        bounds = null;
+    }
+
+    /**
+     * Invalidates the data that depends on the vertex coordinates. 
+     * This method should be called after direct manipulations  
+     * of the x, y vertex coordinates arrays to avoid unpredictable 
+     * results of methods which rely on the bounding box.
+     */
+    public void invalidate() {
+        bounds = null;
+    }
+
+    /**
+     * Adds the point to the Polygon and updates the bounding box 
+     * accordingly.
+     * 
+     * @param px the X coordinate of the added vertex.
+     * @param py the Y coordinate of the added vertex.
+     */
+    public void addPoint(int px, int py) {
+        if (npoints == xpoints.length) {
+            int[] tmp;
+
+            tmp = new int[xpoints.length + BUFFER_CAPACITY];
+            System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
+            xpoints = tmp;
+
+            tmp = new int[ypoints.length + BUFFER_CAPACITY];
+            System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
+            ypoints = tmp;
+        }
+
+        xpoints[npoints] = px;
+        ypoints[npoints] = py;
+        npoints++;
+
+        if (bounds != null) {
+            bounds.setFrameFromDiagonal(
+                    Math.min(bounds.getMinX(), px),
+                    Math.min(bounds.getMinY(), py),
+                    Math.max(bounds.getMaxX(), px),
+                    Math.max(bounds.getMaxY(), py));
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds()
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+        if (npoints == 0) {
+            return new Rectangle();
+        }
+
+        int bx1 = xpoints[0];
+        int by1 = ypoints[0];
+        int bx2 = bx1;
+        int by2 = by1;
+
+        for (int i = 1; i < npoints; i++) {
+            int x = xpoints[i];
+            int y = ypoints[i];
+            if (x < bx1) {
+                bx1 = x;
+            } else if (x > bx2) {
+                bx2 = x;
+            }
+            if (y < by1) {
+                by1 = y;
+            } else if (y > by2) {
+                by2 = y;
+            }
+        }
+
+        return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @deprecated Use getBounds() method.
+     */
+    @Deprecated
+    public Rectangle getBoundingBox() {
+        return getBounds();
+    }
+
+    /**
+     * Gets the Rectangle2D which represents Polygon bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds2D()
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds().getBounds2D();
+    }
+
+    /**
+     * Translates all vertices of Polygon the specified distances
+     * along X, Y axis.
+     * 
+     * @param mx the distance to translate horizontally.
+     * @param my the distance to translate vertically.
+     */
+    public void translate(int mx, int my) {
+        for (int i = 0; i < npoints; i++) {
+            xpoints[i] += mx;
+            ypoints[i] += my;
+        }
+        if (bounds != null) {
+            bounds.translate(mx, my);
+        }
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @deprecated Use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point with specified double coordinates 
+     * lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the point given by the double coordinates 
+     * lies inside the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double)
+     */
+    public boolean contains(double x, double y) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double, double, double)
+     */
+    public boolean contains(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] intersects the interior of
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(double, double, double, double)
+     */
+    public boolean intersects(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
+     */
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Checks whether or not the specified Point lies inside the Polygon.
+     * 
+     * @param point the Point object.
+     * 
+     * @return true, if the specified Point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(Point point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Polygon.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
+     */
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the interior of rectangle specified by 
+     * the Rectangle2D object intersects the interior of the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
+     */
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Polygon.
+     * 
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(t, this);
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * The flatness parameter is ignored.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided curve 
+     * is replaced by a straight line connecting the endpoints. 
+     * This parameter is ignored for the Polygon class.
+     * 
+     * @return PathIterator object for the Polygon.
+     *  
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform, double)
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(t, this);
+    }
+
+}
+
diff --git a/awt/java/awt/Rectangle.java b/awt/java/awt/Rectangle.java
new file mode 100644
index 0000000..86c4dfc
--- /dev/null
+++ b/awt/java/awt/Rectangle.java
@@ -0,0 +1,686 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * The Rectangle class defines the rectangular area in terms of its
+ * upper left corner coordinates [x,y], its width, and its height.  
+ * A Rectangle specified by [x, y, width, height] parameters has an 
+ * outline path with corners at [x, y], [x + width,y], [x + width,y + height], 
+ * and [x, y + height]. 
+ * <br><br>
+ * The rectangle is empty if the width or height is negative or zero. 
+ * In this case the isEmpty method returns true.
+ */
+public class Rectangle extends Rectangle2D implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4345857070255674764L;
+
+    /** The X coordinate of the rectangle's left upper corner. */
+    public int x;
+    
+    /** The Y coordinate of the rectangle's left upper corner. */
+    public int y;
+    
+    /** The width of rectangle. */
+    public int width;
+    
+    /** The height of rectangle. */
+    public int height;
+
+    /**
+     * Instantiates a new rectangle with [0, 0] upper left corner coordinates,
+     * the width and the height are zero.
+     */
+    public Rectangle() {
+        setBounds(0, 0, 0, 0);
+    }
+
+    /**
+     * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and 
+     * the height are zero. 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     */
+    public Rectangle(Point p) {
+        setBounds(p.x, p.y, 0, 0);
+    }
+
+    /**
+      * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and the height
+     * are given by Dimension object (d.width and d.height). 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     * @param d the Dimention specifies the width and the height of the rectangle. 
+     */
+    public Rectangle(Point p, Dimension d) {
+        setBounds(p.x, p.y, d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new rectangle determined by the upper left corner 
+     * coordinates (x, y), width and height.
+     * 
+     * @param x the X upper left corner coordinate of the rectangle.
+     * @param y the Y upper left corner coordinate of the rectangle.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with [0, 0] as its upper left 
+     * corner coordinates and the specified width and height.
+     * 
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int width, int height) {
+        setBounds(0, 0, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with the same coordinates 
+     * as the given source rectangle.
+     * 
+     * @param r the Rectangle object which parameters will be used for 
+     * instantiating a new Rectangle.
+     */
+    public Rectangle(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+/*
+    public Rectangle(Dimension d) {
+        setBounds(0, 0, d.width, d.height);
+    }
+*/
+    /**
+     * Gets the X coordinate of bound as a double.
+     * 
+     * @return the X coordinate of bound as a double.
+     *   
+     * @see java.awt.geom.RectangularShape#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets the Y coordinate of bound as a double.
+     * 
+     * @return the Y coordinate of bound as a double.
+     * 
+     * @see java.awt.geom.RectangularShape#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the height of the rectangle as a double.
+     * 
+     * @return the height of the rectangle as a double. 
+     * 
+     * @see java.awt.geom.RectangularShape#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the rectangle as a double.
+     * 
+     * @return the width of the rectangle as a double.
+     *  
+     * @see java.awt.geom.RectangularShape#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+    /**
+     * Determines whether or not the rectangle is empty. The rectangle is empty if 
+     * its width or height is negative or zero.
+     * 
+     * @return true, if the rectangle is empty, otherwise false.
+     * 
+     * @see java.awt.geom.RectangularShape#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return width <= 0 || height <= 0;
+    }
+
+    /**
+     * Gets the size of a Rectangle as Dimention object.
+     * 
+     * @return a Dimention object which represents size of the rectangle.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Sets the size of the Rectangle.
+     * 
+     * @param width the new width of the rectangle. 
+     * @param height the new height of the rectangle.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of a Rectangle specified as Dimension object.
+     * 
+     * @param d a Dimension object which represents new size of a rectangle.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Gets the location of a rectangle's upper left corner as a Point object.
+     * 
+     * @return the Point object with coordinates equal to the upper left corner 
+     * of the rectangle.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the rectangle in terms of its upper left 
+     * corner coordinates X and Y.
+     * 
+     * @param x the X coordinate of the rectangle's upper left corner.
+     * @param y the Y coordinate of the rectangle's upper left corner.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of a rectangle using a Point object to give the 
+     * coordinates of the upper left corner.
+     * 
+     * @param p the Point object which represents the new upper left corner 
+     * coordinates of rectangle.  
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Moves a rectangle to the new location by moving its upper left corner
+     * to the point with coordinates X and Y.
+     * 
+     * @param x the new X coordinate of the rectangle's upper left corner.
+     * @param y the new Y coordinate of the rectangle's upper left corner.
+     * 
+     * @deprecated Use setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Sets the rectangle to be the nearest rectangle with integer coordinates 
+     * bounding the rectangle defined by the double-valued parameters.
+     * 
+     * @param x the X coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param y the Y coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param width the width of the rectangle to be bounded.
+     * @param height the height of the rectangle to be bounded.      
+     * 
+     * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
+     */
+    @Override
+    public void setRect(double x, double y, double width, double height) {
+        int x1 = (int)Math.floor(x);
+        int y1 = (int)Math.floor(y);
+        int x2 = (int)Math.ceil(x + width);
+        int y2 = (int)Math.ceil(y + height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Sets a new size for the rectangle.
+     * 
+     * @param width the rectangle's new width.
+     * @param height the rectangle's new height.
+     * 
+     * @deprecated use the setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Resets the bounds of a rectangle to the specified x, y, width and height 
+     * parameters.
+     * 
+     * @param x the new X coordinate of the upper left corner.
+     * @param y the new Y coordinate of the upper left corner.
+     * @param width the new width of rectangle.
+     * @param height the new height of rectangle. 
+     * 
+     * @deprecated use setBounds(int, int, int, int) method
+     */
+    @Deprecated
+    public void reshape(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Gets bounds of the rectangle as a new Rectangle object.
+     *  
+     * @return the Rectangle object with the same bounds as 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.RectangularShape#getBounds()
+     */
+    @Override
+    public Rectangle getBounds() {
+        return new Rectangle(x, y, width, height);
+    }
+
+    /**
+     * Gets the bounds of the original rectangle as a Rectangle2D object.
+     *  
+     * @return the Rectangle2D object which represents the bounds of 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.Rectangle2D#getBounds2D()
+     */
+    @Override
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Sets the bounds of a rectangle to the specified x, y, width, and height 
+     * parameters.
+     * 
+     * @param x the X coordinate of the upper left corner.
+     * @param y the Y coordinate of the upper left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int width, int height) {
+        this.x = x;
+        this.y = y;
+        this.height = height;
+        this.width = width;
+    }
+
+    /**
+     * Sets the bounds of the rectangle to match the bounds of the
+     * Rectangle object sent as a parameter.
+     * 
+     * @param r the Rectangle object which specifies the new bounds. 
+     */
+    public void setBounds(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Enlarges the rectangle by moving each corner outward from the 
+     * center by a distance of dx horizonally and a distance of dy 
+     * vertically. Specifically, changes a rectangle with 
+     * [x, y, width, height] parameters to 
+     * a rectangle with [x-dx, y-dy, width+2*dx, height+2*dy]
+     * parameters. 
+     *   
+     * @param dx the horizontal distance to move each corner coordinate.
+     * @param dy the vertical distance to move each corner coordinate.
+     */
+    public void grow(int dx, int dy) {
+        x -= dx;
+        y -= dy;
+        width += dx + dx;
+        height += dy + dy;
+    }
+
+    /**
+     * Moves a rectangle a distance of mx along the x coordinate axis 
+     * and a distance of my along y coordinate axis.
+     * 
+     * @param mx the horizontal translation increment.
+     * @param my the vertical translation increment.
+     */
+    public void translate(int mx, int my) {
+        x += mx;
+        y += my;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point.
+     * 
+     * @param px the X coordinate of the new point to be covered by the rectangle.
+     * @param py the Y coordinate of the new point to be covered by the rectangle.
+     */
+    public void add(int px, int py) {
+        int x1 = Math.min(x, px);
+        int x2 = Math.max(x + width, px);
+        int y1 = Math.min(y, py);
+        int y2 = Math.max(y + height, py);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point with the
+     * new point given as a Point object.
+     * 
+     * @param p the Point object that specifies the new point to 
+     * be covered by the rectangle.
+     */
+    public void add(Point p) {
+        add(p.x, p.y);
+    }
+
+    /**
+     * Adds a new rectangle to the original rectangle, the result is an union of
+     * the specified specified rectangle and original rectangle.
+     * 
+     * @param r the Rectangle which is added to the original rectangle. 
+     */
+    public void add(Rectangle r) {
+        int x1 = Math.min(x, r.x);
+        int x2 = Math.max(x + width, r.x + r.width);
+        int y1 = Math.min(y, r.y);
+        int y2 = Math.max(y + height, r.y + r.height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the point with specified coordinates [px, py] 
+     * is within the bounds of the rectangle.
+     * 
+     * @param px the X coordinate of point.
+     * @param py the Y coordinate of point.
+     * 
+     * @return true, if the point with specified coordinates [px, py] is 
+     * within the bounds of the rectangle, otherwise false.
+     */
+    public boolean contains(int px, int py) {
+        if (isEmpty()) {
+            return false;
+        }
+        if (px < x || py < y) {
+            return false;
+        }
+        px -= x;
+        py -= y;
+        return px < width && py < height;
+    }
+
+    /**
+     * Determines whether or not the point given as a Point object 
+     * is within the bounds of the rectangle.
+     * 
+     * @param p the Point object
+     * 
+     * @return true, if the point p is within the bounds of the 
+     * rectangle, otherwise false.
+     */
+    public boolean contains(Point p) {
+        return contains(p.x, p.y);
+    }
+
+    /**
+     * Determines whether or not the rectangle specified by [rx, ry, rw, rh] 
+     * parameters is located inside the original rectangle.
+     * 
+     * @param rx the X coordinate of the rectangle to compare.
+     * @param ry the Y coordinate of the rectangle to compare.
+     * @param rw the width of the rectangle to compare.
+     * @param rh the height of the rectangle to compare.
+     * 
+     * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(int rx, int ry, int rw, int rh) {
+        return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
+    }
+
+    /**
+     * Compares whether or not the rectangle specified by the Rectangle object
+     * is located inside the original rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the rectangle specified by Rectangle object is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(Rectangle r) {
+        return contains(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Compares whether or not a point with specified coordinates [px, py] belongs 
+     * to a rectangle.
+     * 
+     * @param px the X coordinate of a point.
+     * @param py the Y coordinate of a point.
+     * 
+     * @return true, if a point with specified coordinates [px, py] belongs 
+     * to a rectangle, otherwise false.
+     * 
+     * @deprecated use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int px, int py) {
+        return contains(px, py);
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the Rectangle2D object that is the result of intersecting 
+     * the original rectangle with the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createIntersection(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return intersection((Rectangle) r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.intersect(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified rectangle. An empty rectangle is returned if there is no
+     * intersection.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return the Rectangle object is result of the original rectangle with the 
+     * specified rectangle. 
+     */
+    public Rectangle intersection(Rectangle r) {
+        int x1 = Math.max(x, r.x);
+        int y1 = Math.max(y, r.y);
+        int x2 = Math.min(x + width, r.x + r.width);
+        int y2 = Math.min(y + height, r.y + r.height);
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the original rectangle intersects 
+     * the specified rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the two rectangles overlap; otherwise false.
+     */
+    public boolean intersects(Rectangle r) {
+        return !intersection(r).isEmpty();
+    }
+
+    /**
+     * Determines where the specified Point is located with respect to 
+     * the rectangle. This method computes whether the point is to the 
+     * right or to the left of the rectangle and whether it is above 
+     * or below the rectangle, and packs the result into an int by 
+     * using a binary OR operation with the following masks:
+     * <ul>
+     *<li>Rectangle2D.OUT_LEFT</li>
+     *<li>Rectangle2D.OUT_TOP</li>
+     *<li>Rectangle2D.OUT_RIGHT</li>
+     *<li>Rectangle2D.OUT_BOTTOM</li>
+     *</ul>
+     *
+     * If the rectangle is empty, all masks are set, and if the 
+     * point is inside the rectangle, none are set.
+     * 
+     * @param px the X coordinate of the specified point.
+     * @param py the Y coordinate of the specified point.
+     * 
+     * @return the location of the Point relative to the rectangle 
+     * as the result of logical OR operation with all out masks.
+     * 
+     * @see java.awt.geom.Rectangle2D#outcode(double, double)
+     */
+    @Override
+    public int outcode(double px, double py) {
+        int code = 0;
+
+        if (width <= 0) {
+            code |= OUT_LEFT | OUT_RIGHT;
+        } else
+            if (px < x) {
+                code |= OUT_LEFT;
+            } else
+                if (px > x + width) {
+                    code |= OUT_RIGHT;
+                }
+
+        if (height <= 0) {
+            code |= OUT_TOP | OUT_BOTTOM;
+        } else
+            if (py < y) {
+                code |= OUT_TOP;
+            } else
+                if (py > y + height) {
+                    code |= OUT_BOTTOM;
+                }
+
+        return code;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the union of the original and the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createUnion(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return union((Rectangle)r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.union(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified rectangle.
+     * 
+     * @param r the Rectangle.
+     * 
+     * @return the union of the original and the specified rectangle.
+     */
+    public Rectangle union(Rectangle r) {
+        Rectangle dst = new Rectangle(this);
+        dst.add(r);
+        return dst;
+    }
+
+    /**
+     * Compares the original Rectangle with the specified object.
+     * 
+     * @param obj the specified Object for comparison.
+     * 
+     * @return true, if the specified Object is a rectangle with the 
+     * same dimensions as the original rectangle, otherwise false.
+     * 
+     * @see java.awt.geom.Rectangle2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle) {
+            Rectangle r = (Rectangle)obj;
+            return r.x == x && r.y == y && r.width == width && r.height == height;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of the rectangle; the string contains 
+     * [x, y, width, height] parameters of the rectangle.
+     * 
+     * @return the string representation of the rectangle.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Rectangle().toString())
+        return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
+            ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
+
diff --git a/awt/java/awt/RenderingHints.java b/awt/java/awt/RenderingHints.java
new file mode 100644
index 0000000..4957884
--- /dev/null
+++ b/awt/java/awt/RenderingHints.java
@@ -0,0 +1,601 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The RenderingHints class represents preferences for the rendering algorithms. 
+ * The preferences are arbitrary and can be specified by Map objects or by 
+ * key-value pairs. 
+ */
+public class RenderingHints implements Map<Object, Object>, Cloneable {
+    
+    /**
+     * The Constant KEY_ALPHA_INTERPOLATION - alpha interpolation rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ALPHA_INTERPOLATION = new KeyImpl(1);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_DEFAULT - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_SPEED - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_QUALITY - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY = new KeyValue(KEY_ALPHA_INTERPOLATION);
+
+    /** 
+     * The Constant KEY_ANTIALIASING - antialiasing rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ANTIALIASING = new KeyImpl(2);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_DEFAULT - antialiasing
+     * rendering hint value. 
+     */
+    public static final Object VALUE_ANTIALIAS_DEFAULT = new KeyValue(KEY_ANTIALIASING);
+    
+    /** 
+     * The Constant VALUE_ANTIALIAS_ON - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_ON = new KeyValue(KEY_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_OFF - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_OFF = new KeyValue(KEY_ANTIALIASING);
+
+    /** 
+     * The Constant KEY_COLOR_RENDERING  - color rendering 
+     * hint key.
+     */
+    public static final Key KEY_COLOR_RENDERING = new KeyImpl(3);
+    
+    /**
+     * The Constant VALUE_COLOR_RENDER_DEFAULT - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_DEFAULT = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_SPEED  - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_SPEED = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_QUALITY - color
+     * rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_QUALITY = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     *  The Constant KEY_DITHERING  - dithering
+     * rendering hint key.
+     */
+    public static final Key KEY_DITHERING = new KeyImpl(4);
+    
+    /**
+     * The Constant VALUE_DITHER_DEFAULT - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DEFAULT = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DISABLE = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_ENABLE = new KeyValue(KEY_DITHERING);
+
+    /** 
+     * The Constant KEY_FRACTIONALMETRICS - fractional metrics
+     * rendering hint key.
+     */
+    public static final Key KEY_FRACTIONALMETRICS = new KeyImpl(5);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_DEFAULT - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_ON - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_ON = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     *  The Constant VALUE_FRACTIONALMETRICS_OFF - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_OFF = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /** 
+     * The Constant KEY_INTERPOLATION - interpolation
+     * rendering hint key.
+     */
+    public static final Key KEY_INTERPOLATION = new KeyImpl(6);
+    
+    /** 
+     * The Constant VALUE_INTERPOLATION_BICUBIC - interpolation
+     * rendering hint value. 
+     */
+    public static final Object VALUE_INTERPOLATION_BICUBIC = new KeyValue(KEY_INTERPOLATION);
+    
+    /**
+     * The Constant VALUE_INTERPOLATION_BILINEAR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_BILINEAR = new KeyValue(KEY_INTERPOLATION);
+    
+    /** The Constant VALUE_INTERPOLATION_NEAREST_NEIGHBOR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR = new KeyValue(KEY_INTERPOLATION);
+
+    /**
+     * The Constant KEY_RENDERING - rendering hint key.
+     */
+    public static final Key KEY_RENDERING = new KeyImpl(7);
+    
+    /** 
+     * The Constant VALUE_RENDER_DEFAULT - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_DEFAULT = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_SPEED - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_SPEED = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_QUALITY - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_QUALITY = new KeyValue(KEY_RENDERING);
+
+    /** 
+     * The Constant KEY_STROKE_CONTROL - stroke control hint key. 
+     */
+    public static final Key KEY_STROKE_CONTROL = new KeyImpl(8);
+    
+    /** 
+     * The Constant VALUE_STROKE_DEFAULT - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_DEFAULT = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_NORMALIZE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_NORMALIZE = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_PURE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_PURE = new KeyValue(KEY_STROKE_CONTROL);
+
+    /** 
+     * The Constant KEY_TEXT_ANTIALIASING - text antialiasing hint key. 
+     */
+    public static final Key KEY_TEXT_ANTIALIASING = new KeyImpl(9);
+    
+    /**
+     *  The Constant VALUE_TEXT_ANTIALIAS_DEFAULT - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_ON - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_ON = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_OFF - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_OFF = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /** The map. */
+    private HashMap<Object, Object> map = new HashMap<Object, Object>();
+    
+    /**
+     * Instantiates a new rendering hints object from specified Map object with defined
+     * key/value pairs or null for empty RenderingHints. 
+     * 
+     * @param map the Map object with defined key/value pairs or null for
+     * empty RenderingHints. 
+     */
+    public RenderingHints(Map<Key, ?> map) {
+        super();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Instantiates a new rendering hints object with the specified key/value pair.
+     * 
+     * @param key the key of hint property.
+     * @param value the value of hint property.
+     */
+    public RenderingHints(Key key, Object value) {
+        super();
+        put(key, value);
+    }
+
+    /**
+     * Adds the properties represented by key/value pairs from the specified
+     * RenderingHints object to current object.
+     * 
+     * @param hints the RenderingHints to be added.
+     */
+    public void add(RenderingHints hints) {
+        map.putAll(hints.map);
+    }
+
+    /**
+     * Puts the specified value to the specified key. Neither the key nor 
+     * the value can be null.
+     * 
+     * @param key the rendering hint key.
+     * @param value the rendering hint value. 
+     * 
+     * @return the previous rendering hint value assigned to the key or null.
+     * 
+     */
+    public Object put(Object key, Object value) {
+        if (!((Key)key).isCompatibleValue(value)) {
+            throw new IllegalArgumentException();
+        }
+
+        return map.put(key, value);
+    }
+
+    /**
+     * Removes the specified key and corresponding value from 
+     * the RenderingHints object.
+     * 
+     * @param key the specified hint key to be removed.
+     * 
+     * @return the object of previous rendering hint value which is 
+     * assigned to the specified key, or null.
+     */
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Gets the value assigned to the specified key.
+     * 
+     * @param key the rendering hint key.
+     * 
+     * @return the object assigned to the specified key.
+     */
+    public Object get(Object key) {
+        return map.get(key);
+    }
+
+    /**
+     * Returns a set of rendering hints keys for current RenderingHints object.
+     * 
+     * @return the set of rendering hints keys. 
+     */
+    public Set<Object> keySet() {
+        return map.keySet();
+    }
+
+    /**
+     * Returns a set of Map.Entry objects which contain current RenderingHint
+     * key/value pairs.
+     * 
+     * @return the a set of mapped RenderingHint key/value pairs.
+     */
+    public Set<Map.Entry<Object, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+    /**
+     * Puts all of the preferences from the specified Map into 
+     * the current RenderingHints object. These mappings replace 
+     * all existing preferences.
+     * 
+     * @param m the specified Map of preferences.
+     */
+    public void putAll(Map<?, ?> m) {
+        if (m instanceof RenderingHints) {
+            map.putAll(((RenderingHints) m).map);
+        } else {
+            Set<?> entries = m.entrySet();
+
+            if (entries != null){
+                Iterator<?> it = entries.iterator();
+                while (it.hasNext()) {
+                    Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
+                    Key key = (Key) entry.getKey();
+                    Object val = entry.getValue();
+                    put(key, val);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Collection of values contained in current RenderingHints object.
+     * 
+     * @return the Collection of RenderingHints's values.
+     */
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains at least one
+     * the value which is equal to the specified Object.
+     * 
+     * @param value the specified Object.
+     * 
+     * @return true, if the specified object is assigned to at least one
+     * RenderingHint's key, false otherwise.
+     */
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains the key
+     * which is equal to the specified Object.
+     * 
+     * @param key the specified Object.
+     * 
+     * @return true, if the RenderingHints object contains the specified Object
+     * as a key, false otherwise.
+     * 
+     */
+    public boolean containsKey(Object key) {
+        if (key == null) {
+            throw new NullPointerException();
+        }
+
+        return map.containsKey(key);
+    }
+
+    /**
+     * Checks whether or not the RenderingHints object contains any 
+     * key/value pairs.
+     * 
+     * @return true, if the RenderingHints object is empty, false otherwise.
+     */
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    /**
+     * Clears the RenderingHints of all key/value pairs.
+     */
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Returns the number of key/value pairs in the RenderingHints.
+     * 
+     * @return the number of key/value pairs.
+     */
+    public int size() {
+        return map.size();
+    }
+
+    /**
+     * Compares the RenderingHints object with the specified object.
+     * 
+     * @param o the specified Object to be compaired.
+     * 
+     * @return true, if the Object is a Map whose key/value pairs 
+     * match this RenderingHints' key/value pairs, 
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map)) {
+            return false;
+        }
+
+        Map<?, ?> m = (Map<?, ?>)o;
+        Set<?> keys = keySet();
+        if (!keys.equals(m.keySet())) {
+            return false;
+        }
+
+        Iterator<?> it = keys.iterator();
+        while (it.hasNext()) {
+            Key key = (Key)it.next();
+            Object v1 = get(key);
+            Object v2 = m.get(key);
+            if (!(v1==null?v2==null:v1.equals(v2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the hash code for this RenderingHints object.
+     * 
+     * @return the hash code for this RenderingHints object.
+     */
+    @Override
+    public int hashCode() {
+        return map.hashCode();
+    }
+
+    /**
+     * Returns the clone of the RenderingHints object with the same contents.
+     * 
+     * @return the clone of the RenderingHints instance.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        RenderingHints clone = new RenderingHints(null);
+        clone.map = (HashMap<Object, Object>)this.map.clone();
+        return clone;
+    }
+
+    /**
+     * Returns the string representation of the RenderingHints object.
+     * 
+     * @return the String object which represents RenderingHints object. 
+     */
+    @Override
+    public String toString() {
+        return "RenderingHints["+map.toString()+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * The RenderingHints.Key class is abstract and defines a base type for 
+     * all RenderingHints keys.
+     */
+    public abstract static class Key {
+        
+        /** The key. */
+        private final int key;
+
+        /**
+         * Instantiates a new key with unique int identifier. 
+         * No two objects of the same subclass with the same integer key
+         * can be instantiated. 
+         * 
+         * @param key the unique key.
+         */
+        protected Key(int key) {
+            this.key = key;
+        }
+
+        /**
+         * Compares the Key object with the specified object.
+         * 
+         * @param o the specified Object to be compaired.
+         * 
+         * @return true, if the Key is equal to the specified object, 
+         * false otherwise.
+         */
+        @Override
+        public final boolean equals(Object o) {
+            return this == o;
+        }
+
+        /**
+         * Returns the hash code for this Key object.
+         * 
+         * @return the hash code for this Key object.
+         */
+        @Override
+        public final int hashCode() {
+            return System.identityHashCode(this);
+        }
+
+        /**
+         * Returns int unique key with which this Key object has been 
+         * instantiated.
+         * 
+         * @return the int unique key with which this Key object has been 
+         * instantiated.
+         */
+        protected final int intKey() {
+            return key;
+        }
+
+        /**
+         * Checks whether or not specified value is compatible with the Key.
+         * 
+         * @param val the Object.
+         * 
+         * @return true, if the specified value is compatible with the Key,
+         * false otherwise.
+         */
+        public abstract boolean isCompatibleValue(Object val);
+    }
+
+    /**
+     * Private implementation of Key class.
+     */
+    private static class KeyImpl extends Key {
+
+        /**
+         * Instantiates a new key impl.
+         * 
+         * @param key the key
+         */
+        protected KeyImpl(int key) {
+            super(key);
+        }
+
+        @Override
+        public boolean isCompatibleValue(Object val) {
+            if (!(val instanceof KeyValue)) {
+                return false;
+            }
+
+            return ((KeyValue)val).key == this;
+        }
+    }
+
+    /**
+     * Private class KeyValue is used as value for Key class instance.
+     */
+    private static class KeyValue {
+        
+        /** The key. */
+        private final Key key;
+
+        /**
+         * Instantiates a new key value.
+         * 
+         * @param key the key
+         */
+        protected KeyValue(Key key) {
+            this.key = key;
+        }
+    }
+}
diff --git a/awt/java/awt/Shape.java b/awt/java/awt/Shape.java
new file mode 100644
index 0000000..3dbad25
--- /dev/null
+++ b/awt/java/awt/Shape.java
@@ -0,0 +1,162 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The Shape interface defines a geometric shape defined by a boundary 
+ * (outline) path. The path outline can be accessed through a 
+ * PathIterator object. The Shape 
+ * interface provides methods for obtaining the bounding box (which is 
+ * the smallest rectangle containing the shape and for obtaining a PathIterator 
+ * object for current Shape, as well as utility methods which 
+ * determine if the Shape contains or intersects a Rectangle or contains a Point.
+ */
+public interface Shape {
+    
+    /**
+     * Checks whether or not the point with specified coordinates lies inside 
+     * the Shape.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * 
+     * @return true, if the specified coordinates lie inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y);
+
+    /**
+     * Checks whether or not the rectangle with specified 
+     * [x, y, width, height] parameters lies inside the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left 
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Shape.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Point2D point);
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Rectangle2D r);
+
+    /**
+     * Gets the bounding rectangle of the Shape. The bounding rectangle
+     * is the smallest rectangle which contains the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle getBounds();
+
+    /**
+     * Gets the Rectangle2D which represents Shape bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle2D getBounds2D();
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the shape's boundary modified 
+     * by the specified AffineTransform.
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at);
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the coordinates of the shapes boundary modified 
+     * by the specified AffineTransform. The flatness parameter
+     * defines the amount of subdivision of the curved segments and
+     * specifies the maximum distance which every point on the 
+     * unflattened transformed curve can deviate from the returned 
+     * flattened path segments.  
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided 
+     * curve is replaced by a straight line connecting the endpoints. 
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness);
+
+    /**
+     * Checks whether or not the interior of rectangular specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the rectangle specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape, otherwise false.
+     * 
+     */
+    public boolean intersects(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the interior of rectangl specified by 
+     * Rectangle2D object intersects the interior of the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Shape, otherwise false.
+     */
+    public boolean intersects(Rectangle2D r);
+}
diff --git a/awt/java/awt/Stroke.java b/awt/java/awt/Stroke.java
new file mode 100644
index 0000000..e6d683d
--- /dev/null
+++ b/awt/java/awt/Stroke.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Stroke interface gives a pen style to be used by the 
+ * Graphics2D interface. It provides a means for getting a stroked version 
+ * of a shape, which is the version that is suitable for drawing via 
+ * the Graphics2D interface. Stroking a shape gives the shape's outline
+ * a width or drawing style. 
+ * <p>
+ * The Draw methods from Graphics2D interface should use the Stroke object for 
+ * rendering the shape's outline. The stroke should be set by 
+ * setStroke(java.awt.Stroke) method of the Graphics2D interface. 
+ * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
+ */
+public interface Stroke {
+    
+    /**
+     * Creates the stroked shape, which is the version that is suitable for drawing via 
+     * the Graphics2D interface. Stroking a shape gives the shape's outline
+     * a width or drawing style.
+     * 
+     * @param p the original shape.
+     * 
+     * @return the stroked shape.
+     */
+    public Shape createStrokedShape(Shape p);
+}
diff --git a/awt/java/awt/Toolkit.java b/awt/java/awt/Toolkit.java
new file mode 100644
index 0000000..0c066b2
--- /dev/null
+++ b/awt/java/awt/Toolkit.java
@@ -0,0 +1,1338 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.event.AWTEventListener;
+import java.awt.event.AWTEventListenerProxy;
+import java.awt.event.InputEvent;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.FontPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.awt.ChoiceStyle;
+import org.apache.harmony.awt.ComponentInternals;
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.ReadOnlyIterator;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.CreationParams;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeEventThread;
+import org.apache.harmony.awt.wtk.ShutdownWatchdog;
+import org.apache.harmony.awt.wtk.Synchronizer;
+import org.apache.harmony.awt.wtk.WTK;
+
+/**
+ * The Toolkit class is the representation of the platform-specific 
+ * Abstract Window Toolkit implementation. Toolkit's subclasses 
+ * are used to bind the various components to particular native 
+ * toolkit implementations.
+ */
+public abstract class Toolkit {
+    
+    /** The Constant RECOURCE_PATH. */
+    private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
+    
+    /** The Constant properties. */
+    private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
+    
+    /** The dispatcher. */
+    Dispatcher dispatcher;
+
+    /** The system event queue core. */
+    private EventQueueCore systemEventQueueCore;
+
+    /** The dispatch thread. */
+    EventDispatchThread dispatchThread;
+
+    /** The native thread. */
+    NativeEventThread nativeThread;
+
+    /** The awt events manager. */
+    protected AWTEventsManager awtEventsManager;
+
+    /**
+     * The Class AWTTreeLock.
+     */
+    private class AWTTreeLock {
+    }
+
+    /** The awt tree lock. */
+    final Object awtTreeLock = new AWTTreeLock();
+
+    /** The synchronizer. */
+    private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
+
+    /** The shutdown watchdog. */
+    final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
+
+    /** The auto number. */
+    final AutoNumber autoNumber = new AutoNumber();
+
+    /** The event type lookup. */
+    final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
+
+    /** The b dynamic layout set. */    
+    private boolean bDynamicLayoutSet = true;
+
+    /** The set of desktop properties that user set directly. */
+    private final HashSet<String> userPropSet = new HashSet<String>();
+
+    /** The desktop properties. */
+    protected Map<String, Object> desktopProperties;
+
+    /** The desktop props support. */
+    protected PropertyChangeSupport desktopPropsSupport;
+
+    /**
+     * For this component the native window is being created
+     * It is used in the callback-driven window creation
+     * (e.g. on Windows in the handler of WM_CREATE event)
+     * to establish the connection between this component
+     * and its native window.
+     */
+    private Object recentNativeWindowComponent;
+
+    /** The wtk. */
+    private WTK wtk;
+
+    /**
+     * The Class ComponentInternalsImpl.
+     */
+    protected final class ComponentInternalsImpl extends ComponentInternals {
+
+        /**
+         * Shutdown.
+         */
+        @Override
+        public void shutdown() {
+            dispatchThread.shutdown();
+        }
+       
+        /**
+         * Sets the desktop property to the specified value and fires a property 
+         * change event.  
+         * 
+         * @param name the name of property.
+         * @param value the new value of property.
+         */
+        @Override
+        public void setDesktopProperty(String name, Object value) {
+            Toolkit.this.setDesktopProperty(name, value);
+        }
+    }
+
+
+    /**
+     * A lot of methods must throw HeadlessException
+     * if <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    static void checkHeadless() throws HeadlessException {
+        if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
+            throw new HeadlessException();
+    }
+
+    /**
+     * Lock awt.
+     */
+    final void lockAWT() {
+        synchronizer.lock();
+    }
+
+    /**
+     * Static lock awt.
+     */
+    static final void staticLockAWT() {
+        ContextStorage.getSynchronizer().lock();
+    }
+
+    /**
+     * Unlock awt.
+     */
+    final void unlockAWT() {
+        synchronizer.unlock();
+    }
+
+    /**
+     * Static unlock awt.
+     */
+    static final void staticUnlockAWT() {
+        ContextStorage.getSynchronizer().unlock();
+    }    
+
+    /**
+     * InvokeAndWait under AWT lock. W/o this method system can hang up.
+     * Added to support modality (Dialog.show() & PopupMenu.show()) from
+     * not event dispatch thread. Use in other cases is not recommended.
+     *
+     * Still can be called only for whole API methods that
+     * cannot be called from other classes API methods.
+     * Examples:
+     *      show() for modal dialogs    - correct, only user can call it,
+     *                                      directly or through setVisible(true)
+     *      setBounds() for components  - incorrect, setBounds()
+     *                                      can be called from layoutContainer()
+     *                                      for layout managers
+     * 
+     * @param runnable the runnable
+     * 
+     * @throws InterruptedException the interrupted exception
+     * @throws InvocationTargetException the invocation target exception
+     */
+    final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
+            InvocationTargetException {
+        synchronizer.storeStateAndFree();
+        try {
+            EventQueue.invokeAndWait(runnable);
+        } finally {
+            synchronizer.lockAndRestoreState();
+        }
+    }
+
+    /**
+     * Gets the synchronizer.
+     * 
+     * @return the synchronizer
+     */
+    final Synchronizer getSynchronizer() {
+        return synchronizer;
+    }
+
+    /**
+     * Gets the wTK.
+     * 
+     * @return the wTK
+     */
+    final WTK getWTK() {
+        return wtk;
+    }
+
+    /**
+     * Gets the property with the specified key and default value. 
+     * This method returns the defValue if the property is not found. 
+     * 
+     * @param propName the name of property.
+     * @param defVal the default value.
+     * 
+     * @return the property value.
+     */
+    public static String getProperty(String propName, String defVal) {
+        if (propName == null) {
+            // awt.7D=Property name is null
+            throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
+        }
+        staticLockAWT();
+        try {
+            String retVal = null;
+            if (properties != null) {
+                try {
+                    retVal = properties.getString(propName);
+                } catch (MissingResourceException e) {
+                } catch (ClassCastException e) {
+                }
+            }
+            return (retVal == null) ? defVal : retVal;
+        } finally {
+            staticUnlockAWT();
+        }
+    }
+    
+    /**
+     * Gets the default Toolkit.
+     * 
+     * @return the default Toolkit
+     */
+    public static Toolkit getDefaultToolkit() {
+        synchronized (ContextStorage.getContextLock()) {
+            if (ContextStorage.shutdownPending()) {
+                return null;
+            }
+            Toolkit defToolkit = ContextStorage.getDefaultToolkit();
+            if (defToolkit != null) {
+                return defToolkit;
+            }
+            staticLockAWT();
+            try {
+                defToolkit = GraphicsEnvironment.isHeadless() ?
+                        new HeadlessToolkit() : new ToolkitImpl();
+                ContextStorage.setDefaultToolkit(defToolkit);
+                return defToolkit;
+            } finally {
+                staticUnlockAWT();
+            }
+            //TODO: read system property named awt.toolkit
+            //and create an instance of the specified class,
+            //by default use ToolkitImpl
+        }
+    }
+    
+    /**
+     * Gets the default Font.
+     * 
+     * @return the derault Font for Toolkit.
+     */
+    Font getDefaultFont() {
+        return wtk.getSystemProperties().getDefaultFont();
+    }
+    
+    /**
+     * Load resources.
+     * 
+     * @param path the path
+     * 
+     * @return the resource bundle
+     */
+    private static ResourceBundle loadResources(String path) {
+        try {
+            return ResourceBundle.getBundle(path);
+        } catch (MissingResourceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the wTK class name.
+     * 
+     * @return the wTK class name
+     */
+    private static String getWTKClassName() {
+        return "com.android.internal.awt.AndroidWTK";
+    }
+
+    /**
+     * Gets the component by id.
+     * 
+     * @param id the id
+     * 
+     * @return the component by id
+     */
+    Component getComponentById(long id) {
+        if (id == 0) {
+            return null;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the GraphicsFactory.
+     * 
+     * @return the GraphicsFactory object.
+     */
+    public GraphicsFactory getGraphicsFactory() {
+        return wtk.getGraphicsFactory();
+    }
+
+    /**
+     * Instantiates a new toolkit.
+     */
+    public Toolkit() {        
+        init();
+    }
+
+    /**
+     * Inits AWT.
+     */
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            new EventQueue(this); // create the system EventQueue
+            dispatcher = new Dispatcher(this);
+            final String className = getWTKClassName();
+            desktopProperties = new HashMap<String, Object>();
+            desktopPropsSupport = new PropertyChangeSupport(this);
+            awtEventsManager = new AWTEventsManager();
+            dispatchThread = new EventDispatchThread(this, dispatcher);
+            nativeThread = new NativeEventThread();
+            NativeEventThread.Init init = new NativeEventThread.Init() {
+                public WTK init() {
+                    wtk = createWTK(className);
+                    wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
+                    synchronizer.setEnvironment(wtk, dispatchThread);
+                    ContextStorage.setWTK(wtk);
+                    return wtk;
+                }
+            };
+            nativeThread.start(init);
+            dispatchThread.start();
+            wtk.getNativeEventQueue().awake();
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    /**
+     * Synchronizes this toolkit's graphics.
+     */
+    public abstract void sync();
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * @param a0 the image to be checked.
+     * @param a1 the width of scaled image for which the status is being checked, or -1.
+     * @param a2 the height of scaled image for which the status is being checked, or -1.
+     * @param a3 the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags which give the current state of the image data.
+     */
+    public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
+   
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param a0 the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public abstract Image createImage(ImageProducer a0);
+
+    /**
+     * Creates the image from the specified byte array, offset and length.
+     * The byte array should contain data with image format supported by 
+     * Toolkit such as JPEG, GIF, or PNG.  
+     * 
+     * @param a0 the byte array with the image data.
+     * @param a1 the offset of the beggining the image data in the byte array.
+     * @param a2 the length of the image data in the byte array.
+     * 
+     * @return the created Image.
+     */
+    public abstract Image createImage(byte[] a0, int a1, int a2);
+
+    /**
+     * Creates the image using image data from the specified URL.
+     * 
+     * @param a0 the URL for extracting image data.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(URL a0);
+
+    /**
+     * Creates the image using image data from the specified file.
+     * 
+     * @param a0 the file name which contains image data of supported format.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(String a0);
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel of Toolkit's screen.
+     * 
+     * @throws HeadlessException if the 
+     * GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract ColorModel getColorModel() throws HeadlessException;
+    
+    /**
+     * Gets the screen device metrics for the specified font.
+     * 
+     * @param font the Font.
+     * 
+     * @return the FontMetrics for the specified Font.
+     * 
+     * @deprecated Use getLineMetrics method from Font class.
+     */
+        
+    @Deprecated
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Prepares the specified image for rendering on the screen with the
+     * specified size.
+     * 
+     * @param a0 the Image to be prepared.
+     * @param a1 the width of the screen representation or -1 for the current screen.
+     * @param a2 the height of the screen representation or -1 for the current screen.
+     * @param a3 the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true, if image is fully prepared; false otherwise.
+     */
+    public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
+
+    /**
+     * Creates an audio beep.
+     */
+    public abstract void beep();
+
+    /**
+     * Returns the array of font names which are available in this Toolkit.
+     * 
+     * @return the array of font names which are available in this Toolkit.
+     * 
+     * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
+     */
+    @Deprecated
+    public abstract String[] getFontList();
+    
+    /**
+     * Gets the the Font implementation using the specified peer 
+     * interface.
+     * 
+     * @param a0 the Font name to be implemented.
+     * @param a1 the the font style: PLAIN, BOLD, ITALIC.
+     * 
+     * @return the FontPeer implementation of the specified Font.
+     * 
+     * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
+     */
+
+    @Deprecated
+    protected abstract FontPeer getFontPeer(String a0, int a1);
+
+    /**
+     * Gets the image from the specified file which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image file name.
+     * 
+     * @param a0 the file name which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(String a0);
+
+    /**
+     * Gets the image from the specified URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image URL.
+     * 
+     * @param a0 the URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(URL a0);
+
+    /**
+     * Gets the screen resolution.
+     * 
+     * @return the screen resolution.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract int getScreenResolution() throws HeadlessException;
+
+    /**
+     * Gets the screen size.
+     * 
+     * @return a Dimension object containing the width and height of
+     * the screen.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Dimension getScreenSize() throws HeadlessException;
+
+    /**
+     * Gets the EventQueue instance without checking access.
+     * 
+     * @return the system EventQueue.
+     */
+    protected abstract EventQueue getSystemEventQueueImpl();
+
+    /**
+     * Returns a map of text attributes for the abstract level description 
+     * of the specified input method highlight, or null if no mapping is found. 
+     *  
+     * @param highlight the InputMethodHighlight.
+     * 
+     * @return the Map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException;
+
+    /**
+     * Map input method highlight impl.
+     * 
+     * @param highlight the highlight
+     * 
+     * @return the map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
+        wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
+        return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
+    }
+
+    /**
+     * Adds the specified PropertyChangeListener listener for the specified
+     * property.
+     * 
+     * @param propName the property name for which the specified PropertyChangeListener
+     * will be added. 
+     * @param l the PropertyChangeListener object.
+     */
+    public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+        } finally {
+            unlockAWT();
+        }
+        if (l != null) { // there is no guarantee that null listener will not be added
+            desktopPropsSupport.addPropertyChangeListener(propName, l);
+        }
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit.
+     * 
+     * @return an array of the property change listeners registered with
+     * this Toolkit. 
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return desktopPropsSupport.getPropertyChangeListeners();
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit for notification regarding the specified property.
+     * 
+     * @param propName the property name for which the PropertyChangeListener
+     * was registered.
+     * 
+     * @return the array of PropertyChangeListeners registered for the specified 
+     * property name.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
+        return desktopPropsSupport.getPropertyChangeListeners(propName);
+    }
+
+    /**
+     * Removes the specified property change listener registered for the
+     * specified property name.
+     * 
+     * @param propName the property name.
+     * @param l the PropertyChangeListener registered for the specified property name.
+     */
+    public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
+        desktopPropsSupport.removePropertyChangeListener(propName, l);
+    }
+    
+    /**
+     * Creates a custom cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @param img the image of activated cursor.
+     * @param hotSpot the Point giving the coordinates of the cursor's hot spot. 
+     * @param name the cursor description.
+     * 
+     * @return the cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @throws IndexOutOfBoundsException if the hot spot values are outside  
+     * the bounds of the cursor.
+     * @throws HeadlessException if isHeadless() method of GraphicsEnvironment
+     * class returns true.
+     */
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+            throws IndexOutOfBoundsException, HeadlessException {
+        lockAWT();
+        try {
+            int w = img.getWidth(null), x = hotSpot.x;
+            int h = img.getHeight(null), y = hotSpot.y;
+            if (x < 0 || x >= w || y < 0 || y >= h) {
+                // awt.7E=invalid hotSpot
+                throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
+            }
+            return new Cursor(name, img, hotSpot);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the supported cursor dimension which is closest to the 
+     * specified width and height. If the Toolkit only supports a single 
+     * cursor size, this method should return the supported cursor size.
+     * If custom cursor is not supported, a dimension of 0, 0 should be
+     * returned.
+     * 
+     * @param prefWidth the preffered cursor width.
+     * @param prefHeight the preffered cursor height.
+     * 
+     * @return the supported cursor dimension which is closest to the 
+     * specified width and height.
+     * 
+     * @throws HeadlessException if GraphicsEnvironment.isHeadless() 
+     * returns true.
+     */
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the value for the specified desktop property. 
+     * 
+     * @param propName the property name.
+     * 
+     * @return the Object that is the property's value.
+     */
+    public final Object getDesktopProperty(String propName) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+            if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
+                // dynamicLayoutSupported is special case
+                return Boolean.valueOf(isDynamicLayoutActive());
+            }
+            Object val = desktopProperties.get(propName);
+            if (val == null) {
+                // try to lazily load prop value
+                // just for compatibility, our lazilyLoad is empty
+                val = lazilyLoadDesktopProperty(propName);
+            }
+            return val;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the locking key state for the specified key.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * 
+     * @return true if the specified key code is in the locked state,
+     * false otherwise.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be retrieved, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public boolean getLockingKeyState(int a0) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return true;
+    }
+
+    /**
+     * Returns the maximum number of colors which the Toolkit supports for
+     * custom cursor.
+     * 
+     * @return the maximum cursor colors.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMaximumCursorColors() throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getMaximumCursorColors();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the menu shortcut key mask.
+     *
+     * @return the menu shortcut key mask.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        lockAWT();
+        try {
+            return InputEvent.CTRL_MASK;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the screen insets.
+     * 
+     * @param gc the GraphicsConfiguration.
+     * 
+     * @return the insets of this toolkit.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        if (gc == null) {
+            throw new NullPointerException();
+        }
+        lockAWT();
+        try {
+            return new Insets(0, 0, 0, 0); //TODO: get real screen insets
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the system EventQueue instance. 
+     * If the default implementation of checkAwtEventQueueAccess is used,
+     * then this results of a call to the security manager's checkPermission
+     * method with an AWTPermission("accessEventQueue") permission.
+     * 
+     * @return the system EventQueue instance.
+     */
+    public final EventQueue getSystemEventQueue() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkAwtEventQueueAccess();
+        }
+        return getSystemEventQueueImpl();
+    }
+
+    /** 
+     * Gets the system event queue core.
+     * 
+     * @return the system event queue core
+     */
+    EventQueueCore getSystemEventQueueCore() {
+        return systemEventQueueCore;
+    }
+    
+    /**
+     * Sets the system event queue core.
+     * 
+     * @param core the new system event queue core
+     */
+    void setSystemEventQueueCore(EventQueueCore core) {
+        systemEventQueueCore = core;
+    }
+
+    /**
+     * Initialize the desktop properties.
+     */
+    protected void initializeDesktopProperties() {
+        lockAWT();
+        try {
+            wtk.getSystemProperties().init(desktopProperties);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if dynamic layout of Containers is active or not.
+     * 
+     * @return true, if is dynamic layout of Containers is active,
+     * false otherwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        lockAWT();
+        try {
+            // always return true
+            return true;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+
+    /**
+     * Returns if the layout of Containers is checked dynamically during resizing,
+     * or statically after resizing is completed. 
+     * 
+     * @return true, if if the layout of Containers is checked dynamically during 
+     * resizing; false, if the layout of Containers is checked statically after 
+     * resizing is completed. 
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        lockAWT();
+        try {
+            return bDynamicLayoutSet;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the specified frame state is supported by Toolkit or not.
+     * 
+     * @param state the frame state.
+     * 
+     * @return true, if frame state is supported; false othrwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getWindowFactory().isWindowStateSupported(state);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Loads the value of the desktop property with the specified property name.
+     * 
+     * @param propName the property name.
+     * 
+     * @return the desktop property values.
+     */
+    protected Object lazilyLoadDesktopProperty(String propName) {
+        return null;
+    }
+
+    /**
+     * Loads the current system color values to the specified array.
+     * 
+     * @param colors the array where the current system color values 
+     * are written by this method.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected void loadSystemColors(int[] colors) throws HeadlessException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the value of the desktop property with the specified name.
+     * 
+     * @param propName the property's name.
+     * @param value the property's value.
+     */
+    protected final void setDesktopProperty(String propName, Object value) {
+        Object oldVal;
+        lockAWT();
+        try {
+            oldVal = getDesktopProperty(propName);
+            userPropSet.add(propName);
+            desktopProperties.put(propName, value);
+        } finally {
+            unlockAWT();
+        }
+        desktopPropsSupport.firePropertyChange(propName, oldVal, value);
+    }
+
+    /**
+     * Sets the layout state, whether the Container layout is checked 
+     * dynamically during resizing, or statically after resizing is completed. 
+     * 
+     * @param dynamic the new dynamic layout state - if true the layout of 
+     * Containers is checked dynamically during resizing, if false -
+     * statically after resizing is completed.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        lockAWT();
+        try {
+            bDynamicLayoutSet = dynamic;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locking key state for the specified key code.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * @param a1 the state - true to set the specified key code to the locked state,
+     * false - to unlock it.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be set, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return;
+    }
+
+
+    /**
+     * On queue empty.
+     */
+    void onQueueEmpty() {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Creates the wtk.
+     * 
+     * @param clsName the cls name
+     * 
+     * @return the wTK
+     */
+    private WTK createWTK(String clsName) {
+        WTK newWTK = null;
+        try {
+            newWTK = (WTK) Class.forName(clsName).newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return newWTK;
+    }
+
+    /**
+     * Connect the component to its native window
+     * @param winId - id of native window just created
+     */
+    boolean onWindowCreated(long winId) {
+        return false;
+    }
+
+    /**
+     * Gets the native event queue.
+     * 
+     * @return the native event queue
+     */
+    NativeEventQueue getNativeEventQueue() {
+        return wtk.getNativeEventQueue();
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for
+     * 
+     * @param type - Java Cursor type
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createNativeCursor(int type) {
+        return wtk.getCursorFactory().getCursor(type);
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for custom cursor
+     * 
+     * @param img the img
+     * @param hotSpot the hot spot
+     * @param name the name
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
+        return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
+    }
+
+    /**
+     * Adds an AWTEventListener to the Toolkit to listen for events
+     * of types corresponding to bits in the specified event mask. 
+     * Event masks are defined in AWTEvent class.
+     * 
+     * @param listener the AWTEventListener.
+     * @param eventMask he bitmask of event types.
+     */
+    public void addAWTEventListener(AWTEventListener listener, long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.addAWTEventListener(listener, eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the specified awt event listener.
+     * 
+     * @param listener the AWTEventListener to be removed.
+     */
+    public void removeAWTEventListener(AWTEventListener listener) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.removeAWTEventListener(listener);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the array of all AWT event listeners registered with this Toolkit.
+     * 
+     * @return the array of all AWT event listeners registered with this Toolkit.
+     */
+    public AWTEventListener[] getAWTEventListeners() {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the array of the AWT event listeners registered with this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     * 
+     * @param eventMask the bit mask of event type.
+     * 
+     * @return the array of the AWT event listeners registered in this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     */
+    public AWTEventListener[] getAWTEventListeners(long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners(eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatch awt event.
+     * 
+     * @param event the event
+     */
+    void dispatchAWTEvent(AWTEvent event) {
+        awtEventsManager.dispatchAWTEvent(event);
+    }
+    
+    /**
+     * The Class AWTEventsManager.
+     */
+    final class AWTEventsManager {
+
+        /** The permission. */
+        AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
+
+        /** The listeners. */
+        private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
+
+        /**
+         * Adds the awt event listener.
+         * 
+         * @param listener the listener
+         * @param eventMask the event mask
+         */
+        void addAWTEventListener(AWTEventListener listener, long eventMask) {
+            if (listener != null) {
+                listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
+            }
+        }
+
+        /**
+         * Removes the awt event listener.
+         * 
+         * @param listener the listener
+         */
+        void removeAWTEventListener(AWTEventListener listener) {
+            if (listener != null) {
+                for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                    if (listener == proxy.getListener()) {
+                        listeners.removeUserListener(proxy);
+                        return;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners() {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                listenersSet.add(proxy.getListener());
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @param eventMask the event mask
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners(long eventMask) {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & eventMask) == eventMask) {
+                    listenersSet.add(proxy.getListener());
+                }
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Dispatch awt event.
+         * 
+         * @param event the event
+         */
+        void dispatchAWTEvent(AWTEvent event) {
+            AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
+            if (descriptor == null) {
+                return;
+            }
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
+                    proxy.eventDispatched(event);
+                }
+            }
+        }
+    }
+    
+    /**
+     * The Class AutoNumber.
+     */
+    static final class AutoNumber {
+
+        /** The next component. */
+        int nextComponent = 0;
+
+        /** The next canvas. */
+        int nextCanvas = 0;
+
+        /** The next panel. */
+        int nextPanel = 0;
+
+        /** The next window. */
+        int nextWindow = 0;
+
+        /** The next frame. */
+        int nextFrame = 0;
+
+        /** The next dialog. */
+        int nextDialog = 0;
+
+        /** The next button. */
+        int nextButton = 0;
+
+        /** The next menu component. */
+        int nextMenuComponent = 0;
+
+        /** The next label. */
+        int nextLabel = 0;
+
+        /** The next check box. */
+        int nextCheckBox = 0;
+
+        /** The next scrollbar. */
+        int nextScrollbar = 0;
+
+        /** The next scroll pane. */
+        int nextScrollPane = 0;
+
+        /** The next list. */
+        int nextList = 0;
+
+        /** The next choice. */
+        int nextChoice = 0;
+
+        /** The next file dialog. */
+        int nextFileDialog = 0;
+
+        /** The next text area. */
+        int nextTextArea = 0;
+
+        /** The next text field. */
+        int nextTextField = 0;
+    }
+    
+    private class Lock {
+    }
+
+        /** The lock. */
+    private final Object lock = new Lock();
+        
+}
diff --git a/awt/java/awt/ToolkitImpl.java b/awt/java/awt/ToolkitImpl.java
new file mode 100644
index 0000000..5015aef
--- /dev/null
+++ b/awt/java/awt/ToolkitImpl.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.awt;
+
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.*;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.Map;
+import org.apache.harmony.awt.gl.image.*;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+class ToolkitImpl extends Toolkit {
+	
+    static final Hashtable<Serializable, Image> imageCache = new Hashtable<Serializable, Image>();
+
+    @Override
+    public void sync() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return ImageObserver.ALLBITS;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return ImageObserver.ALLBITS;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.checkImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(ImageProducer producer) {
+        lockAWT();
+        try {
+            return new OffscreenImage(producer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new ByteArrayDecodingImageSource(imagedata, imageoffset,
+                    imagelength));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(URL url) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new URLDecodingImageSource(url));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(String filename) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new FileDecodingImageSource(filename));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        lockAWT();
+        try {
+            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
+                    .getDefaultConfiguration().getColorModel();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public FontMetrics getFontMetrics(Font font) {
+        lockAWT();
+        try {
+        	GraphicsFactory gf = getGraphicsFactory();
+            return gf.getFontMetrics(font);
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    @Override
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return true;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return true;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.prepareImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public void beep() {
+        lockAWT();
+        try {
+        	// ???AWT: is there nothing to be implemented here?
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public String[] getFontList() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    protected FontPeer getFontPeer(String a0, int a1) {
+        lockAWT();
+        try {
+            return null;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image getImage(String filename) {
+        return getImage(filename, this);
+    }
+
+    static Image getImage(String filename, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = (filename == null ? null : imageCache.get(filename));
+
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(filename);
+                    imageCache.put(filename, im);
+                } catch (Exception e) {
+                }
+            }
+
+            return im;
+        }
+    }
+
+    @Override
+    public Image getImage(URL url) {
+        return getImage(url, this);
+    }
+
+    static Image getImage(URL url, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = imageCache.get(url);
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(url);
+                    imageCache.put(url, im);
+                } catch (Exception e) {
+                }
+            }
+            return im;
+        }
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        lockAWT();
+        try {
+        	return 62;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Dimension getScreenSize() {
+        lockAWT();
+        try {
+            DisplayMode dm = GraphicsEnvironment.getLocalGraphicsEnvironment()
+                    .getDefaultScreenDevice().getDisplayMode();
+            return new Dimension(dm.getWidth(), dm.getHeight());
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        lockAWT();
+        try {
+            return mapInputMethodHighlightImpl(highlight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    protected EventQueue getSystemEventQueueImpl() {
+        return getSystemEventQueueCore().getActiveEventQueue();
+    }
+}
diff --git a/awt/java/awt/Transparency.java b/awt/java/awt/Transparency.java
new file mode 100644
index 0000000..9793114
--- /dev/null
+++ b/awt/java/awt/Transparency.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Transparency interface defines transparency's general modes.
+ */
+public interface Transparency {
+
+    /** The Constant OPAQUE represents completely opaque data,
+     * all pixels have an alpha value of 1.0. 
+     */
+    public static final int OPAQUE = 1;
+
+    /** The Constant BITMASK represents data which can be either 
+     * completely opaque, with an alpha value of 1.0, or completely 
+     * transparent, with an alpha value of 0.0.
+     */
+    public static final int BITMASK = 2;
+
+    /** The Constant TRANSLUCENT represents data which alpha value
+     * can vary between and including 0.0 and 1.0. */
+    public static final int TRANSLUCENT = 3;
+
+    /**
+     * Gets the transparency mode.
+     * 
+     * @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.  
+     */
+    public int getTransparency();
+
+}
+
diff --git a/awt/java/awt/color/CMMException.java b/awt/java/awt/color/CMMException.java
new file mode 100644
index 0000000..16fe76e
--- /dev/null
+++ b/awt/java/awt/color/CMMException.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The CMMException is thrown as soon as a native CMM error
+ * occures.
+ */
+public class CMMException extends java.lang.RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5775558044142994965L;
+
+    /**
+     * Instantiates a new CMM exception with detail message.
+     * 
+     * @param s the String - detail message.
+     */
+    public CMMException (String s) {
+        super (s);
+    }
+}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
new file mode 100644
index 0000000..f961514
--- /dev/null
+++ b/awt/java/awt/color/ColorSpace.java
@@ -0,0 +1,340 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.Serializable;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorSpace class defines a color space type for a Color and provides methods
+ * for arrays of color component operations.
+ */
+public abstract class ColorSpace implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -409452704308689724L;
+
+    /** The Constant TYPE_XYZ indicates XYZ color space type. */
+    public static final int TYPE_XYZ = 0;
+
+    /** The Constant TYPE_Lab indicates Lab color space type. */
+    public static final int TYPE_Lab = 1;
+
+    /** The Constant TYPE_Luv indicates Luv color space type. */
+    public static final int TYPE_Luv = 2;
+
+    /** The Constant TYPE_YCbCr indicates YCbCr color space type. */
+    public static final int TYPE_YCbCr = 3;
+
+    /** The Constant TYPE_Yxy indicates Yxy color space type. */
+    public static final int TYPE_Yxy = 4;
+
+    /** The Constant TYPE_RGB indicates RGB color space type. */
+    public static final int TYPE_RGB = 5;
+
+    /** The Constant TYPE_GRAY indicates Gray color space type. */
+    public static final int TYPE_GRAY = 6;
+
+    /** The Constant TYPE_HSV indicates HSV color space type. */
+    public static final int TYPE_HSV = 7;
+
+    /** The Constant TYPE_HLS indicates HLS color space type. */
+    public static final int TYPE_HLS = 8;
+
+    /** The Constant TYPE_CMYK indicates CMYK color space type. */
+    public static final int TYPE_CMYK = 9;
+
+    /** The Constant TYPE_CMY indicates CMY color space type. */
+    public static final int TYPE_CMY = 11;
+
+    /** The Constant TYPE_2CLR indicates color spaces with 2 components. */
+    public static final int TYPE_2CLR = 12;
+
+    /** The Constant TYPE_3CLR indicates color spaces with 3 components. */
+    public static final int TYPE_3CLR = 13;
+
+    /** The Constant TYPE_4CLR indicates color spaces with 4 components. */
+    public static final int TYPE_4CLR = 14;
+
+    /** The Constant TYPE_5CLR indicates color spaces with 5 components. */
+    public static final int TYPE_5CLR = 15;
+
+    /** The Constant TYPE_6CLR indicates color spaces with 6 components. */
+    public static final int TYPE_6CLR = 16;
+
+    /** The Constant TYPE_7CLR indicates color spaces with 7 components. */
+    public static final int TYPE_7CLR = 17;
+
+    /** The Constant TYPE_8CLR indicates color spaces with 8 components. */
+    public static final int TYPE_8CLR = 18;
+
+    /** The Constant TYPE_9CLR indicates color spaces with 9 components. */
+    public static final int TYPE_9CLR = 19;
+
+    /** The Constant TYPE_ACLR indicates color spaces with 10 components. */
+    public static final int TYPE_ACLR = 20;
+
+    /** The Constant TYPE_BCLR indicates color spaces with 11 components. */
+    public static final int TYPE_BCLR = 21;
+
+    /** The Constant TYPE_CCLR indicates color spaces with 12 components. */
+    public static final int TYPE_CCLR = 22;
+
+    /** The Constant TYPE_DCLR indicates color spaces with 13 components. */
+    public static final int TYPE_DCLR = 23;
+
+    /** The Constant TYPE_ECLR indicates color spaces with 14 components. */
+    public static final int TYPE_ECLR = 24;
+
+    /** The Constant TYPE_FCLR indicates color spaces with 15 components. */
+    public static final int TYPE_FCLR = 25;
+
+    /** The Constant CS_sRGB indicates standard RGB color space.*/
+    public static final int CS_sRGB = 1000;
+
+    /** The Constant CS_LINEAR_RGB indicates linear RGB color space. */
+    public static final int CS_LINEAR_RGB = 1004;
+
+    /** The Constant CS_CIEXYZ indicates CIEXYZ conversion color space. */
+    public static final int CS_CIEXYZ = 1001;
+
+    /** The Constant CS_PYCC indicates Photo YCC conversion color space. */
+    public static final int CS_PYCC = 1002;
+
+    /** The Constant CS_GRAY indicates linear gray scale color space. */
+    public static final int CS_GRAY = 1003;
+
+    /** The cs_ gray. */
+    private static ColorSpace cs_Gray = null;
+    
+    /** The cs_ pycc. */
+    private static ColorSpace cs_PYCC = null;
+    
+    /** The cs_ ciexyz. */
+    private static ColorSpace cs_CIEXYZ = null;
+    
+    /** The cs_ lrgb. */
+    private static ColorSpace cs_LRGB = null;
+    
+    /** The cs_s rgb. */
+    private static ColorSpace cs_sRGB = null;
+
+    /** The type. */
+    private int type;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a ColorSpace with the specified
+     * ColorSpace type and number of components.
+     * 
+     * @param type the type of color space.
+     * @param numcomponents the number of components.
+     */
+    protected ColorSpace(int type, int numcomponents) {
+        this.numComponents = numcomponents;
+        this.type = type;
+    }
+
+    /**
+     * Gets the name of the component for the specified component index.
+     * 
+     * @param idx the index of the component.
+     * 
+     * @return the name of the component.
+     */
+    public String getName(int idx) {
+        if (idx < 0 || idx > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", idx)); //$NON-NLS-1$
+        }
+
+      return "Unnamed color component #" + idx; //$NON-NLS-1$
+    }
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the RGB color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * RGB color space.
+     */
+    public abstract float[] toRGB(float[] colorvalue);
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the CS_CIEXYZ color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * CS_CIEXYZ color space. 
+     */
+    public abstract float[] toCIEXYZ(float[] colorvalue);
+
+    /**
+     * Performs color transformation from the RGB color space 
+     * into this ColorSpace.
+     * 
+     * @param rgbvalue a float array in the RGB color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromRGB(float[] rgbvalue);
+
+    /**
+     * Performs color transformation from the CS_CIEXYZ color space 
+     * into this ColorSpace.
+     * 
+     * @param colorvalue a float array in the CS_CIEXYZ color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+    /**
+     * Gets the minimum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the miniimum normalized value of the component.
+     */
+    public float getMinValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the maximum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the maximum normalized value of the component.
+     */
+    public float getMaxValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 1;
+    }
+
+    /**
+     * Checks if this ColorSpace has CS_sRGB type or not.
+     * 
+     * @return true, if this ColorSpace has CS_sRGB type, 
+     * false otherwise.
+     */
+    public boolean isCS_sRGB() {
+        // If our color space is sRGB, then cs_sRGB
+        // is already initialized
+        return (this == cs_sRGB);
+    }
+
+    /**
+     * Gets the type of the ColorSpace.
+     * 
+     * @return the type of the ColorSpace.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the number of components for this ColorSpace.
+     * 
+     * @return the number of components.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+
+    /**
+     * Gets the single instance of ColorSpace with the specified
+     * ColorSpace: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_GRAY, 
+     * or CS_PYCC.
+     * 
+     * @param colorspace the identifier of the specified Colorspace.
+     * 
+     * @return the single instance of the desired ColorSpace.
+     */
+    public static ColorSpace getInstance(int colorspace) {
+        switch (colorspace) {
+            case CS_sRGB:
+                if (cs_sRGB == null) {
+                    cs_sRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_sRGB));
+                    LUTColorConverter.sRGB_CS = cs_sRGB;
+                            //ICC_Profile.getInstance (CS_sRGB));
+                }
+                return cs_sRGB;
+            case CS_CIEXYZ:
+                if (cs_CIEXYZ == null) {
+                    cs_CIEXYZ = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_CIEXYZ));
+                            //ICC_Profile.getInstance (CS_CIEXYZ));
+                }
+                return cs_CIEXYZ;
+            case CS_GRAY:
+                if (cs_Gray == null) {
+                    cs_Gray = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_GRAY));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_GRAY));
+                }
+                return cs_Gray;
+            case CS_PYCC:
+                if (cs_PYCC == null) {
+                    cs_PYCC = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_PYCC));
+                            //ICC_Profile.getInstance (CS_PYCC));
+                }
+                return cs_PYCC;
+            case CS_LINEAR_RGB:
+                if (cs_LRGB == null) {
+                    cs_LRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_LINEAR_RGB));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_LINEAR_RGB));
+                }
+                return cs_LRGB;
+            default:
+        }
+
+        // Unknown argument passed
+        // awt.16B=Not a predefined colorspace
+        throw new IllegalArgumentException(Messages.getString("Not a predefined colorspace")); //$NON-NLS-1$
+    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ICC_ColorSpace.java b/awt/java/awt/color/ICC_ColorSpace.java
new file mode 100644
index 0000000..5ece2ef
--- /dev/null
+++ b/awt/java/awt/color/ICC_ColorSpace.java
@@ -0,0 +1,379 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import java.io.*;
+
+/**
+ * ICC_ColorSpace class implements ColorSpace abstract class and 
+ * represents device independent and device dependent color spaces.
+ * This color space is based on the International Color Consortium 
+ * Specification (ICC) File Format for Color Profiles: 
+ * <a href="http://www.color.org">http://www.color.org</a>
+ */
+public class ICC_ColorSpace extends ColorSpace {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3455889114070431483L;
+
+    // Need to keep compatibility with serialized form
+    /** The Constant serialPersistentFields. */
+    private static final ObjectStreamField[]
+      serialPersistentFields = {
+        new ObjectStreamField("thisProfile", ICC_Profile.class), //$NON-NLS-1$
+        new ObjectStreamField("minVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("maxVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("diffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("invDiffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("needScaleInit", Boolean.TYPE) //$NON-NLS-1$
+    };
+
+
+   /**
+    * According to ICC specification (from http://www.color.org)
+    * "For the CIEXYZ encoding, each component (X, Y, and Z)
+    * is encoded as a u1Fixed15Number".
+    * This means that max value for this encoding is 1 + (32767/32768)
+    */
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+    
+    /** The Constant MAX_SHORT. */
+    private static final float MAX_SHORT = 65535f;
+    
+    /** The Constant INV_MAX_SHORT. */
+    private static final float INV_MAX_SHORT = 1f/MAX_SHORT;
+    
+    /** The Constant SHORT2XYZ_FACTOR. */
+    private static final float SHORT2XYZ_FACTOR = MAX_XYZ/MAX_SHORT;
+    
+    /** The Constant XYZ2SHORT_FACTOR. */
+    private static final float XYZ2SHORT_FACTOR = MAX_SHORT/MAX_XYZ;
+
+    /** The profile. */
+    private ICC_Profile profile = null;
+    
+    /** The min values. */
+    private float minValues[] = null;
+    
+    /** The max values. */
+    private float maxValues[] = null;
+
+    // cache transforms here - performance gain
+    /** The to rgb transform. */
+    private ICC_Transform toRGBTransform = null;
+    
+    /** The from rgb transform. */
+    private ICC_Transform fromRGBTransform = null;
+    
+    /** The to xyz transform. */
+    private ICC_Transform toXYZTransform = null;
+    
+    /** The from xyz transform. */
+    private ICC_Transform fromXYZTransform = null;
+
+    /** The converter. */
+    private final ColorConverter converter = new ColorConverter();
+    
+    /** The scaler. */
+    private final ColorScaler scaler = new ColorScaler();
+    
+    /** The scaling data loaded. */
+    private boolean scalingDataLoaded = false;
+
+    /** The resolved deserialized inst. */
+    private ICC_ColorSpace resolvedDeserializedInst;
+
+    /**
+     * Instantiates a new ICC color space from an ICC_Profile object.
+     * 
+     * @param pf the ICC_Profile object.
+     */
+    public ICC_ColorSpace(ICC_Profile pf) {
+        super(pf.getColorSpaceType(), pf.getNumComponents());
+
+        int pfClass = pf.getProfileClass();
+
+        switch (pfClass) {
+            case ICC_Profile.CLASS_COLORSPACECONVERSION:
+            case ICC_Profile.CLASS_DISPLAY:
+            case ICC_Profile.CLASS_OUTPUT:
+            case ICC_Profile.CLASS_INPUT:
+                break; // OK, it is color conversion profile
+            default:
+                // awt.168=Invalid profile class.
+                throw new IllegalArgumentException(Messages.getString("awt.168")); //$NON-NLS-1$
+        }
+
+        profile = pf;
+        fillMinMaxValues();
+    }
+
+    /**
+     * Returns the ICC_Profile for this ICC_ColorSpace.
+     * 
+     * @return the ICC_Profile for this ICC_ColorSpace.
+     */
+    public ICC_Profile getProfile() {
+        if (profile instanceof ICC_ProfileStub) {
+            profile = ((ICC_ProfileStub) profile).loadProfile();
+        }
+
+        return profile;
+    }
+
+    @Override
+    public float[] toRGB(float[] colorvalue) {
+        if (toRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), sRGBProfile};
+            toRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toRGBTransform, data, null);
+
+        // unscale to sRGB
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * INV_MAX_SHORT;
+        res[1] = ((converted[1] & 0xFFFF)) * INV_MAX_SHORT;
+        res[2] = ((converted[2] & 0xFFFF)) * INV_MAX_SHORT;
+
+        return res;
+    }
+
+    @Override
+    public float[] toCIEXYZ(float[] colorvalue) {
+        if (toXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), xyzProfile};
+            try {
+                int[] intents = {
+                        ICC_Profile.icRelativeColorimetric,
+                        ICC_Profile.icPerceptual};
+                toXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                toXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toXYZTransform, data, null);
+
+        // unscale to XYZ
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[1] = ((converted[1] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[2] = ((converted[2] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+
+        return res;
+    }
+
+    @Override
+    public float[] fromRGB(float[] rgbvalue) {
+        if (fromRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {sRGBProfile, getProfile()};
+            fromRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        // scale rgb value to short
+        short[] scaledRGBValue = new short[3];
+        scaledRGBValue[0] = (short)(rgbvalue[0] * MAX_SHORT + 0.5f);
+        scaledRGBValue[1] = (short)(rgbvalue[1] * MAX_SHORT + 0.5f);
+        scaledRGBValue[2] = (short)(rgbvalue[2] * MAX_SHORT + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromRGBTransform, scaledRGBValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float[] fromCIEXYZ(float[] xyzvalue) {
+        if (fromXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {xyzProfile, getProfile()};
+            try {
+                int[] intents = {
+                        ICC_Profile.icPerceptual,
+                        ICC_Profile.icRelativeColorimetric};
+                fromXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                fromXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+
+        }
+
+        // scale xyz value to short
+        short[] scaledXYZValue = new short[3];
+        scaledXYZValue[0] = (short)(xyzvalue[0] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[1] = (short)(xyzvalue[1] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[2] = (short)(xyzvalue[2] * XYZ2SHORT_FACTOR + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromXYZTransform, scaledXYZValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return minValues[component];
+    }
+
+    @Override
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return maxValues[component];
+    }
+
+    /**
+     * Fill min max values.
+     */
+    private void fillMinMaxValues() {
+        int n = getNumComponents();
+        maxValues = new float[n];
+        minValues = new float[n];
+        switch (getType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for(int i=0; i<n; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+    }
+
+    /**
+     * Write object.
+     * 
+     * @param out the out
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        ObjectOutputStream.PutField fields = out.putFields();
+
+        fields.put("thisProfile", profile); //$NON-NLS-1$
+        fields.put("minVal", null); //$NON-NLS-1$
+        fields.put("maxVal", null); //$NON-NLS-1$
+        fields.put("diffMinMax", null); //$NON-NLS-1$
+        fields.put("invDiffMinMax", null); //$NON-NLS-1$
+        fields.put("needScaleInit", true); //$NON-NLS-1$
+
+        out.writeFields();
+    }
+
+    /**
+     * Read object.
+     * 
+     * @param in the in
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = in.readFields();
+        resolvedDeserializedInst =
+                new ICC_ColorSpace((ICC_Profile) fields.get("thisProfile", null)); //$NON-NLS-1$
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    Object readResolve() throws ObjectStreamException {
+        return resolvedDeserializedInst;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_Profile.java b/awt/java/awt/color/ICC_Profile.java
new file mode 100644
index 0000000..ad704e0
--- /dev/null
+++ b/awt/java/awt/color/ICC_Profile.java
@@ -0,0 +1,1231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
+import org.apache.harmony.awt.gl.color.NativeCMM;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_Profile class represents a color profile data for color spaces 
+ * based on the International Color Consortium Specification ICC.1:2001-12, 
+ * File Format for Color Profiles.
+ */
+public class ICC_Profile implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -3938515861990936766L;
+
+    // NOTE: Constant field values are noted in 1.5 specification.
+
+    /**
+     * The Constant CLASS_INPUT indicates that profile class is input. 
+     */
+    public static final int CLASS_INPUT = 0;
+
+    /** 
+     * The Constant CLASS_DISPLAY indicates that profile class is display. 
+     */
+    public static final int CLASS_DISPLAY = 1;
+
+    /** 
+     * The Constant CLASS_OUTPUT indicates that profile class is output. 
+     */
+    public static final int CLASS_OUTPUT = 2;
+
+    /** 
+     * The Constant CLASS_DEVICELINK indicates that profile class 
+     * is device link. 
+     */
+    public static final int CLASS_DEVICELINK = 3;
+
+    /** 
+     * The Constant CLASS_COLORSPACECONVERSION indicates that profile class 
+     * is color space conversion.
+     */
+    public static final int CLASS_COLORSPACECONVERSION = 4;
+
+    /** The Constant CLASS_ABSTRACT indicates that profile class is abstract. */
+    public static final int CLASS_ABSTRACT = 5;
+
+    /** 
+     * The Constant CLASS_NAMEDCOLOR indicates that profile class 
+     * is named color. 
+     */
+    public static final int CLASS_NAMEDCOLOR = 6;
+
+    /** The Constant icSigXYZData - ICC Profile Color Space Type Signature. */
+    public static final int icSigXYZData = 1482250784;
+
+    /** The Constant icSigLabData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLabData = 1281450528;
+
+    /** The Constant icSigLuvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLuvData = 1282766368;
+
+    /** The Constant icSigYCbCrData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYCbCrData = 1497588338;
+
+    /** The Constant icSigYxyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYxyData = 1501067552;
+
+    /** The Constant icSigRgbData - ICC Profile Color Space Type Signature. */
+    public static final int icSigRgbData = 1380401696;
+
+    /** The Constant icSigGrayData - ICC Profile Color Space Type Signature. */
+    public static final int icSigGrayData = 1196573017;
+
+    /** The Constant icSigHsvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHsvData = 1213421088;
+
+    /** The Constant icSigHlsData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHlsData = 1212961568;
+
+    /** The Constant icSigCmykData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmykData = 1129142603;
+
+    /** The Constant icSigCmyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmyData = 1129142560;
+
+    /** The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace2CLR = 843271250;
+
+    /** The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace3CLR = 860048466;
+
+    /** The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace4CLR = 876825682;
+
+    /** The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace5CLR = 893602898;
+
+    /** The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace6CLR = 910380114;
+
+    /** The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace7CLR = 927157330;
+
+    /** The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace8CLR = 943934546;
+
+    /** The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace9CLR = 960711762;
+
+    /** The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceACLR = 1094929490;
+
+    /** The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceBCLR = 1111706706;
+
+    /** The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceCCLR = 1128483922;
+
+    /** The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceDCLR = 1145261138;
+
+    /** The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceECLR = 1162038354;
+
+    /** The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceFCLR = 1178815570;
+
+    /** The Constant icSigInputClass - ICC Profile Class Signature. */
+    public static final int icSigInputClass = 1935896178;
+
+    /** The Constant icSigDisplayClass - ICC Profile Class Signature. */
+    public static final int icSigDisplayClass = 1835955314;
+
+    /** The Constant icSigOutputClass - ICC Profile Class Signature. */
+    public static final int icSigOutputClass = 1886549106;
+
+    /** The Constant icSigLinkClass - ICC Profile Class Signature. */
+    public static final int icSigLinkClass = 1818848875;
+
+    /** The Constant icSigAbstractClass - ICC Profile Class Signature. */
+    public static final int icSigAbstractClass = 1633842036;
+
+    /** The Constant icSigColorantOrderTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantOrderTag = 1668051567;
+
+    /** The Constant icSigColorantTableTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantTableTag = 1668051572;
+
+    /** The Constant icSigColorSpaceClass - ICC Profile Tag Signature. */
+    public static final int icSigColorSpaceClass = 1936744803;
+
+    /** The Constant icSigNamedColorClass - ICC Profile Tag Signature. */
+    public static final int icSigNamedColorClass = 1852662636;
+
+    /** The Constant icPerceptual - ICC Profile Rendering Intent. */
+    public static final int icPerceptual = 0;
+
+    /** The Constant icRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icRelativeColorimetric = 1;
+
+    /** The Constant icSaturation - ICC Profile Rendering Intent. */
+    public static final int icSaturation = 2;
+
+    /** The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icAbsoluteColorimetric = 3;
+
+    /** The Constant icSigHead - ICC Profile Tag Signature. */
+    public static final int icSigHead = 1751474532;
+
+    /** The Constant icSigAToB0Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB0Tag = 1093812784;
+
+    /** The Constant icSigAToB1Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB1Tag = 1093812785;
+
+    /** The Constant icSigAToB2Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB2Tag = 1093812786;
+
+    /** The Constant icSigBlueColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueColorantTag = 1649957210;
+
+    /** The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueMatrixColumnTag = 1649957210;
+
+    /** The Constant icSigBlueTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueTRCTag = 1649693251;
+
+    /** The Constant icSigBToA0Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA0Tag = 1110589744;
+
+    /** The Constant icSigBToA1Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA1Tag = 1110589745;
+
+    /** The Constant icSigBToA2Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA2Tag = 1110589746;
+
+    /** The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature. */
+    public static final int icSigCalibrationDateTimeTag = 1667329140;
+
+    /** The Constant icSigCharTargetTag - ICC Profile Tag Signature. */
+    public static final int icSigCharTargetTag = 1952543335;
+
+    /** The Constant icSigCopyrightTag - ICC Profile Tag Signature. */
+    public static final int icSigCopyrightTag = 1668313716;
+
+    /** The Constant icSigCrdInfoTag - ICC Profile Tag Signature. */
+    public static final int icSigCrdInfoTag = 1668441193;
+
+    /** The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceMfgDescTag = 1684893284;
+
+    /** The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceModelDescTag = 1684890724;
+
+    /** The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceSettingsTag = 1684371059;
+
+    /** The Constant icSigGamutTag - ICC Profile Tag Signature. */
+    public static final int icSigGamutTag = 1734438260;
+
+    /** The Constant icSigGrayTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGrayTRCTag = 1800688195;
+
+    /** The Constant icSigGreenColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenColorantTag = 1733843290;
+
+    /** The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenMatrixColumnTag = 1733843290;
+
+    /** The Constant icSigGreenTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenTRCTag = 1733579331;
+
+    /** The Constant icSigLuminanceTag - ICC Profile Tag Signature. */
+    public static final int icSigLuminanceTag = 1819635049;
+
+    /** The Constant icSigMeasurementTag - ICC Profile Tag Signature. */
+    public static final int icSigMeasurementTag = 1835360627;
+
+    /** The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaBlackPointTag = 1651208308;
+
+    /** The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaWhitePointTag = 2004119668;
+
+    /** The Constant icSigNamedColor2Tag - ICC Profile Tag Signature. */
+    public static final int icSigNamedColor2Tag = 1852009522;
+
+    /** The Constant icSigOutputResponseTag - ICC Profile Tag Signature. */
+    public static final int icSigOutputResponseTag = 1919251312;
+
+    /** The Constant icSigPreview0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview0Tag = 1886545200;
+
+    /** The Constant icSigPreview1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview1Tag = 1886545201;
+
+    /** The Constant icSigPreview2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview2Tag = 1886545202;
+
+    /** The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileDescriptionTag = 1684370275;
+
+    /** The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileSequenceDescTag = 1886610801;
+
+    /** The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD0Tag = 1886610480;
+
+    /** The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD1Tag = 1886610481;
+
+    /** The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD2Tag = 1886610482;
+
+    /** The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD3Tag = 1886610483;
+
+    /** The Constant icSigPs2CSATag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CSATag = 1886597747;
+
+    /** The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature. */
+    public static final int icSigPs2RenderingIntentTag = 1886597737;
+
+    /** The Constant icSigRedColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigRedColorantTag = 1918392666;
+
+    /** The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigRedMatrixColumnTag = 1918392666;
+
+    /** The Constant icSigRedTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigRedTRCTag = 1918128707;
+
+    /** The Constant icSigScreeningDescTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningDescTag = 1935897188;
+
+    /** The Constant icSigScreeningTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningTag = 1935897198;
+
+    /** The Constant icSigTechnologyTag - ICC Profile Tag Signature. */
+    public static final int icSigTechnologyTag = 1952801640;
+
+    /** The Constant icSigUcrBgTag - ICC Profile Tag Signature. */
+    public static final int icSigUcrBgTag = 1650877472;
+
+    /** The Constant icSigViewingCondDescTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingCondDescTag = 1987405156;
+
+    /** The Constant icSigViewingConditionsTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingConditionsTag = 1986618743;
+
+    /** The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticAdaptationTag = 1667785060;
+
+    /** The Constant icSigChromaticityTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticityTag = 1667789421;
+
+    /** The Constant icHdrSize - ICC Profile Header Location. */
+    public static final int icHdrSize = 0;
+
+    /** The Constant icHdrCmmId - ICC Profile Header Location. */
+    public static final int icHdrCmmId = 4;
+
+    /** The Constant icHdrVersion - ICC Profile Header Location. */
+    public static final int icHdrVersion = 8;
+
+    /** The Constant icHdrDeviceClass - ICC Profile Header Location. */
+    public static final int icHdrDeviceClass = 12;
+
+    /** The Constant icHdrColorSpace - ICC Profile Header Location. */
+    public static final int icHdrColorSpace = 16;
+
+    /** The Constant icHdrPcs - ICC Profile Header Location. */
+    public static final int icHdrPcs = 20;
+
+    /** The Constant icHdrDate - ICC Profile Header Location. */
+    public static final int icHdrDate = 24;
+
+    /** The Constant icHdrMagic - ICC Profile Header Location. */
+    public static final int icHdrMagic = 36;
+
+    /** The Constant icHdrPlatform - ICC Profile Header Location. */
+    public static final int icHdrPlatform = 40;
+
+    /** The Constant icHdrProfileID - ICC Profile Header Location. */
+    public static final int icHdrProfileID = 84;
+
+    /** The Constant icHdrFlags - ICC Profile Header Location. */
+    public static final int icHdrFlags = 44;
+
+    /** The Constant icHdrManufacturer - ICC Profile Header Location. */
+    public static final int icHdrManufacturer = 48;
+
+    /** The Constant icHdrModel - ICC Profile Header Location. */
+    public static final int icHdrModel = 52;
+
+    /** The Constant icHdrAttributes - ICC Profile Header Location. */
+    public static final int icHdrAttributes = 56;
+
+    /** The Constant icHdrRenderingIntent - ICC Profile Header Location. */
+    public static final int icHdrRenderingIntent = 64;
+
+    /** The Constant icHdrIlluminant - ICC Profile Header Location. */
+    public static final int icHdrIlluminant = 68;
+
+    /** The Constant icHdrCreator - ICC Profile Header Location. */
+    public static final int icHdrCreator = 80;
+
+    /** The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icICCAbsoluteColorimetric = 3;
+
+    /** The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icMediaRelativeColorimetric = 1;
+
+    /** The Constant icTagType - ICC Profile Constant. */
+    public static final int icTagType = 0;
+
+    /** The Constant icTagReserved - ICC Profile Constant. */
+    public static final int icTagReserved = 4;
+
+    /** The Constant icCurveCount - ICC Profile Constant. */
+    public static final int icCurveCount = 8;
+
+    /** The Constant icCurveData - ICC Profile Constant. */
+    public static final int icCurveData = 12;
+
+    /** The Constant icXYZNumberX - ICC Profile Constant. */
+    public static final int icXYZNumberX = 8;
+
+    /** Size of a profile header. */
+    private static final int headerSize = 128;
+
+    /** header magic number. */
+    private static final int headerMagicNumber = 0x61637370;
+
+    // Cache of predefined profiles
+    /** The s rgb profile. */
+    private static ICC_Profile sRGBProfile;
+    
+    /** The xyz profile. */
+    private static ICC_Profile xyzProfile;
+    
+    /** The gray profile. */
+    private static ICC_Profile grayProfile;
+    
+    /** The pycc profile. */
+    private static ICC_Profile pyccProfile;
+    
+    /** The linear rgb profile. */
+    private static ICC_Profile linearRGBProfile;
+
+    /** Handle to the current profile. */
+    private transient long profileHandle = 0;
+
+    /** If handle is used by another class this object is not responsible for closing profile. */
+    private transient boolean handleStolen = false;
+
+    /** Cached header data. */
+    private transient byte[] headerData = null;
+
+    /** Serialization support. */
+    private transient ICC_Profile openedProfileObject;
+
+    /**
+     * Instantiates a new iC c_ profile.
+     * 
+     * @param data the data
+     */
+    private ICC_Profile(byte[] data) {
+        profileHandle = NativeCMM.cmmOpenProfile(data);
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Used to instantiate dummy ICC_ProfileStub objects.
+     */
+    ICC_Profile() {
+    }
+
+    /**
+     * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
+     * 
+     * @param profileHandle - should be valid handle to opened color profile
+     */
+    ICC_Profile(long profileHandle) {
+        this.profileHandle = profileHandle;
+        // A new object reference, need to add it.
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Writes the ICC_Profile to a file with the specified name.
+     * 
+     * @param fileName the file name.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening the file.
+     */
+    public void write(String fileName) throws IOException {
+        FileOutputStream oStream = new FileOutputStream(fileName);
+        oStream.write(getData());
+        oStream.close();
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        s.defaultWriteObject();
+        s.writeObject(null);
+        s.writeObject(getData());
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        String colorSpaceStr = (String)s.readObject();
+        byte[] data = (byte[])s.readObject();
+
+        if (colorSpaceStr != null) {
+            if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_sRGB);
+            } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_GRAY);
+            } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
+            } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
+            } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_PYCC);
+            } else {
+                openedProfileObject = ICC_Profile.getInstance(data);
+            }
+        } else {
+            openedProfileObject = ICC_Profile.getInstance(data);
+        }
+    }
+
+    /**
+     * Resolves instances being deserialized into instances registered with CMM.
+     * 
+     * @return ICC_Profile object for profile registered with CMM.
+     * 
+     * @throws ObjectStreamException if there is an error in the serialized 
+     * files or during the process of reading them.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return openedProfileObject;
+    }
+
+    /**
+     * Writes the ICC_Profile to an OutputStream.
+     * 
+     * @param s the OutputStream.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening OutputStream.
+     */
+    public void write(OutputStream s) throws IOException {
+        s.write(getData());
+    }
+
+    /**
+     * Sets a tagged data element in the profile from a byte array. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to be set. 
+     * @param tagData the data to be set for the specified tag signature.
+     */
+    public void setData(int tagSignature, byte[] tagData) {
+        NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
+        // Remove cached header data if header is modified
+        if (tagSignature == icSigHead) {
+            headerData = null;
+        }
+    }
+
+    /**
+     * Gets a tagged data element from the profile as a byte array. 
+     * Elements are identified by tag signatures as defined in 
+     * the ICC specification. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to get.
+     * 
+     * @return a byte array that contains the tagged data element.
+     */
+    public byte[] getData(int tagSignature) {
+        int tagSize = 0;
+        try {
+            tagSize = NativeCMM.cmmGetProfileElementSize(
+                    profileHandle,
+                    tagSignature
+                );
+        } catch (CMMException e) {
+            // We'll get this exception if there's no element with
+            // the specified tag signature
+            return null;
+        }
+
+        byte[] data = new byte[tagSize];
+        NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
+        return data;
+    }
+
+    /**
+     * Gets a data byte array of this ICC_Profile.
+     * 
+     * @return a byte array that contains the ICC Profile data.
+     */
+    public byte[] getData() {
+        int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
+        byte[] data = new byte[profileSize];
+        NativeCMM.cmmGetProfile(profileHandle, data);
+        return data;
+    }
+
+    /**
+     * Frees the resources associated with an ICC_Profile object.
+     */
+    @Override
+    protected void finalize() {
+        if (profileHandle!=0 && !handleStolen) {
+            NativeCMM.cmmCloseProfile(profileHandle);
+        }
+
+        // Always remove because key no more exist
+        // when object is destroyed
+        NativeCMM.removeHandle(this);
+    }
+
+    /**
+     * Gets the profile class.
+     * 
+     * @return the profile class constant.
+     */
+    public int getProfileClass() {
+        int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
+
+        switch (deviceClassSignature) {
+            case icSigColorSpaceClass:
+                return CLASS_COLORSPACECONVERSION;
+            case icSigDisplayClass:
+                return CLASS_DISPLAY;
+            case icSigOutputClass:
+                return CLASS_OUTPUT;
+            case icSigInputClass:
+                return CLASS_INPUT;
+            case icSigLinkClass:
+                return CLASS_DEVICELINK;
+            case icSigAbstractClass:
+                return CLASS_ABSTRACT;
+            case icSigNamedColorClass:
+                return CLASS_NAMEDCOLOR;
+            default:
+        }
+
+        // Not an ICC profile class
+        // awt.15F=Profile class does not comply with ICC specification
+        throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
+        
+    }
+
+    /**
+     * Returns the color space type of the Profile Connection Space (PCS).
+     * 
+     * @return the PCS type.
+     */
+    public int getPCSType() {
+         return csFromSignature(getIntFromHeader(icHdrPcs));
+    }
+
+    /**
+     * Gets the number of components of this ICC Profile.
+     * 
+     * @return the number of components of this ICC Profile.
+     */
+    public int getNumComponents() {
+        switch (getIntFromHeader(icHdrColorSpace)) {
+            // The most common cases go first to increase speed
+            case icSigRgbData:
+            case icSigXYZData:
+            case icSigLabData:
+                return 3;
+            case icSigCmykData:
+                return 4;
+                // Then all other
+            case icSigGrayData:
+                return 1;
+            case icSigSpace2CLR:
+                return 2;
+            case icSigYCbCrData:
+            case icSigLuvData:
+            case icSigYxyData:
+            case icSigHlsData:
+            case icSigHsvData:
+            case icSigCmyData:
+            case icSigSpace3CLR:
+                return 3;
+            case icSigSpace4CLR:
+                return 4;
+            case icSigSpace5CLR:
+                return 5;
+            case icSigSpace6CLR:
+                return 6;
+            case icSigSpace7CLR:
+                return 7;
+            case icSigSpace8CLR:
+                return 8;
+            case icSigSpace9CLR:
+                return 9;
+            case icSigSpaceACLR:
+                return 10;
+            case icSigSpaceBCLR:
+                return 11;
+            case icSigSpaceCCLR:
+                return 12;
+            case icSigSpaceDCLR:
+                return 13;
+            case icSigSpaceECLR:
+                return 14;
+            case icSigSpaceFCLR:
+                return 15;
+            default:
+        }
+
+        // awt.160=Color space doesn't comply with ICC specification
+        throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
+        );
+    }
+
+    /**
+     * Gets the minor version of this ICC profile.
+     * 
+     * @return the minor version of this ICC profile.
+     */
+    public int getMinorVersion() {
+        return getByteFromHeader(icHdrVersion+1);
+    }
+
+    /**
+     * Gets the major version of this ICC profile.
+     * 
+     * @return the major version of this ICC profile.
+     */
+    public int getMajorVersion() {
+        return getByteFromHeader(icHdrVersion);
+    }
+
+    /**
+     * Gets the color space type of this ICC_Profile.
+     * 
+     * @return the color space type.
+     */
+    public int getColorSpaceType() {
+        return csFromSignature(getIntFromHeader(icHdrColorSpace));
+    }
+
+    /**
+     * Tries to open file at the specified path. Path entries can be 
+     * divided by a separator character.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the file input stream
+     */
+    private static FileInputStream tryPath(String path, String fileName) {
+        FileInputStream fiStream = null;
+
+        if (path == null) {
+            return null;
+        }
+
+        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+
+        while (st.hasMoreTokens()) {
+            String pathEntry = st.nextToken();
+            try {
+                fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
+                if (fiStream != null) {
+                    return fiStream;
+                }
+            } catch (FileNotFoundException e) {}
+        }
+
+        return fiStream;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from data in the specified file.
+     * 
+     * @param fileName the specified name of file with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException signals that an I/O error occured while reading the file
+     * or the file doesn't exist.
+     */
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        final String fName = fileName; // to use in the privileged block
+
+        FileInputStream fiStream = (FileInputStream) AccessController.doPrivileged(
+                new PrivilegedAction<FileInputStream>() {
+                    public FileInputStream run() {
+                        FileInputStream fiStream = null;
+
+                        // Open absolute path
+                        try {
+                            fiStream = new FileInputStream(fName);
+                            if (fiStream != null) {
+                                return fiStream;
+                            }
+                        } catch (FileNotFoundException e) {}
+
+                        // Check java.iccprofile.path entries
+                        fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check java.class.path entries
+                        fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check directory with java sample profiles
+                        String home = System.getProperty("java.home"); //$NON-NLS-1$
+                        if (home != null) {
+                            fiStream = tryPath(
+                                    home + File.separatorChar +
+                                    "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
+                            );
+                        }
+
+                        return fiStream;
+                    }
+                });
+
+        if (fiStream == null) {
+            // awt.161=Unable to open file {0}
+            throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
+        }
+
+        ICC_Profile pf = getInstance(fiStream);
+        fiStream.close();
+        return pf;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with data in
+     * the specified InputStream.
+     * 
+     * @param s the InputStream with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException if an I/O exception has occurred during reading 
+     * from InputStream.
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        byte[] header = new byte[headerSize];
+        // awt.162=Invalid ICC Profile Data
+        String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
+
+        // Get header from the input stream
+        if (s.read(header) != headerSize) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Check the profile data for consistency
+        if (
+                ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) !=
+                headerMagicNumber
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Get profile size from header, create an array for profile data
+        int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
+        byte[] profileData = new byte[profileSize];
+
+        // Copy header into it
+        System.arraycopy(header, 0, profileData, 0, headerSize);
+
+        // Read the profile itself
+        if (
+                s.read(profileData, headerSize, profileSize - headerSize) !=
+                profileSize - headerSize
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        return getInstance(profileData);
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @param data the byte array of ICC profile.
+     * 
+     * @return single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(byte[] data) {
+        ICC_Profile res = null;
+
+        try {
+            res = new ICC_Profile(data);
+        } catch (CMMException e) {
+            // awt.162=Invalid ICC Profile Data
+            throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
+        }
+
+      if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
+        try {
+            if ( res.getColorSpaceType () == ColorSpace.TYPE_RGB &&
+                 res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                 res.getDataSize(icSigRedColorantTag) > 0 &&
+                 res.getDataSize(icSigGreenColorantTag) > 0 &&
+                 res.getDataSize(icSigBlueColorantTag) > 0 &&
+                 res.getDataSize(icSigRedTRCTag) > 0 &&
+                 res.getDataSize(icSigGreenTRCTag) > 0 &&
+                 res.getDataSize(icSigBlueTRCTag) > 0
+                ) {
+                res = new ICC_ProfileRGB(res.getProfileHandle());
+            } else if ( res.getColorSpaceType () == ColorSpace.TYPE_GRAY &&
+                        res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                        res.getDataSize(icSigGrayTRCTag) > 0
+                ) {
+                res = new ICC_ProfileGray (res.getProfileHandle());
+            }
+
+        } catch (CMMException e) { /* return res in this case */ }
+      }
+
+      return res;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with the specific color space
+     * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
+     * CS_PYCC, CS_GRAY.
+     * 
+     * @param cspace the type of color space defined in the ColorSpace class.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IllegalArgumentException is not one of the defined color 
+     * space types.
+     */
+    public static ICC_Profile getInstance(int cspace) {
+    try {
+      switch (cspace) {
+
+      case ColorSpace.CS_sRGB:
+        if (sRGBProfile == null) {
+            sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
+        }
+        return sRGBProfile;
+
+      case ColorSpace.CS_CIEXYZ:
+        if (xyzProfile == null) {
+            xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
+        }
+        return xyzProfile;
+
+      case ColorSpace.CS_GRAY:
+        if (grayProfile == null) {
+            grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
+        }
+        return grayProfile;
+
+      case ColorSpace.CS_PYCC:
+        if (pyccProfile == null) {
+            pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
+        }
+        return pyccProfile;
+
+      case ColorSpace.CS_LINEAR_RGB:
+        if (linearRGBProfile == null) {
+            linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
+        }
+        return linearRGBProfile;
+      }
+
+    } catch (IOException e) {
+        // awt.163=Can't open color profile 
+        throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
+    }
+
+    // awt.164=Not a predefined color space
+    throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
+  }
+
+    /**
+     * Reads an integer from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the int from header
+     */
+    private int getIntFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return  ((headerData[idx]   & 0xFF) << 24)|
+                  ((headerData[idx+1] & 0xFF) << 16)|
+                  ((headerData[idx+2] & 0xFF) << 8) |
+                  ((headerData[idx+3] & 0xFF));
+    }
+
+    /**
+     * Reads byte from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the byte from header
+     */
+    private byte getByteFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return headerData[idx];
+    }
+
+    /**
+     * Converts ICC color space signature to the java predefined
+     * color space type.
+     * 
+     * @param signature the signature
+     * 
+     * @return the int
+     */
+    private int csFromSignature(int signature) {
+        switch (signature) {
+            case icSigRgbData:
+                return ColorSpace.TYPE_RGB;
+            case icSigXYZData:
+                return ColorSpace.TYPE_XYZ;
+            case icSigCmykData:
+                return ColorSpace.TYPE_CMYK;
+            case icSigLabData:
+                return ColorSpace.TYPE_Lab;
+            case icSigGrayData:
+                return ColorSpace.TYPE_GRAY;
+            case icSigHlsData:
+                return ColorSpace.TYPE_HLS;
+            case icSigLuvData:
+                return ColorSpace.TYPE_Luv;
+            case icSigYCbCrData:
+                return ColorSpace.TYPE_YCbCr;
+            case icSigYxyData:
+                return ColorSpace.TYPE_Yxy;
+            case icSigHsvData:
+                return ColorSpace.TYPE_HSV;
+            case icSigCmyData:
+                return ColorSpace.TYPE_CMY;
+            case icSigSpace2CLR:
+                return ColorSpace.TYPE_2CLR;
+            case icSigSpace3CLR:
+                return ColorSpace.TYPE_3CLR;
+            case icSigSpace4CLR:
+                return ColorSpace.TYPE_4CLR;
+            case icSigSpace5CLR:
+                return ColorSpace.TYPE_5CLR;
+            case icSigSpace6CLR:
+                return ColorSpace.TYPE_6CLR;
+            case icSigSpace7CLR:
+                return ColorSpace.TYPE_7CLR;
+            case icSigSpace8CLR:
+                return ColorSpace.TYPE_8CLR;
+            case icSigSpace9CLR:
+                return ColorSpace.TYPE_9CLR;
+            case icSigSpaceACLR:
+                return ColorSpace.TYPE_ACLR;
+            case icSigSpaceBCLR:
+                return ColorSpace.TYPE_BCLR;
+            case icSigSpaceCCLR:
+                return ColorSpace.TYPE_CCLR;
+            case icSigSpaceDCLR:
+                return ColorSpace.TYPE_DCLR;
+            case icSigSpaceECLR:
+                return ColorSpace.TYPE_ECLR;
+            case icSigSpaceFCLR:
+                return ColorSpace.TYPE_FCLR;
+            default:
+        }
+
+        // awt.165=Color space doesn't comply with ICC specification
+        throw new IllegalArgumentException (Messages.getString("awt.165")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the profile handle.
+     * 
+     * @return the profile handle
+     */
+    private long getProfileHandle() {
+        handleStolen = true;
+        return profileHandle;
+    }
+
+    /**
+     * Gets the data size.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the data size
+     */
+    private int getDataSize(int tagSignature) {
+        return NativeCMM.cmmGetProfileElementSize(
+                profileHandle,
+                tagSignature
+            );
+    }
+
+    /**
+     * Reads XYZ value from the tag data.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the XYZ value
+     */
+    float[] getXYZValue(int tagSignature) {
+        float[] res = new float[3];
+        byte[] data = getData(tagSignature);
+
+        // Convert from ICC s15Fixed16Number type
+        // 1 (float) = 0x10000 (s15Fixed16Number),
+        // hence dividing by 0x10000
+        res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
+        res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
+        res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
+
+        return res;
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point
+     */
+    float[] getMediaWhitePoint() {
+        return getXYZValue(icSigMediaWhitePointTag);
+    }
+
+    /**
+     * If TRC is not a table returns gamma via return value
+     * and sets dataTRC to null. If TRC is a table returns 0
+     * and fills dataTRC with values.
+     * 
+     * @param tagSignature the tag signature
+     * @param dataTRC the data trc
+     * 
+     * @return - gamma or zero if TRC is a table
+     */
+    private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
+        byte[] data = getData(tagSignature);
+        int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
+
+        dataTRC = null;
+
+        if (trcSize == 0) {
+            return 1.0f;
+        }
+
+        if (trcSize == 1) {
+            // Cast from ICC u8Fixed8Number to float
+            return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
+        }
+
+        // TRC is a table
+        dataTRC = new short[trcSize];
+        for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
+            dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the gamma.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the gamma
+     */
+    float getGamma(int tagSignature) {
+        short[] dataTRC = null;
+        float gamma = getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            return gamma;
+        }
+        // awt.166=TRC is not a simple gamma value.
+        throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the tRC.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the tRC
+     */
+    short[] getTRC(int tagSignature) {
+        short[] dataTRC = null;
+        getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            // awt.167=TRC is a gamma value, not a table.
+            throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
+        }
+        return dataTRC;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileGray.java b/awt/java/awt/color/ICC_ProfileGray.java
new file mode 100644
index 0000000..f009b18
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileGray.java
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ICC_ProfileGray class represent profiles with TYPE_GRAY color space type,
+ * and includes the grayTRCTag and mediaWhitePointTag tags. 
+ * 
+ * The gray component can be transformed from a GRAY device profile color space 
+ * to the CIEXYZ Profile through the tone reproduction curve (TRC): 
+ * <p>PCSY = grayTRC[deviceGray]
+ */
+public class ICC_ProfileGray extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1124721290732002649L;
+
+    /**
+     * Instantiates a new iC c_ profile gray.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileGray(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /**
+     * Gets the TRC as an array of shorts.
+     * 
+     * @return a short array of the TRC.
+     */
+    public short[] getTRC() {
+        return super.getTRC(icSigGrayTRCTag);
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+    /**
+     * Gets a gamma value representing the tone reproduction curve (TRC).
+     * 
+     * @return the gamma value representing the tone reproduction curve (TRC).
+     */
+    public float getGamma() {
+        return super.getGamma(icSigGrayTRCTag);
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileRGB.java b/awt/java/awt/color/ICC_ProfileRGB.java
new file mode 100644
index 0000000..beb1a0c
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileRGB.java
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_ProfileRGB class represents profiles with RGB color space type and 
+ * contains the redColorantTag, greenColorantTag, blueColorantTag, redTRCTag, 
+ * greenTRCTag, blueTRCTag, and mediaWhitePointTag tags.
+ */
+public class ICC_ProfileRGB extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8505067385152579334L;
+
+    /**
+     * Instantiates a new iC c_ profile rgb.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileRGB(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /** The Constant REDCOMPONENT indicates the red component. */
+    public static final int REDCOMPONENT = 0;
+
+    /** The Constant GREENCOMPONENT indicates the green component. */
+    public static final int GREENCOMPONENT = 1;
+
+    /** The Constant BLUECOMPONENT indicates the blue component. */
+    public static final int BLUECOMPONENT = 2;
+
+    // awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+    /** The Constant UNKNOWN_COMPONENT_MSG. */
+    private static final String UNKNOWN_COMPONENT_MSG = Messages
+            .getString("awt.15E"); //$NON-NLS-1$
+
+    @Override
+    public short[] getTRC(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getTRC(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getTRC(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getTRC(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    @Override
+    public float getGamma(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getGamma(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getGamma(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getGamma(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    /**
+     * Gets a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     * 
+     * @return a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     */
+    public float[][] getMatrix() {
+        float [][] m = new float[3][3]; // The matrix
+
+        float[] redXYZ = getXYZValue(icSigRedColorantTag);
+        float[] greenXYZ = getXYZValue(icSigGreenColorantTag);
+        float[] blueXYZ = getXYZValue(icSigBlueColorantTag);
+
+        m[0][0] = redXYZ[0];
+        m[1][0] = redXYZ[1];
+        m[2][0] = redXYZ[2];
+
+        m[0][1] = greenXYZ[0];
+        m[1][1] = greenXYZ[1];
+        m[2][1] = greenXYZ[2];
+
+        m[0][2] = blueXYZ[0];
+        m[1][2] = blueXYZ[1];
+        m[2][2] = blueXYZ[2];
+
+        return m;
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileStub.java b/awt/java/awt/color/ICC_ProfileStub.java
new file mode 100644
index 0000000..bc04c8a
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileStub.java
@@ -0,0 +1,173 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.color;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+final class ICC_ProfileStub extends ICC_Profile {
+    private static final long serialVersionUID = 501389760875253507L;
+
+    transient int colorspace;
+
+    public ICC_ProfileStub(int csSpecifier) {
+        switch (csSpecifier) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+            case ColorSpace.CS_GRAY:
+                break;
+            default:
+                // awt.15D=Invalid colorspace
+                throw new IllegalArgumentException(Messages.getString("awt.15D")); //$NON-NLS-1$
+        }
+        colorspace = csSpecifier;
+    }
+
+    @Override
+    public void write(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    /**
+     * Serializable implementation
+     *
+     * @throws ObjectStreamException
+     */
+    private Object writeReplace() throws ObjectStreamException {
+        return loadProfile();
+    }
+
+    @Override
+    public void write(OutputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public void setData(int tagSignature, byte[] tagData) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData(int tagSignature) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    protected void finalize() {
+    }
+
+    @Override
+    public int getProfileClass() {
+        return CLASS_COLORSPACECONVERSION;
+    }
+
+    @Override
+    public int getPCSType() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getNumComponents() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+                return 3;
+            case ColorSpace.CS_GRAY:
+                return 1;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int getMinorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getMajorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getColorSpaceType() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_LINEAR_RGB:
+                return ColorSpace.TYPE_RGB;
+            case ColorSpace.CS_CIEXYZ:
+                return ColorSpace.TYPE_XYZ;
+            case ColorSpace.CS_PYCC:
+                return ColorSpace.TYPE_3CLR;
+            case ColorSpace.CS_GRAY:
+                return ColorSpace.TYPE_GRAY;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(byte[] data) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(int cspace) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public ICC_Profile loadProfile() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+            case ColorSpace.CS_GRAY:
+                return ICC_Profile.getInstance(ColorSpace.CS_GRAY);
+            case ColorSpace.CS_CIEXYZ:
+                return ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+            case ColorSpace.CS_LINEAR_RGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB);
+            case ColorSpace.CS_PYCC:
+                return ICC_Profile.getInstance(ColorSpace.CS_PYCC);
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ProfileDataException.java b/awt/java/awt/color/ProfileDataException.java
new file mode 100644
index 0000000..ca169fe
--- /dev/null
+++ b/awt/java/awt/color/ProfileDataException.java
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ProfileDataException class represents an error which occurs 
+ * while accessing or processing an ICC_Profile object.
+ */
+public class ProfileDataException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 7286140888240322498L;
+
+    /**
+     * Instantiates a new profile data exception with detailed message.
+     * 
+     * @param s the detailed message.
+     */
+    public ProfileDataException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
new file mode 100644
index 0000000..f621c9b
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.util.EventListener;
+
+public interface AWTEventListener extends EventListener {
+
+    public void eventDispatched(AWTEvent event);
+
+}
diff --git a/awt/java/awt/event/AWTEventListenerProxy.java b/awt/java/awt/event/AWTEventListenerProxy.java
new file mode 100644
index 0000000..5ee5e59
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListenerProxy.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+import java.util.EventListenerProxy;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class AWTEventListenerProxy extends EventListenerProxy implements AWTEventListener {
+
+    private AWTEventListener listener;
+    private long eventMask;
+
+    public AWTEventListenerProxy(long eventMask, AWTEventListener listener) {
+        super(listener);
+
+        // awt.193=Listener can't be zero
+        assert listener != null : Messages.getString("awt.193"); //$NON-NLS-1$
+
+        this.listener = listener;
+        this.eventMask = eventMask;
+    }
+
+    public void eventDispatched(AWTEvent evt) {
+        listener.eventDispatched(evt);
+    }
+
+    public long getEventMask() {
+        return eventMask;
+    }
+
+}
diff --git a/awt/java/awt/event/ActionEvent.java b/awt/java/awt/event/ActionEvent.java
new file mode 100644
index 0000000..c32fc4b
--- /dev/null
+++ b/awt/java/awt/event/ActionEvent.java
@@ -0,0 +1,108 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class ActionEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -7671078796273832149L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ACTION_FIRST = 1001;
+
+    public static final int ACTION_LAST = 1001;
+
+    public static final int ACTION_PERFORMED = 1001;
+
+    private long when;
+    private int modifiers;
+    private String command;
+
+    public ActionEvent(Object source, int id, String command) {
+        this(source, id, command, 0);
+    }
+
+    public ActionEvent(Object source, int id, String command, int modifiers) {
+        this(source, id, command, 0l, modifiers);
+    }
+
+    public ActionEvent(Object source, int id, String command, long when, int modifiers) {
+        super(source, id);
+
+        this.command = command;
+        this.when = when;
+        this.modifiers = modifiers;
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getActionCommand() {
+        return command;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ActionEvent e = new ActionEvent(new Component(){},
+         *       ActionEvent.ACTION_PERFORMED, "Command",
+         *       ActionEvent.SHIFT_MASK|ActionEvent.CTRL_MASK|
+         *       ActionEvent.META_MASK|ActionEvent.ALT_MASK);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ACTION_PERFORMED) ? 
+                          "ACTION_PERFORMED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+        String modifiersString = ""; //$NON-NLS-1$
+
+        if ((modifiers & SHIFT_MASK) > 0) {
+            modifiersString += "Shift"; //$NON-NLS-1$
+        }
+        if ((modifiers & CTRL_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Ctrl" : "+Ctrl"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & META_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Meta" : "+Meta"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & ALT_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Alt" : "+Alt"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return (idString + ",cmd=" + command + ",when=" + when +  //$NON-NLS-1$ //$NON-NLS-2$
+                ",modifiers=" + modifiersString); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ActionListener.java b/awt/java/awt/event/ActionListener.java
new file mode 100644
index 0000000..473d2b6
--- /dev/null
+++ b/awt/java/awt/event/ActionListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ActionListener extends EventListener {
+
+    public void actionPerformed(ActionEvent e);
+
+}
diff --git a/awt/java/awt/event/AdjustmentEvent.java b/awt/java/awt/event/AdjustmentEvent.java
new file mode 100644
index 0000000..a2b11a8
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentEvent.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Adjustable;
+
+public class AdjustmentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 5700290645205279921L;
+
+    public static final int ADJUSTMENT_FIRST = 601;
+
+    public static final int ADJUSTMENT_LAST = 601;
+
+    public static final int ADJUSTMENT_VALUE_CHANGED = 601;
+
+    public static final int UNIT_INCREMENT = 1;
+
+    public static final int UNIT_DECREMENT = 2;
+
+    public static final int BLOCK_DECREMENT = 3;
+
+    public static final int BLOCK_INCREMENT = 4;
+
+    public static final int TRACK = 5;
+
+    private int type;
+    private int value;
+    private boolean isAdjusting;
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value) {
+        this(source, id, type, value, false);
+    }
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value, 
+                           boolean isAdjusting) {
+        super(source, id);
+        this.type = type;
+        this.value = value;
+        this.isAdjusting = isAdjusting;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public int getAdjustmentType() {
+        return type;
+    }
+
+    public boolean getValueIsAdjusting() {
+        return isAdjusting;
+    }
+
+    public Adjustable getAdjustable() {
+        return (Adjustable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AdjustmentEvent e = new AdjustmentEvent(new Scrollbar(), 
+         *       AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 
+         *       AdjustmentEvent.UNIT_INCREMENT, 1);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ADJUSTMENT_VALUE_CHANGED ?
+                "ADJUSTMENT_VALUE_CHANGED" : "unknown type"); //$NON-NLS-1$ //$NON-NLS-2$
+        String adjType = null;
+
+        switch (type) {
+        case UNIT_INCREMENT:
+            adjType = "UNIT_INCREMENT"; //$NON-NLS-1$
+            break;
+        case UNIT_DECREMENT:
+            adjType = "UNIT_DECREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_INCREMENT:
+            adjType = "BLOCK_INCREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_DECREMENT:
+            adjType = "BLOCK_DECREMENT"; //$NON-NLS-1$
+            break;
+        case TRACK:
+            adjType = "TRACK"; //$NON-NLS-1$
+            break;
+        default:
+            adjType = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",adjType=" + adjType + ",value=" + value + //$NON-NLS-1$ //$NON-NLS-2$
+                ",isAdjusting=" + isAdjusting); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/AdjustmentListener.java b/awt/java/awt/event/AdjustmentListener.java
new file mode 100644
index 0000000..ef7c378
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface AdjustmentListener extends EventListener {
+
+    public void adjustmentValueChanged(AdjustmentEvent e);
+
+}
diff --git a/awt/java/awt/event/ComponentAdapter.java b/awt/java/awt/event/ComponentAdapter.java
new file mode 100644
index 0000000..4f0bd90
--- /dev/null
+++ b/awt/java/awt/event/ComponentAdapter.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ComponentAdapter implements ComponentListener {
+
+    public ComponentAdapter() {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+
+    public void componentMoved(ComponentEvent e) {
+    }
+
+    public void componentResized(ComponentEvent e) {
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentEvent.java b/awt/java/awt/event/ComponentEvent.java
new file mode 100644
index 0000000..d0bca54
--- /dev/null
+++ b/awt/java/awt/event/ComponentEvent.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+public class ComponentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 8101406823902992965L;
+
+    public static final int COMPONENT_FIRST = 100;
+
+    public static final int COMPONENT_LAST = 103;
+
+    public static final int COMPONENT_MOVED = 100;
+
+    public static final int COMPONENT_RESIZED = 101;
+
+    public static final int COMPONENT_SHOWN = 102;
+
+    public static final int COMPONENT_HIDDEN = 103;
+
+    public ComponentEvent(Component source, int id) {
+        super(source, id);
+    }
+
+    public Component getComponent() {
+        return (Component) source;
+    }
+    
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ComponentEvent e = new ComponentEvent(new Button("Button"), 
+         *          ComponentEvent.COMPONENT_SHOWN);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        Component c = getComponent();
+
+        switch (id) {
+        case COMPONENT_MOVED:
+            idString = "COMPONENT_MOVED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_RESIZED:
+            idString = "COMPONENT_RESIZED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_SHOWN:
+            return "COMPONENT_SHOWN"; //$NON-NLS-1$
+        case COMPONENT_HIDDEN:
+            return "COMPONENT_HIDDEN"; //$NON-NLS-1$
+        default:
+            return "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + " (" + c.getX() + "," + c.getY() +  //$NON-NLS-1$ //$NON-NLS-2$
+                " " + c.getWidth()+ "x" + c.getHeight() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentListener.java b/awt/java/awt/event/ComponentListener.java
new file mode 100644
index 0000000..147e9e0
--- /dev/null
+++ b/awt/java/awt/event/ComponentListener.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ComponentListener extends EventListener {
+
+    public void componentHidden(ComponentEvent e);
+
+    public void componentMoved(ComponentEvent e);
+
+    public void componentResized(ComponentEvent e);
+
+    public void componentShown(ComponentEvent e);
+
+}
diff --git a/awt/java/awt/event/ContainerAdapter.java b/awt/java/awt/event/ContainerAdapter.java
new file mode 100644
index 0000000..12dc3de
--- /dev/null
+++ b/awt/java/awt/event/ContainerAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ContainerAdapter implements ContainerListener {
+
+    public ContainerAdapter() {
+    }
+
+    public void componentAdded(ContainerEvent e) {
+    }
+
+    public void componentRemoved(ContainerEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerEvent.java b/awt/java/awt/event/ContainerEvent.java
new file mode 100644
index 0000000..1a1055c
--- /dev/null
+++ b/awt/java/awt/event/ContainerEvent.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class ContainerEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -4114942250539772041L;
+
+    public static final int CONTAINER_FIRST = 300;
+
+    public static final int CONTAINER_LAST = 301;
+
+    public static final int COMPONENT_ADDED = 300;
+
+    public static final int COMPONENT_REMOVED = 301;
+
+    private Component child;
+
+    public ContainerEvent(Component src, int id, Component child) {
+        super(src, id);
+        this.child = child;
+    }
+
+    public Component getChild() {
+        return child;
+    }
+
+    //???AWT
+    /*
+    public Container getContainer() {
+        return (Container) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ContainerEvent e = new ContainerEvent(new Panel(),
+         *          ContainerEvent.COMPONENT_ADDED,
+         *          new Button("Button"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case COMPONENT_ADDED:
+            idString = "COMPONENT_ADDED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_REMOVED:
+            idString = "COMPONENT_REMOVED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",child=" + child.getName()); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerListener.java b/awt/java/awt/event/ContainerListener.java
new file mode 100644
index 0000000..bf47664
--- /dev/null
+++ b/awt/java/awt/event/ContainerListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ContainerListener extends EventListener {
+
+    public void componentAdded(ContainerEvent e);
+
+    public void componentRemoved(ContainerEvent e);
+
+}
diff --git a/awt/java/awt/event/FocusAdapter.java b/awt/java/awt/event/FocusAdapter.java
new file mode 100644
index 0000000..3489e11
--- /dev/null
+++ b/awt/java/awt/event/FocusAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class FocusAdapter implements FocusListener {
+
+    public FocusAdapter() {
+    }
+
+    public void focusGained(FocusEvent e) {
+    }
+
+    public void focusLost(FocusEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/FocusEvent.java b/awt/java/awt/event/FocusEvent.java
new file mode 100644
index 0000000..1db5263
--- /dev/null
+++ b/awt/java/awt/event/FocusEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class FocusEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 523753786457416396L;
+
+    public static final int FOCUS_FIRST = 1004;
+
+    public static final int FOCUS_LAST = 1005;
+
+    public static final int FOCUS_GAINED = 1004;
+
+    public static final int FOCUS_LOST = 1005;
+
+    private boolean temporary;
+    private Component opposite;
+
+    public FocusEvent(Component source, int id) {
+        this(source, id, false);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary) {
+        this(source, id, temporary, null);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary, Component opposite) {
+        super(source, id);
+        this.temporary = temporary;
+        this.opposite = opposite;
+    }
+
+    public Component getOppositeComponent() {
+        return opposite;
+    }
+
+    public boolean isTemporary() {
+        return temporary;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * FocusEvent e = new FocusEvent(new Button("Button0"),
+         *       FocusEvent.FOCUS_GAINED, false, new Button("Button1"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case FOCUS_GAINED:
+            idString = "FOCUS_GAINED"; //$NON-NLS-1$
+            break;
+        case FOCUS_LOST:
+            idString = "FOCUS_LOST"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString +
+                (temporary ? ",temporary" : ",permanent") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",opposite=" + opposite); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/FocusListener.java b/awt/java/awt/event/FocusListener.java
new file mode 100644
index 0000000..ee98d90
--- /dev/null
+++ b/awt/java/awt/event/FocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface FocusListener extends EventListener {
+
+    public void focusGained(FocusEvent e);
+
+    public void focusLost(FocusEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsAdapter.java b/awt/java/awt/event/HierarchyBoundsAdapter.java
new file mode 100644
index 0000000..24e3d9d
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener {
+
+    public HierarchyBoundsAdapter() {
+    }
+
+    public void ancestorMoved(HierarchyEvent e) {
+    }
+
+    public void ancestorResized(HierarchyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsListener.java b/awt/java/awt/event/HierarchyBoundsListener.java
new file mode 100644
index 0000000..4288f52
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyBoundsListener extends EventListener {
+
+    public void ancestorMoved(HierarchyEvent e);
+
+    public void ancestorResized(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyEvent.java b/awt/java/awt/event/HierarchyEvent.java
new file mode 100644
index 0000000..1881667
--- /dev/null
+++ b/awt/java/awt/event/HierarchyEvent.java
@@ -0,0 +1,148 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class HierarchyEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -5337576970038043990L;
+
+    public static final int HIERARCHY_FIRST = 1400;
+
+    public static final int HIERARCHY_CHANGED = 1400;
+
+    public static final int ANCESTOR_MOVED = 1401;
+
+    public static final int ANCESTOR_RESIZED = 1402;
+
+    public static final int HIERARCHY_LAST = 1402;
+
+    public static final int PARENT_CHANGED = 1;
+
+    public static final int DISPLAYABILITY_CHANGED = 2;
+
+    public static final int SHOWING_CHANGED = 4;
+
+    //???AWT: private Container changedParent;
+    private Component changed;
+    private long changeFlag;
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed, 
+                          Container changedParent) {
+        this(source, id, changed, changedParent, 0l);
+    }
+    */
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed,
+            Container changedParent, long changeFlags) {
+        super(source, id);
+
+        this.changed = changed;
+        this.changedParent = changedParent;
+        this.changeFlag = changeFlags;
+    }
+    */
+    //???AWT: Fake constructor, should be as above.
+    public HierarchyEvent(Component source, int id, Component changed,
+            Object changedParent, long changeFlags) {
+        super(source, id);
+
+//        this.changed = changed;
+//        this.changedParent = changedParent;
+//        this.changeFlag = changeFlags;
+    }
+    
+    public Component getComponent() {
+        return (Component) source;
+    }
+
+    public long getChangeFlags() {
+        return changeFlag;
+    }
+
+    public Component getChanged() {
+        return changed;
+    }
+
+    //???AWT
+    /*
+    public Container getChangedParent() {
+        return changedParent;
+
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * HierarchyEvent e = new HierarchyEvent(new Button("Button"),
+         *          HierarchyEvent.HIERARCHY_CHANGED,
+         *          new Panel(), new Container());
+         * System.out.println(e);
+         */
+        String paramString = null;
+
+        switch (id) {
+        case HIERARCHY_CHANGED:
+            paramString = "HIERARCHY_CHANGED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_MOVED:
+            paramString = "ANCESTOR_MOVED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_RESIZED:
+            paramString = "ANCESTOR_RESIZED"; //$NON-NLS-1$
+            break;
+        default:
+            paramString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += " ("; //$NON-NLS-1$
+
+        if (id == HIERARCHY_CHANGED) {
+            if ((changeFlag & PARENT_CHANGED) > 0) {
+                paramString += "PARENT_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & DISPLAYABILITY_CHANGED) > 0) {
+                paramString += "DISPLAYABILITY_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & SHOWING_CHANGED) > 0) {
+                paramString += "SHOWING_CHANGED,"; //$NON-NLS-1$
+            }
+        }
+
+        //???AWT
+        /*
+        return paramString + "changed=" + changed +  //$NON-NLS-1$
+                ",changedParent=" + changedParent + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyListener.java b/awt/java/awt/event/HierarchyListener.java
new file mode 100644
index 0000000..e01ba11
--- /dev/null
+++ b/awt/java/awt/event/HierarchyListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyListener extends EventListener {
+
+    public void hierarchyChanged(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/InputEvent.java b/awt/java/awt/event/InputEvent.java
new file mode 100644
index 0000000..c98382d
--- /dev/null
+++ b/awt/java/awt/event/InputEvent.java
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public abstract class InputEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -2482525981698309786L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ALT_GRAPH_MASK = 32;
+
+    public static final int BUTTON1_MASK = 16;
+
+    public static final int BUTTON2_MASK = 8;
+
+    public static final int BUTTON3_MASK = 4;
+
+    public static final int SHIFT_DOWN_MASK = 64;
+
+    public static final int CTRL_DOWN_MASK = 128;
+
+    public static final int META_DOWN_MASK = 256;
+
+    public static final int ALT_DOWN_MASK = 512;
+
+    public static final int BUTTON1_DOWN_MASK = 1024;
+
+    public static final int BUTTON2_DOWN_MASK = 2048;
+
+    public static final int BUTTON3_DOWN_MASK = 4096;
+
+    public static final int ALT_GRAPH_DOWN_MASK = 8192;
+
+    private static final int DOWN_MASKS = SHIFT_DOWN_MASK | CTRL_DOWN_MASK |
+            META_DOWN_MASK | ALT_DOWN_MASK | BUTTON1_DOWN_MASK |
+            BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | ALT_GRAPH_DOWN_MASK;
+
+    private long when;
+    private int modifiersEx;
+
+    public static String getModifiersExText(int modifiers/*Ex*/) {
+        return MouseEvent.addMouseModifiersExText(
+                KeyEvent.getKeyModifiersExText(modifiers), modifiers);
+    }
+
+    static int extractExFlags(int modifiers) {
+        int exFlags = modifiers & DOWN_MASKS;
+
+        if ((modifiers & SHIFT_MASK) != 0) {
+            exFlags |= SHIFT_DOWN_MASK;
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            exFlags |= CTRL_DOWN_MASK;
+        }
+        if ((modifiers & META_MASK) != 0) {
+            exFlags |= META_DOWN_MASK;
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            exFlags |= ALT_DOWN_MASK;
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            exFlags |= ALT_GRAPH_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            exFlags |= BUTTON1_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            exFlags |= BUTTON2_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            exFlags |= BUTTON3_DOWN_MASK;
+        }
+
+        return exFlags;
+    }
+
+    InputEvent(Component source, int id, long when, int modifiers) {
+        super(source, id);
+
+        this.when = when;
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public int getModifiers() {
+        int modifiers = 0;
+
+        if ((modifiersEx & SHIFT_DOWN_MASK) != 0) {
+            modifiers |= SHIFT_MASK;
+        }
+        if ((modifiersEx & CTRL_DOWN_MASK) != 0) {
+            modifiers |= CTRL_MASK;
+        }
+        if ((modifiersEx & META_DOWN_MASK) != 0) {
+            modifiers |= META_MASK;
+        }
+        if ((modifiersEx & ALT_DOWN_MASK) != 0) {
+            modifiers |= ALT_MASK;
+        }
+        if ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0) {
+            modifiers |= ALT_GRAPH_MASK;
+        }
+        if ((modifiersEx & BUTTON1_DOWN_MASK) != 0) {
+            modifiers |= BUTTON1_MASK;
+        }
+        if ((modifiersEx & BUTTON2_DOWN_MASK) != 0) {
+            modifiers |= BUTTON2_MASK;
+        }
+        if ((modifiersEx & BUTTON3_DOWN_MASK) != 0) {
+            modifiers |= BUTTON3_MASK;
+        }
+
+        return modifiers;
+    }
+
+    public int getModifiersEx() {
+        return modifiersEx;
+    }
+
+    void setModifiers(int modifiers) {
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public boolean isAltDown() {
+        return ((modifiersEx & ALT_DOWN_MASK) != 0);
+    }
+
+    public boolean isAltGraphDown() {
+        return ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
+    }
+
+    public boolean isControlDown() {
+        return ((modifiersEx & CTRL_DOWN_MASK) != 0);
+    }
+
+    public boolean isMetaDown() {
+        return ((modifiersEx & META_DOWN_MASK) != 0);
+    }
+
+    public boolean isShiftDown() {
+        return ((modifiersEx & SHIFT_DOWN_MASK) != 0);
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodEvent.java b/awt/java/awt/event/InputMethodEvent.java
new file mode 100644
index 0000000..a5cac4e
--- /dev/null
+++ b/awt/java/awt/event/InputMethodEvent.java
@@ -0,0 +1,150 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 4727190874778922661L;
+
+    public static final int INPUT_METHOD_FIRST = 1100;
+
+    public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
+
+    public static final int CARET_POSITION_CHANGED = 1101;
+
+    public static final int INPUT_METHOD_LAST = 1101;
+
+    private AttributedCharacterIterator text;
+    private TextHitInfo visiblePosition;
+    private TextHitInfo caret;
+    private int committedCharacterCount;
+    private long when;
+
+    public InputMethodEvent(Component src, int id,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, null, 0, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, 
+                            AttributedCharacterIterator text,
+                            int commitedCharCount,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, 0l, text, commitedCharCount, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, long when,
+                            AttributedCharacterIterator text, 
+                            int committedCharacterCount,
+                            TextHitInfo caret,
+                            TextHitInfo visiblePos) {
+        super(src, id);
+
+        if ((id < INPUT_METHOD_FIRST) || (id > INPUT_METHOD_LAST)) {
+            // awt.18E=Wrong event id
+            throw new IllegalArgumentException(Messages.getString("awt.18E")); //$NON-NLS-1$
+        }
+        if ((id == CARET_POSITION_CHANGED) && (text != null)) {
+            // awt.18F=Text must be null for CARET_POSITION_CHANGED
+            throw new IllegalArgumentException(Messages.getString("awt.18F")); //$NON-NLS-1$
+        }
+        if ((text != null) &&
+                ((committedCharacterCount < 0) ||
+                 (committedCharacterCount > 
+                        (text.getEndIndex() - text.getBeginIndex())))) {
+            // awt.190=Wrong committedCharacterCount
+            throw new IllegalArgumentException(Messages.getString("awt.190")); //$NON-NLS-1$
+        }
+
+        this.when = when;
+        this.text = text;
+        this.caret = caret;
+        this.visiblePosition = visiblePos;
+        this.committedCharacterCount = committedCharacterCount;
+    }
+
+    public TextHitInfo getCaret() {
+        return caret;
+    }
+
+    public int getCommittedCharacterCount() {
+        return committedCharacterCount;
+    }
+
+    public AttributedCharacterIterator getText() {
+        return text;
+    }
+
+    public TextHitInfo getVisiblePosition() {
+        return visiblePosition;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InputMethodEvent e = new InputMethodEvent(new Component(){},
+         *          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+         *          TextHitInfo.leading(1), TextHitInfo.trailing(2));
+         * System.out.println(e);
+         */
+        String typeString = null;
+
+        switch (id) {
+        case INPUT_METHOD_TEXT_CHANGED:
+            typeString = "INPUT_METHOD_TEXT_CHANGED"; //$NON-NLS-1$
+            break;
+        case CARET_POSITION_CHANGED:
+            typeString = "CARET_POSITION_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",text=" + text +  //$NON-NLS-1$
+                ",commitedCharCount=" + committedCharacterCount + //$NON-NLS-1$
+                ",caret=" + caret + ",visiblePosition=" + visiblePosition; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodListener.java b/awt/java/awt/event/InputMethodListener.java
new file mode 100644
index 0000000..0ab6918
--- /dev/null
+++ b/awt/java/awt/event/InputMethodListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface InputMethodListener extends EventListener {
+
+    public void caretPositionChanged(InputMethodEvent e);
+
+    public void inputMethodTextChanged(InputMethodEvent e);
+
+}
diff --git a/awt/java/awt/event/InvocationEvent.java b/awt/java/awt/event/InvocationEvent.java
new file mode 100644
index 0000000..59346ed
--- /dev/null
+++ b/awt/java/awt/event/InvocationEvent.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InvocationEvent extends AWTEvent implements ActiveEvent {
+
+    private static final long serialVersionUID = 436056344909459450L;
+
+    public static final int INVOCATION_FIRST = 1200;
+
+    public static final int INVOCATION_DEFAULT = 1200;
+
+    public static final int INVOCATION_LAST = 1200;
+
+    protected Runnable runnable;
+
+    protected Object notifier;
+
+    protected boolean catchExceptions;
+
+    private long when;
+    private Throwable throwable;
+
+    public InvocationEvent(Object source, Runnable runnable) {
+        this(source, runnable, null, false);
+    }
+
+    public InvocationEvent(Object source, Runnable runnable, 
+                           Object notifier, boolean catchExceptions) {
+        this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
+    }
+
+    protected InvocationEvent(Object source, int id, Runnable runnable,
+            Object notifier, boolean catchExceptions)
+    {
+        super(source, id);
+
+        // awt.18C=Cannot invoke null runnable
+        assert runnable != null : Messages.getString("awt.18C"); //$NON-NLS-1$
+
+        if (source == null) {
+            // awt.18D=Source is null
+            throw new IllegalArgumentException(Messages.getString("awt.18D")); //$NON-NLS-1$
+        }
+        this.runnable = runnable;
+        this.notifier = notifier;
+        this.catchExceptions = catchExceptions;
+
+        throwable = null;
+        when = System.currentTimeMillis();
+    }
+
+    public void dispatch() {
+        if (!catchExceptions) {
+            runAndNotify();
+        } else {
+            try {
+                runAndNotify();
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    private void runAndNotify() {
+        if (notifier != null) {
+            synchronized(notifier) {
+                try {
+                    runnable.run();
+                } finally {
+                    notifier.notifyAll();
+                }
+            }
+        } else {
+            runnable.run();
+        }
+    }
+
+    public Exception getException() {
+        return (throwable != null && throwable instanceof Exception) ?
+                (Exception)throwable : null;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InvocationEvent e = new InvocationEvent(new Component(){},
+         *       new Runnable() { public void run(){} });
+         * System.out.println(e);
+         */
+
+        return ((id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",runnable=" + runnable + //$NON-NLS-1$
+                ",notifier=" + notifier + //$NON-NLS-1$
+                ",catchExceptions=" + catchExceptions + //$NON-NLS-1$
+                ",when=" + when); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemEvent.java b/awt/java/awt/event/ItemEvent.java
new file mode 100644
index 0000000..842da14
--- /dev/null
+++ b/awt/java/awt/event/ItemEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ItemSelectable;
+
+public class ItemEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -608708132447206933L;
+
+    public static final int ITEM_FIRST = 701;
+
+    public static final int ITEM_LAST = 701;
+
+    public static final int ITEM_STATE_CHANGED = 701;
+
+    public static final int SELECTED = 1;
+
+    public static final int DESELECTED = 2;
+
+    private Object item;
+    private int stateChange;
+
+    public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) {
+        super(source, id);
+
+        this.item = item;
+        this.stateChange = stateChange;
+    }
+
+    public Object getItem() {
+        return item;
+    }
+
+    public int getStateChange() {
+        return stateChange;
+    }
+
+    public ItemSelectable getItemSelectable() {
+        return (ItemSelectable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Checkbox c = new Checkbox("Checkbox", true);
+         * ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, 
+         *                             c, ItemEvent.SELECTED);
+         * System.out.println(e);
+         */
+
+        String stateString = null;
+
+        switch (stateChange) {
+        case SELECTED:
+            stateString = "SELECTED"; //$NON-NLS-1$
+            break;
+        case DESELECTED:
+            stateString = "DESELECTED"; //$NON-NLS-1$
+            break;
+        default:
+            stateString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return ((id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",item=" + item + ",stateChange=" + stateString); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemListener.java b/awt/java/awt/event/ItemListener.java
new file mode 100644
index 0000000..33633be
--- /dev/null
+++ b/awt/java/awt/event/ItemListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ItemListener extends EventListener {
+
+    public void itemStateChanged(ItemEvent e);
+
+}
diff --git a/awt/java/awt/event/KeyAdapter.java b/awt/java/awt/event/KeyAdapter.java
new file mode 100644
index 0000000..423b5c9
--- /dev/null
+++ b/awt/java/awt/event/KeyAdapter.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class KeyAdapter implements KeyListener {
+
+    public KeyAdapter() {
+    }
+
+    public void keyPressed(KeyEvent e) {
+    }
+
+    public void keyReleased(KeyEvent e) {
+    }
+
+    public void keyTyped(KeyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/KeyEvent.java b/awt/java/awt/event/KeyEvent.java
new file mode 100644
index 0000000..056c64c
--- /dev/null
+++ b/awt/java/awt/event/KeyEvent.java
@@ -0,0 +1,681 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class KeyEvent extends InputEvent {
+
+    private static final long serialVersionUID = -2352130953028126954L;
+
+    public static final int KEY_FIRST = 400;
+
+    public static final int KEY_LAST = 402;
+
+    public static final int KEY_TYPED = 400;
+
+    public static final int KEY_PRESSED = 401;
+
+    public static final int KEY_RELEASED = 402;
+
+    public static final int VK_ENTER = 10;
+
+    public static final int VK_BACK_SPACE = 8;
+
+    public static final int VK_TAB = 9;
+
+    public static final int VK_CANCEL = 3;
+
+    public static final int VK_CLEAR = 12;
+
+    public static final int VK_SHIFT = 16;
+
+    public static final int VK_CONTROL = 17;
+
+    public static final int VK_ALT = 18;
+
+    public static final int VK_PAUSE = 19;
+
+    public static final int VK_CAPS_LOCK = 20;
+
+    public static final int VK_ESCAPE = 27;
+
+    public static final int VK_SPACE = 32;
+
+    public static final int VK_PAGE_UP = 33;
+
+    public static final int VK_PAGE_DOWN = 34;
+
+    public static final int VK_END = 35;
+
+    public static final int VK_HOME = 36;
+
+    public static final int VK_LEFT = 37;
+
+    public static final int VK_UP = 38;
+
+    public static final int VK_RIGHT = 39;
+
+    public static final int VK_DOWN = 40;
+
+    public static final int VK_COMMA = 44;
+
+    public static final int VK_MINUS = 45;
+
+    public static final int VK_PERIOD = 46;
+
+    public static final int VK_SLASH = 47;
+
+    public static final int VK_0 = 48;
+
+    public static final int VK_1 = 49;
+
+    public static final int VK_2 = 50;
+
+    public static final int VK_3 = 51;
+
+    public static final int VK_4 = 52;
+
+    public static final int VK_5 = 53;
+
+    public static final int VK_6 = 54;
+
+    public static final int VK_7 = 55;
+
+    public static final int VK_8 = 56;
+
+    public static final int VK_9 = 57;
+
+    public static final int VK_SEMICOLON = 59;
+
+    public static final int VK_EQUALS = 61;
+
+    public static final int VK_A = 65;
+
+    public static final int VK_B = 66;
+
+    public static final int VK_C = 67;
+
+    public static final int VK_D = 68;
+
+    public static final int VK_E = 69;
+
+    public static final int VK_F = 70;
+
+    public static final int VK_G = 71;
+
+    public static final int VK_H = 72;
+
+    public static final int VK_I = 73;
+
+    public static final int VK_J = 74;
+
+    public static final int VK_K = 75;
+
+    public static final int VK_L = 76;
+
+    public static final int VK_M = 77;
+
+    public static final int VK_N = 78;
+
+    public static final int VK_O = 79;
+
+    public static final int VK_P = 80;
+
+    public static final int VK_Q = 81;
+
+    public static final int VK_R = 82;
+
+    public static final int VK_S = 83;
+
+    public static final int VK_T = 84;
+
+    public static final int VK_U = 85;
+
+    public static final int VK_V = 86;
+
+    public static final int VK_W = 87;
+
+    public static final int VK_X = 88;
+
+    public static final int VK_Y = 89;
+
+    public static final int VK_Z = 90;
+
+    public static final int VK_OPEN_BRACKET = 91;
+
+    public static final int VK_BACK_SLASH = 92;
+
+    public static final int VK_CLOSE_BRACKET = 93;
+
+    public static final int VK_NUMPAD0 = 96;
+
+    public static final int VK_NUMPAD1 = 97;
+
+    public static final int VK_NUMPAD2 = 98;
+
+    public static final int VK_NUMPAD3 = 99;
+
+    public static final int VK_NUMPAD4 = 100;
+
+    public static final int VK_NUMPAD5 = 101;
+
+    public static final int VK_NUMPAD6 = 102;
+
+    public static final int VK_NUMPAD7 = 103;
+
+    public static final int VK_NUMPAD8 = 104;
+
+    public static final int VK_NUMPAD9 = 105;
+
+    public static final int VK_MULTIPLY = 106;
+
+    public static final int VK_ADD = 107;
+
+    public static final int VK_SEPARATER = 108;
+
+    public static final int VK_SEPARATOR = 108;
+
+    public static final int VK_SUBTRACT = 109;
+
+    public static final int VK_DECIMAL = 110;
+
+    public static final int VK_DIVIDE = 111;
+
+    public static final int VK_DELETE = 127;
+
+    public static final int VK_NUM_LOCK = 144;
+
+    public static final int VK_SCROLL_LOCK = 145;
+
+    public static final int VK_F1 = 112;
+
+    public static final int VK_F2 = 113;
+
+    public static final int VK_F3 = 114;
+
+    public static final int VK_F4 = 115;
+
+    public static final int VK_F5 = 116;
+
+    public static final int VK_F6 = 117;
+
+    public static final int VK_F7 = 118;
+
+    public static final int VK_F8 = 119;
+
+    public static final int VK_F9 = 120;
+
+    public static final int VK_F10 = 121;
+
+    public static final int VK_F11 = 122;
+
+    public static final int VK_F12 = 123;
+
+    public static final int VK_F13 = 61440;
+
+    public static final int VK_F14 = 61441;
+
+    public static final int VK_F15 = 61442;
+
+    public static final int VK_F16 = 61443;
+
+    public static final int VK_F17 = 61444;
+
+    public static final int VK_F18 = 61445;
+
+    public static final int VK_F19 = 61446;
+
+    public static final int VK_F20 = 61447;
+
+    public static final int VK_F21 = 61448;
+
+    public static final int VK_F22 = 61449;
+
+    public static final int VK_F23 = 61450;
+
+    public static final int VK_F24 = 61451;
+
+    public static final int VK_PRINTSCREEN = 154;
+
+    public static final int VK_INSERT = 155;
+
+    public static final int VK_HELP = 156;
+
+    public static final int VK_META = 157;
+
+    public static final int VK_BACK_QUOTE = 192;
+
+    public static final int VK_QUOTE = 222;
+
+    public static final int VK_KP_UP = 224;
+
+    public static final int VK_KP_DOWN = 225;
+
+    public static final int VK_KP_LEFT = 226;
+
+    public static final int VK_KP_RIGHT = 227;
+
+    public static final int VK_DEAD_GRAVE = 128;
+
+    public static final int VK_DEAD_ACUTE = 129;
+
+    public static final int VK_DEAD_CIRCUMFLEX = 130;
+
+    public static final int VK_DEAD_TILDE = 131;
+
+    public static final int VK_DEAD_MACRON = 132;
+
+    public static final int VK_DEAD_BREVE = 133;
+
+    public static final int VK_DEAD_ABOVEDOT = 134;
+
+    public static final int VK_DEAD_DIAERESIS = 135;
+
+    public static final int VK_DEAD_ABOVERING = 136;
+
+    public static final int VK_DEAD_DOUBLEACUTE = 137;
+
+    public static final int VK_DEAD_CARON = 138;
+
+    public static final int VK_DEAD_CEDILLA = 139;
+
+    public static final int VK_DEAD_OGONEK = 140;
+
+    public static final int VK_DEAD_IOTA = 141;
+
+    public static final int VK_DEAD_VOICED_SOUND = 142;
+
+    public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
+
+    public static final int VK_AMPERSAND = 150;
+
+    public static final int VK_ASTERISK = 151;
+
+    public static final int VK_QUOTEDBL = 152;
+
+    public static final int VK_LESS = 153;
+
+    public static final int VK_GREATER = 160;
+
+    public static final int VK_BRACELEFT = 161;
+
+    public static final int VK_BRACERIGHT = 162;
+
+    public static final int VK_AT = 512;
+
+    public static final int VK_COLON = 513;
+
+    public static final int VK_CIRCUMFLEX = 514;
+
+    public static final int VK_DOLLAR = 515;
+
+    public static final int VK_EURO_SIGN = 516;
+
+    public static final int VK_EXCLAMATION_MARK = 517;
+
+    public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
+
+    public static final int VK_LEFT_PARENTHESIS = 519;
+
+    public static final int VK_NUMBER_SIGN = 520;
+
+    public static final int VK_PLUS = 521;
+
+    public static final int VK_RIGHT_PARENTHESIS = 522;
+
+    public static final int VK_UNDERSCORE = 523;
+
+    public static final int VK_FINAL = 24;
+
+    public static final int VK_WINDOWS = 524; 
+
+    public static final int VK_CONTEXT_MENU = 525;
+
+    public static final int VK_CONVERT = 28;
+
+    public static final int VK_NONCONVERT = 29;
+
+    public static final int VK_ACCEPT = 30;
+
+    public static final int VK_MODECHANGE = 31;
+
+    public static final int VK_KANA = 21;
+
+    public static final int VK_KANJI = 25;
+
+    public static final int VK_ALPHANUMERIC = 240;
+
+    public static final int VK_KATAKANA = 241;
+
+    public static final int VK_HIRAGANA = 242;
+
+    public static final int VK_FULL_WIDTH = 243;
+
+    public static final int VK_HALF_WIDTH = 244;
+
+    public static final int VK_ROMAN_CHARACTERS = 245;
+
+    public static final int VK_ALL_CANDIDATES = 256;
+
+    public static final int VK_PREVIOUS_CANDIDATE = 257;
+
+    public static final int VK_CODE_INPUT = 258;
+
+    public static final int VK_JAPANESE_KATAKANA = 259;
+
+    public static final int VK_JAPANESE_HIRAGANA = 260;
+
+    public static final int VK_JAPANESE_ROMAN = 261;
+
+    public static final int VK_KANA_LOCK = 262;
+
+    public static final int VK_INPUT_METHOD_ON_OFF = 263;
+
+    public static final int VK_CUT = 65489;
+
+    public static final int VK_COPY = 65485;
+
+    public static final int VK_PASTE = 65487;
+
+    public static final int VK_UNDO = 65483;
+
+    public static final int VK_AGAIN = 65481;
+
+    public static final int VK_FIND = 65488;
+
+    public static final int VK_PROPS = 65482;
+
+    public static final int VK_STOP = 65480;
+
+    public static final int VK_COMPOSE = 65312;
+
+    public static final int VK_ALT_GRAPH = 65406;
+
+    public static final int VK_BEGIN = 65368;
+
+    public static final int VK_UNDEFINED = 0;
+
+    public static final char CHAR_UNDEFINED = (char)(-1);
+
+    public static final int KEY_LOCATION_UNKNOWN = 0;
+
+    public static final int KEY_LOCATION_STANDARD = 1;
+
+    public static final int KEY_LOCATION_LEFT = 2;
+
+    public static final int KEY_LOCATION_RIGHT = 3;
+
+    public static final int KEY_LOCATION_NUMPAD = 4;
+
+    private int keyCode;
+    private char keyChar;
+    private int keyLocation;
+
+    public static String getKeyModifiersText(int modifiers) {
+        return getKeyModifiersExText(extractExFlags(modifiers));
+    }
+
+    static String getKeyModifiersExText(int modifiersEx) {
+        String text = ""; //$NON-NLS-1$
+
+        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
+            text += Toolkit.getProperty("AWT.meta", "Meta"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.control", "Ctrl"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.alt", "Alt"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.shift", "Shift"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.altGraph", "Alt Graph"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public static String getKeyText(int keyCode) {
+        String[] rawName = getPublicStaticFinalIntFieldName(keyCode); //$NON-NLS-1$
+
+        if ((rawName == null) || (rawName.length == 0)) {
+            return ("Unknown keyCode: " + (keyCode >= 0 ? "0x" : "-0x") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Integer.toHexString(Math.abs(keyCode)));
+        }
+
+        String propertyName = getPropertyName(rawName);
+        String defaultName = getDefaultName(rawName);
+
+        return Toolkit.getProperty(propertyName, defaultName);
+    }
+
+    private static String getDefaultName(String[] rawName) {
+        String name = ""; //$NON-NLS-1$
+
+        for (int i = 0; true; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+
+            if (i == (rawName.length - 1)) {
+                break;
+            }
+            name += " "; //$NON-NLS-1$
+        }
+
+        return name;
+    }
+
+    private static String getPropertyName(String[] rawName) {
+        String name = rawName[0].toLowerCase();
+
+        for (int i = 1; i < rawName.length; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+        }
+
+        return ("AWT." + name); //$NON-NLS-1$
+    }
+
+    private static String[] getPublicStaticFinalIntFieldName(int value) {
+        Field[] allFields = KeyEvent.class.getDeclaredFields();
+
+        try {
+            for (Field field : allFields) {
+                Class<?> ssalc = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (ssalc.isPrimitive() && ssalc.getName().equals("int") && //$NON-NLS-1$
+                        Modifier.isFinal(modifiers) && Modifier.isPublic(modifiers) &&
+                        Modifier.isStatic(modifiers))
+                {
+                    if (field.getInt(null) == value){
+                        final String name = field.getName();
+                        final int prefixLength = name.indexOf("_") + 1;
+                        return name.substring(prefixLength).split("_"); //$NON-NLS-1$
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return null;
+    }
+
+    @Deprecated
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode) {
+        this(src, id, when, modifiers, keyCode,
+                (keyCode > (2 << 7) - 1) ? CHAR_UNDEFINED : (char) keyCode);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar) {
+        this(src, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar,
+                    int keyLocation) {
+        super(src, id, when, modifiers);
+
+        if (id == KEY_TYPED) {
+            if (keyCode != VK_UNDEFINED) {
+                // awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.191")); //$NON-NLS-1$
+            }
+            if (keyChar == CHAR_UNDEFINED) {
+                // awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.192")); //$NON-NLS-1$
+            }
+        }
+        
+        if ((keyLocation < KEY_LOCATION_UNKNOWN)
+                || (keyLocation > KEY_LOCATION_NUMPAD)) {
+            // awt.297=Invalid keyLocation
+            throw new IllegalArgumentException(Messages.getString("awt.297")); //$NON-NLS-1$
+        }
+
+        this.keyChar = keyChar;
+        this.keyLocation = keyLocation;
+        this.keyCode = keyCode;
+    }
+
+    public int getKeyCode() {
+        return keyCode;
+    }
+
+    public void setKeyCode(int keyCode) {
+        this.keyCode = keyCode;
+    }
+
+    public char getKeyChar() {
+        return keyChar;
+    }
+
+    public void setKeyChar(char keyChar) {
+        this.keyChar = keyChar;
+    }
+
+    public int getKeyLocation() {
+        return keyLocation;
+    }
+
+    @Override
+    @Deprecated
+    public void setModifiers(int modifiers) {
+        super.setModifiers(modifiers);
+    }
+
+    public boolean isActionKey() {
+        return ((keyChar == CHAR_UNDEFINED) && (keyCode != VK_UNDEFINED) &&
+                !((keyCode == VK_ALT) || (keyCode == VK_ALT_GRAPH) ||
+                    (keyCode == VK_CONTROL) || (keyCode == VK_META) || (keyCode == VK_SHIFT)));
+    }
+
+    @Override
+    public String paramString() {
+        /*
+         * The format is based on 1.5 release behavior
+         * which can be revealed by the following code:
+         *
+         * KeyEvent e = new KeyEvent(new Component() {}, 
+         *       KeyEvent.KEY_PRESSED, 0, 
+         *       KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK, 
+         *       KeyEvent.VK_A, 'A', KeyEvent.KEY_LOCATION_STANDARD);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String locString = null;
+        String paramString = null;
+        String keyCharString = (keyChar == '\n') ?
+                keyCharString = getKeyText(VK_ENTER) : "'" + keyChar + "'"; //$NON-NLS-1$ //$NON-NLS-2$
+
+        switch (id) {
+        case KEY_PRESSED:
+            idString = "KEY_PRESSED"; //$NON-NLS-1$
+            break;
+        case KEY_RELEASED:
+            idString = "KEY_RELEASED"; //$NON-NLS-1$
+            break;
+        case KEY_TYPED:
+            idString = "KEY_TYPED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        switch(keyLocation){
+        case KEY_LOCATION_STANDARD:
+            locString = "KEY_LOCATION_STANDARD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_LEFT:
+            locString = "KEY_LOCATION_LEFT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_RIGHT:
+            locString = "KEY_LOCATION_RIGHT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_NUMPAD:
+            locString = "KEY_LOCATION_NUMPAD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_UNKNOWN:
+            locString = "KEY_LOCATION_UNKNOWN"; //$NON-NLS-1$
+            break;
+        default:
+            locString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",keyCode=" + keyCode; //$NON-NLS-1$
+        if (isActionKey()) {
+            paramString += "," + getKeyText(keyCode); //$NON-NLS-1$
+        } else {
+            paramString += ",keyChar=" + keyCharString; //$NON-NLS-1$
+        }
+        if (getModifiersEx() > 0) {
+            paramString += ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",keyLocation=" + locString; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/KeyListener.java b/awt/java/awt/event/KeyListener.java
new file mode 100644
index 0000000..f20fc90
--- /dev/null
+++ b/awt/java/awt/event/KeyListener.java
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface KeyListener extends EventListener {
+
+    public void keyPressed(KeyEvent e);
+
+    public void keyReleased(KeyEvent e);
+
+    public void keyTyped(KeyEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseAdapter.java b/awt/java/awt/event/MouseAdapter.java
new file mode 100644
index 0000000..4973956
--- /dev/null
+++ b/awt/java/awt/event/MouseAdapter.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseAdapter implements MouseListener {
+
+    public MouseAdapter() {
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+    }
+
+    public void mouseReleased(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseEvent.java b/awt/java/awt/event/MouseEvent.java
new file mode 100644
index 0000000..0b776f9
--- /dev/null
+++ b/awt/java/awt/event/MouseEvent.java
@@ -0,0 +1,226 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class MouseEvent extends InputEvent {
+
+    private static final long serialVersionUID = -991214153494842848L;
+
+    public static final int MOUSE_FIRST = 500;
+
+    public static final int MOUSE_LAST = 507;
+
+    public static final int MOUSE_CLICKED = 500;
+
+    public static final int MOUSE_PRESSED = 501;
+
+    public static final int MOUSE_RELEASED = 502;
+
+    public static final int MOUSE_MOVED = 503;
+
+    public static final int MOUSE_ENTERED = 504;
+
+    public static final int MOUSE_EXITED = 505;
+
+    public static final int MOUSE_DRAGGED = 506;
+
+    public static final int MOUSE_WHEEL = 507;
+
+    public static final int NOBUTTON = 0;
+
+    public static final int BUTTON1 = 1;
+
+    public static final int BUTTON2 = 2;
+
+    public static final int BUTTON3 = 3;
+
+    private boolean popupTrigger;
+    private int clickCount;
+    private int button;
+    private int x;
+    private int y;
+
+    public static String getMouseModifiersText(int modifiers) {
+        final StringBuffer text = new StringBuffer();
+
+        if ((modifiers & META_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.meta", "Meta")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & SHIFT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.shift", "Shift")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.control", "Ctrl")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.alt", "Alt")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button1", "Button1")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button2", "Button2")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button3", "Button3")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        return text.length() == 0 ? text.toString() : text.substring(0, text
+                .length() - 1);
+    }
+
+    static String addMouseModifiersExText(String text, int modifiersEx) {
+        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button1", "Button1"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button2", "Button2"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button3", "Button3"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger) {
+        this(source, id, when, modifiers, x, y,
+             clickCount, popupTrigger, NOBUTTON);
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger, int button) {
+        super(source, id, when, modifiers);
+
+        if ((button != NOBUTTON) && (button != BUTTON1) &&
+                (button != BUTTON2) && (button != BUTTON3)) {
+            // awt.18B=Invalid button value
+            throw new IllegalArgumentException(Messages.getString("awt.18B")); //$NON-NLS-1$
+        }
+
+        this.popupTrigger = popupTrigger;
+        this.clickCount = clickCount;
+        this.button = button;
+        this.x = x;
+        this.y = y;
+    }
+
+    public int getButton() {
+        return button;
+    }
+
+    public int getClickCount() {
+        return clickCount;
+    }
+
+    public Point getPoint() {
+        return new Point(x, y);
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public boolean isPopupTrigger() {
+        return popupTrigger;
+    }
+
+    public void translatePoint(int x, int y) {
+        this.x += x;
+        this.y += y;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseEvent e = new MouseEvent(new Component(){}, 
+         *          MouseEvent.MOUSE_PRESSED, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseEvent.BUTTON1);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String paramString = null;
+
+        switch (id) {
+        case MOUSE_MOVED:
+            idString = "MOUSE_MOVED"; //$NON-NLS-1$
+            break;
+        case MOUSE_CLICKED:
+            idString = "MOUSE_CLICKED"; //$NON-NLS-1$
+            break;
+        case MOUSE_PRESSED:
+            idString = "MOUSE_PRESSED"; //$NON-NLS-1$
+            break;
+        case MOUSE_RELEASED:
+            idString = "MOUSE_RELEASED"; //$NON-NLS-1$
+            break;
+        case MOUSE_DRAGGED:
+            idString = "MOUSE_DRAGGED"; //$NON-NLS-1$
+            break;
+        case MOUSE_ENTERED:
+            idString = "MOUSE_ENTERED"; //$NON-NLS-1$
+            break;
+        case MOUSE_EXITED:
+            idString = "MOUSE_EXITED"; //$NON-NLS-1$
+            break;
+        case MOUSE_WHEEL:
+            idString = "MOUSE_WHEEL"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",(" + getX() + "," + getY() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                ",button=" + button; //$NON-NLS-1$
+        if (getModifiersEx() > 0) {
+            paramString += 
+                    ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",clickCount=" + getClickCount(); //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseListener.java b/awt/java/awt/event/MouseListener.java
new file mode 100644
index 0000000..5d32b0f
--- /dev/null
+++ b/awt/java/awt/event/MouseListener.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseListener extends EventListener {
+
+    public void mouseClicked(MouseEvent e);
+
+    public void mouseEntered(MouseEvent e);
+
+    public void mouseExited(MouseEvent e);
+
+    public void mousePressed(MouseEvent e);
+
+    public void mouseReleased(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseMotionAdapter.java b/awt/java/awt/event/MouseMotionAdapter.java
new file mode 100644
index 0000000..a4bebcc
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseMotionAdapter implements MouseMotionListener {
+
+    public MouseMotionAdapter() {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseMotionListener.java b/awt/java/awt/event/MouseMotionListener.java
new file mode 100644
index 0000000..a5c11da
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseMotionListener extends EventListener {
+
+    public void mouseDragged(MouseEvent e);
+
+    public void mouseMoved(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseWheelEvent.java b/awt/java/awt/event/MouseWheelEvent.java
new file mode 100644
index 0000000..d3ac9d8
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelEvent.java
@@ -0,0 +1,97 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class MouseWheelEvent extends MouseEvent {
+
+    private static final long serialVersionUID = -9187413581993563929L;
+
+    public static final int WHEEL_UNIT_SCROLL = 0;
+
+    public static final int WHEEL_BLOCK_SCROLL = 1;
+
+    private int wheelRotation;
+    private int scrollAmount;
+    private int scrollType;
+
+    public MouseWheelEvent(Component source, int id, long when, int modifiers,
+            int x, int y, int clickCount, boolean popupTrigger, int scrollType,
+            int scrollAmount, int wheelRotation) {
+        super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
+
+        this.scrollType = scrollType;
+        this.scrollAmount = scrollAmount;
+        this.wheelRotation = wheelRotation;
+    }
+
+    public int getScrollAmount() {
+        return scrollAmount;
+    }
+
+    public int getScrollType() {
+        return scrollType;
+    }
+
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+
+    public int getUnitsToScroll() {
+        return (scrollAmount * wheelRotation);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseWheelEvent e = new MouseWheelEvent(new Component(){}, 
+         *          MouseWheelEvent.MOUSE_WHEEL, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseWheelEvent.WHEEL_UNIT_SCROLL,
+         *          1, 3);
+         * System.out.println(e);
+         */
+
+        String paramString = super.paramString();
+        String typeString = null;
+
+        switch (scrollType) {
+        case WHEEL_UNIT_SCROLL:
+            typeString = "WHEEL_UNIT_SCROLL"; //$NON-NLS-1$
+            break;
+        case WHEEL_BLOCK_SCROLL:
+            typeString = "WHEEL_BLOCK_SCROLL"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += ",scrollType=" + typeString + //$NON-NLS-1$
+                ",scrollAmount=" + scrollAmount +  //$NON-NLS-1$
+                ",wheelRotation=" + wheelRotation; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseWheelListener.java b/awt/java/awt/event/MouseWheelListener.java
new file mode 100644
index 0000000..8ca1c8b
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelListener.java
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseWheelListener extends EventListener {
+
+    public void mouseWheelMoved(MouseWheelEvent e);
+
+}
diff --git a/awt/java/awt/event/PaintEvent.java b/awt/java/awt/event/PaintEvent.java
new file mode 100644
index 0000000..d0573e1
--- /dev/null
+++ b/awt/java/awt/event/PaintEvent.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+public class PaintEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 1267492026433337593L;
+
+    public static final int PAINT_FIRST = 800;
+
+    public static final int PAINT_LAST = 801;
+
+    public static final int PAINT = 800;
+
+    public static final int UPDATE = 801;
+
+    private Rectangle updateRect;
+
+    public PaintEvent(Component source, int id, Rectangle updateRect) {
+        super(source, id);
+
+        this.updateRect = updateRect;
+    }
+
+    public Rectangle getUpdateRect() {
+        return updateRect;
+    }
+
+    public void setUpdateRect(Rectangle updateRect) {
+        this.updateRect = updateRect;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * PaintEvent e = new PaintEvent(new Component(){}, 
+         *          PaintEvent.PAINT, new Rectangle(0, 0, 10, 20)); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case PAINT:
+            typeString = "PAINT"; //$NON-NLS-1$
+            break;
+        case UPDATE:
+            typeString = "UPDATE"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",updateRect=" + updateRect; //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/TextEvent.java b/awt/java/awt/event/TextEvent.java
new file mode 100644
index 0000000..e2bfd96
--- /dev/null
+++ b/awt/java/awt/event/TextEvent.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class TextEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 6269902291250941179L;
+
+    public static final int TEXT_FIRST = 900;
+
+    public static final int TEXT_LAST = 900;
+
+    public static final int TEXT_VALUE_CHANGED = 900;
+
+    public TextEvent(Object src, int id) {
+        super(src, id);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * TextEvent e = new TextEvent(new Component(){}, 
+         *          TextEvent.TEXT_VALUE_CHANGED); 
+         * System.out.println(e);
+         */
+
+        return (id == TEXT_VALUE_CHANGED) ? 
+                "TEXT_VALUE_CHANGED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/TextListener.java b/awt/java/awt/event/TextListener.java
new file mode 100644
index 0000000..6c5a671
--- /dev/null
+++ b/awt/java/awt/event/TextListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface TextListener extends EventListener {
+
+    public void textValueChanged(TextEvent e);
+
+}
+
diff --git a/awt/java/awt/event/WindowAdapter.java b/awt/java/awt/event/WindowAdapter.java
new file mode 100644
index 0000000..9d4b377
--- /dev/null
+++ b/awt/java/awt/event/WindowAdapter.java
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener {
+
+    public WindowAdapter() {
+    }
+
+    public void windowActivated(WindowEvent e) {
+    }
+
+    public void windowClosed(WindowEvent e) {
+    }
+
+    public void windowClosing(WindowEvent e) {
+    }
+
+    public void windowDeactivated(WindowEvent e) {
+    }
+
+    public void windowDeiconified(WindowEvent e) {
+    }
+
+    public void windowGainedFocus(WindowEvent e) {
+    }
+
+    public void windowIconified(WindowEvent e) {
+    }
+
+    public void windowLostFocus(WindowEvent e) {
+    }
+
+    public void windowOpened(WindowEvent e) {
+    }
+
+    public void windowStateChanged(WindowEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/WindowEvent.java b/awt/java/awt/event/WindowEvent.java
new file mode 100644
index 0000000..65a30e4
--- /dev/null
+++ b/awt/java/awt/event/WindowEvent.java
@@ -0,0 +1,162 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+
+//???AWT
+//import java.awt.Window;
+//import java.awt.Frame;
+
+public class WindowEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -1567959133147912127L;
+
+    public static final int WINDOW_FIRST = 200;
+
+    public static final int WINDOW_OPENED = 200;
+
+    public static final int WINDOW_CLOSING = 201;
+
+    public static final int WINDOW_CLOSED = 202;
+
+    public static final int WINDOW_ICONIFIED = 203;
+
+    public static final int WINDOW_DEICONIFIED = 204;
+
+    public static final int WINDOW_ACTIVATED = 205;
+
+    public static final int WINDOW_DEACTIVATED = 206;
+
+    public static final int WINDOW_GAINED_FOCUS = 207;
+
+    public static final int WINDOW_LOST_FOCUS = 208;
+
+    public static final int WINDOW_STATE_CHANGED = 209;
+
+    public static final int WINDOW_LAST = 209;
+
+    //???AWT: private Window oppositeWindow;
+    private int oldState;
+    private int newState;
+
+    //???AWT
+    /*
+    public WindowEvent(Window source, int id) {
+        this(source, id, null);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite) {
+        this(source, id, opposite, Frame.NORMAL, Frame.NORMAL);
+    }
+
+    public WindowEvent(Window source, int id, int oldState, int newState) {
+        this(source, id, null, oldState, newState);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite, 
+                       int oldState, int newState) {
+        super(source, id);
+
+        oppositeWindow = opposite;
+        this.oldState = oldState;
+        this.newState = newState;
+    }
+    */
+    //???AWT: Fake constructor
+    public WindowEvent() {
+        super(null, 0);
+    }
+    
+    public int getNewState() {
+        return newState;
+    }
+
+    public int getOldState() {
+        return oldState;
+    }
+
+    //???AWT
+    /*
+    public Window getOppositeWindow() {
+        return oppositeWindow;
+    }
+
+    public Window getWindow() {
+        return (Window) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * WindowEvent e = new WindowEvent(new Frame(), 
+         *          WindowEvent.WINDOW_OPENED); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case WINDOW_OPENED:
+            typeString = "WINDOW_OPENED"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSING:
+            typeString = "WINDOW_CLOSING"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSED:
+            typeString = "WINDOW_CLOSED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ICONIFIED:
+            typeString = "WINDOW_ICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEICONIFIED:
+            typeString = "WINDOW_DEICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ACTIVATED:
+            typeString = "WINDOW_ACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEACTIVATED:
+            typeString = "WINDOW_DEACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_GAINED_FOCUS:
+            typeString = "WINDOW_GAINED_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_LOST_FOCUS:
+            typeString = "WINDOW_LOST_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_STATE_CHANGED:
+            typeString = "WINDOW_STATE_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        //???AWT
+        /*
+        return typeString + ",opposite=" + oppositeWindow + //$NON-NLS-1$
+                ",oldState=" + oldState + ",newState=" + newState; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return typeString;
+    }
+
+}
diff --git a/awt/java/awt/event/WindowFocusListener.java b/awt/java/awt/event/WindowFocusListener.java
new file mode 100644
index 0000000..e0200f2
--- /dev/null
+++ b/awt/java/awt/event/WindowFocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowFocusListener extends EventListener {
+
+    public void windowGainedFocus(WindowEvent e);
+
+    public void windowLostFocus(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowListener.java b/awt/java/awt/event/WindowListener.java
new file mode 100644
index 0000000..20a2b08
--- /dev/null
+++ b/awt/java/awt/event/WindowListener.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowListener extends EventListener {
+
+    public void windowActivated(WindowEvent e);
+
+    public void windowClosed(WindowEvent e);
+
+    public void windowClosing(WindowEvent e);
+
+    public void windowDeactivated(WindowEvent e);
+
+    public void windowDeiconified(WindowEvent e);
+
+    public void windowIconified(WindowEvent e);
+
+    public void windowOpened(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowStateListener.java b/awt/java/awt/event/WindowStateListener.java
new file mode 100644
index 0000000..12dbc20
--- /dev/null
+++ b/awt/java/awt/event/WindowStateListener.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowStateListener extends EventListener {
+
+    public void windowStateChanged(WindowEvent e);
+
+}
+
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..766300d
--- /dev/null
+++ b/awt/java/awt/font/FontRenderContext.java
@@ -0,0 +1,168 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * The FontRenderContext class contains the information 
+ * about text measurement. Anti-aliasing and fractional-metrics
+ * modes are defined by an application and affect the size of
+ * a character.
+ */
+public class FontRenderContext {
+
+    // Affine transform of this mode
+    /** The transform. */
+    private AffineTransform transform;
+
+    // Is the anti-aliased mode used
+    /** The anti aliased. */
+    private boolean fAntiAliased;
+
+    // Is the fractional metrics used
+    /** The fractional metrics. */
+    private boolean fFractionalMetrics;
+
+
+    /**
+     * Instantiates a new FontRenderContext object with the specified
+     * AffineTransform, anti-aliasing and fractional metrics flags.
+     * 
+     * @param trans the AffineTransform.
+     * @param antiAliased the anti-aliasing flag.
+     * @param usesFractionalMetrics the fractional metrics flag.
+     */
+    public FontRenderContext(AffineTransform trans, boolean antiAliased, 
+            boolean usesFractionalMetrics) {
+        if (trans != null){
+            transform = new AffineTransform(trans);
+        }
+        fAntiAliased = antiAliased;
+        fFractionalMetrics = usesFractionalMetrics;
+    }
+
+    /**
+     * Instantiates a new FontRenderContext object.
+     */
+    protected FontRenderContext() {
+    }
+
+    /**
+     * Compares the specified Object with current FontRenderContext object. 
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to current
+     * FontRenderContext object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                return equals((FontRenderContext) obj);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+        return false;
+
+    }
+
+    /**
+     * Gets the transform which is used for scaling typographical points 
+     * to pixels in this FontRenderContext.
+     * 
+     * @return the AffineTransform which is used for scaling typographical 
+     * points to pixels in this FontRenderContext.
+     */
+    public AffineTransform getTransform() {
+        if (transform != null){
+            return new AffineTransform(transform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Compares the specified FontRenderContext object with current 
+     * FontRenderContext.
+     * 
+     * @param frc the FontRenderContext object to be compared.
+     * 
+     * @return true, if the specified FontRenderContext object is
+     * equal to current FontRenderContext.
+     */
+    public boolean equals(FontRenderContext frc) {
+        if (this == frc){
+            return true;
+        }
+
+        if (frc == null){
+            return false;
+        }
+
+        if (!frc.getTransform().equals(this.getTransform()) &&
+            !frc.isAntiAliased() == this.fAntiAliased &&
+            !frc.usesFractionalMetrics() == this.fFractionalMetrics){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the text fractional metrics are used in 
+     * this FontRenderContext.
+     * 
+     * @return true, if the text fractional metrics are used in 
+     * this FontRenderContext, false otherwise.
+     */
+    public boolean usesFractionalMetrics() {
+        return this.fFractionalMetrics;
+    }
+
+    /**
+     * Returns true if anti-aliasing is used in this FontRenderContext.
+     * 
+     * @return true, if is anti-aliasing is used in this FontRenderContext,
+     * false otherwise.
+     */
+    public boolean isAntiAliased() {
+        return this.fAntiAliased;
+    }
+
+    /**
+     * Returns hash code of the FontRenderContext object.
+     * 
+     * @return the hash code of the FontRenderContext object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getTransform().hashCode() ^
+                new Boolean(this.fFractionalMetrics).hashCode() ^
+                new Boolean(this.fAntiAliased).hashCode();
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..4c3e02e
--- /dev/null
+++ b/awt/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,185 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GlyphJustificationInfo class provides information about 
+ * the glyph's justification properties. There are four justification 
+ * properties: weight, priority, absorb, and limit.
+ * <p>
+ * There are two sets of metrics: growing and shrinking. 
+ * Growing metrics are used when the glyphs are to be spread apart 
+ * to fit a larger width. Shrinking metrics are used when the glyphs 
+ * are to be moved together to fit a smaller width.
+ */
+public final class GlyphJustificationInfo {
+
+    /** 
+     * The Constant PRIORITY_KASHIDA indicates the highest 
+     * justification priority.
+     */
+    public static final int PRIORITY_KASHIDA = 0;
+
+    /**
+     * The Constant PRIORITY_WHITESPACE indicates the second highest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_WHITESPACE = 1;
+
+    /** 
+     * The Constant PRIORITY_INTERCHAR indicates the second lowest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_INTERCHAR = 2;
+
+    /**
+     * The Constant PRIORITY_NONE indicates the lowest justification 
+     * priority.
+     */
+    public static final int PRIORITY_NONE = 3;
+
+    /** 
+     * The grow absorb flag indicates if this glyph absorbs all extra 
+     * space at this and lower priority levels when it grows.
+     */
+    public final boolean growAbsorb;
+
+    /** 
+     * The grow left limit value represents the maximum value by which 
+     * the left side of this glyph grows. 
+     */
+    public final float growLeftLimit;
+
+    /** 
+     * The grow right limit value repesents the maximum value by which 
+     * the right side of this glyph grows.
+     */
+    public final float growRightLimit;
+
+    /** 
+     * The grow priority value represents the priority level of this 
+     * glyph as it is growing. 
+     */
+    public final int growPriority;
+
+    /** 
+     * The shrink absorb fleg indicates this glyph absorbs all remaining 
+     * shrinkage at this and lower priority levels as it shrinks. 
+     */
+    public final boolean shrinkAbsorb;
+
+    /** 
+     * The shrink left limit value represents the maximum value by which 
+     * the left side of this glyph shrinks. 
+     */
+    public final float shrinkLeftLimit;
+
+    /** 
+     * The shrink right limit value represents the maximum value by which 
+     * the right side of this glyph shrinks. 
+     */
+    public final float shrinkRightLimit;
+
+    /**
+     * The shrink priority represents the glyth's priority level 
+     * as it is shrinking.
+     */
+    public final int shrinkPriority;
+
+    /** 
+     * The weight of the glyph. 
+     */
+    public final float weight;
+
+    /**
+     * Instantiates a new GlyphJustificationInfo object which contains
+     * glyph's justification properties.
+     * 
+     * @param weight the weight of glyph.
+     * @param growAbsorb indicates if this glyph contais all space 
+     * at this priority and lower priority levels when it grows.
+     * @param growPriority indicates the priority level of this glyph 
+     * when it grows.
+     * @param growLeftLimit indicates the maximum value of which the 
+     * left side of this glyph can grow.
+     * @param growRightLimit the maximum value of which the right side of 
+     * this glyph can grow.
+     * @param shrinkAbsorb indicates if this glyph contains all remaining
+     * shrinkage at this and lower priority levels when it shrinks.
+     * @param shrinkPriority indicates the glyph's priority level when 
+     * it shrinks.
+     * @param shrinkLeftLimit indicates the maximum value of which 
+     * the left side of this glyph can shrink. 
+     * @param shrinkRightLimit indicates the maximum amount by which 
+     * the right side of this glyph can shrink.
+     */
+    public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
+            float growLeftLimit, float growRightLimit, boolean shrinkAbsorb,
+            int shrinkPriority, float shrinkLeftLimit, float shrinkRightLimit) {
+
+        if (weight < 0) {
+            // awt.19C=weight must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
+        }
+        this.weight = weight;
+
+        if (growLeftLimit < 0) {
+            // awt.19D=growLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
+        }
+        this.growLeftLimit = growLeftLimit;
+
+        if (growRightLimit < 0) {
+            // awt.19E=growRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
+        }
+        this.growRightLimit = growRightLimit;
+
+        if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
+            // awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
+        }
+        this.shrinkPriority = shrinkPriority;
+
+        if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
+            // awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
+        }
+        this.growPriority = growPriority;
+
+        if (shrinkLeftLimit < 0) {
+            // awt.201=shrinkLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
+        }
+        this.shrinkLeftLimit = shrinkLeftLimit;
+
+        if (shrinkRightLimit < 0) {
+            // awt.202=shrinkRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
+        }
+        this.shrinkRightLimit = shrinkRightLimit;
+
+        this.shrinkAbsorb = shrinkAbsorb;
+        this.growAbsorb = growAbsorb;
+    }
+}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..d96ef18
--- /dev/null
+++ b/awt/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,248 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphMetrics class provides information about the size and shape 
+ * of a single glyph. 
+ * Each glyph has information to specify whether its baseline is horizontal 
+ * or vertical as well as information on how it interacts with 
+ * other characters in a text, given as one of the
+ * following types: STANDARD, LIGATURE, COMBINING, or COMPONENT.
+ */
+public final class GlyphMetrics {
+
+    // advance width of the glyph character cell
+    /** The advance x. */
+    private float advanceX;
+    
+    // advance height of the glyph character cell
+    /** The advance y. */
+    private float advanceY;
+
+    // flag if the glyph horizontal
+    /** The horizontal. */
+    private boolean horizontal;
+
+    // glyph type code 
+    /** The glyph type. */
+    private byte glyphType;
+    
+    // bounding box for outline of the glyph
+    /** The bounds. */
+    private Rectangle2D.Float bounds;
+
+    /** 
+     * The Constant STANDARD indicates a glyph that represents a single 
+     * character. 
+     */
+    public static final byte STANDARD = 0;
+
+    /** 
+     * The Constant LIGATURE indicates a glyph that represents multiple 
+     * characters as a ligature. 
+     */
+    public static final byte LIGATURE = 1;
+
+    /** 
+     * The Constant COMBINING indicates a glyph which has no caret position 
+     * between glyphs (for example umlaut).
+     */
+    public static final byte COMBINING = 2;
+
+    /** 
+     * The Constant COMPONENT indicates a glyph with no corresponding character 
+     * in the backing store.
+     */
+    public static final byte COMPONENT = 3;
+
+    /** 
+     * The Constant WHITESPACE indicates a glyph without visual 
+     * representation. 
+     */
+    public static final byte WHITESPACE = 4;
+
+    /**
+     * Instantiates a new GlyphMetrics object with the specified parameters.
+     * 
+     * @param horizontal specifies if metrics are for a horizontal baseline 
+     * (true value), or a vertical baseline (false value).
+     * @param advanceX the X component of the glyph's advance.
+     * @param advanceY the Y component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, 
+            Rectangle2D bounds, byte glyphType) {
+        this.horizontal = horizontal;
+        this.advanceX = advanceX;
+        this.advanceY = advanceY;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
+     * 
+     * @param advanceX the X component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
+        this.advanceX = advanceX;
+        this.advanceY = 0;
+
+        this.horizontal = true;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Gets the glyph's bounds.
+     * 
+     * @return glyph's bounds.
+     */
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D.Float) this.bounds.clone();
+    }
+
+    /**
+     * Checks if this glyph is whitespace or not.
+     * 
+     * @return true, if this glyph is whitespace, false otherwise.
+     */
+    public boolean isWhitespace() {
+        return ((this.glyphType & 4) == WHITESPACE);
+    }
+
+    /**
+     * Checks if this glyph is standard or not.
+     * 
+     * @return true, if this glyph is standard, false otherwise.
+     */
+    public boolean isStandard() {
+        return ((this.glyphType & 3) == STANDARD);
+    }
+
+    /**
+     * Checks if this glyph is ligature or not.
+     * 
+     * @return true, if this glyph is ligature, false otherwise.
+     */
+    public boolean isLigature() {
+        return ((this.glyphType & 3) == LIGATURE);
+    }
+
+    /**
+     * Checks if this glyph is component or not.
+     * 
+     * @return true, if this glyph is component, false otherwise.
+     */
+    public boolean isComponent() {
+        return ((this.glyphType & 3) == COMPONENT);
+    }
+
+    /**
+     * Checks if this glyph is combining or not.
+     * 
+     * @return true, if this glyph is combining, false otherwise.
+     */
+    public boolean isCombining() {
+        return ((this.glyphType & 3) == COMBINING);
+    }
+
+    /**
+     * Gets the glyph's type.
+     * 
+     * @return the glyph's type.
+     */
+    public int getType() {
+        return this.glyphType;
+    }
+
+    /**
+     * Gets the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     * 
+     * @return the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     */
+    public float getRSB() {
+        if (this.horizontal) {
+            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
+        }
+        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
+    }
+
+    /**
+     * Gets the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     * 
+     * @return the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     */
+    public float getLSB() {
+        if (this.horizontal) {
+            return this.bounds.x;
+        }
+        return this.bounds.y;
+    }
+
+    /**
+     * Gets the Y component of the glyph's advance.
+     * 
+     * @return the Y component of the glyph's advance.
+     */
+    public float getAdvanceY() {
+        return this.advanceY;
+    }
+
+    /**
+     * Gets the X component of the glyph's advance.
+     * 
+     * @return the X component of the glyph's advance.
+     */
+    public float getAdvanceX() {
+        return this.advanceX;
+    }
+
+    /**
+     * Gets the glyph's advance along the baseline.
+     * 
+     * @return the glyph's advance.
+     */
+    public float getAdvance() {
+        if (this.horizontal) {
+            return this.advanceX;
+        }
+        return this.advanceY;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..b3c9406
--- /dev/null
+++ b/awt/java/awt/font/GlyphVector.java
@@ -0,0 +1,394 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphVector class contains a collection of glyphs with geometric 
+ * information and each glyph's location. Each GlyphVector can be associated 
+ * with only one Font. GlyphVector contains the following properties for 
+ * each glyph:
+ * <ul>
+ * <li>the glyph position;</li>
+ * <li>the transform of the glyph;</li>
+ * <li>the metrics of the glyph in the context of the GlyphVector.</li>
+ * </ul>
+ */
+public abstract class GlyphVector implements Cloneable {
+
+    /** 
+     * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector 
+     * has per-glyph transforms.
+     */
+    public static final int FLAG_HAS_TRANSFORMS = 1;
+
+    /** 
+     * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that 
+     * the GlyphVector has per-glyph position adjustments. 
+     */
+    public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+
+    /** 
+     * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a 
+     * right to left run direction.
+     */
+    public static final int FLAG_RUN_RTL = 4;
+
+    /** 
+     * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector 
+     * has a complex glyph to char mapping.
+     */
+    public static final int FLAG_COMPLEX_GLYPHS = 8;
+
+    /** 
+     * The Constant FLAG_MASK indicates a mask for supported flags 
+     * from getLayoutFlags.
+     */
+    public static final int FLAG_MASK = 15; // (|) mask of other flags
+
+    /**
+     * Instantiates a new GlyphVector.
+     */
+    public GlyphVector() {
+    }
+
+    /**
+     * Gets the pixel bounds of the GlyphVector when rendered
+     * at the specified location with the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return the pixel bounds
+     */
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+        // default implementation - integer Rectangle, that encloses visual 
+        // bounds rectangle
+        Rectangle2D visualRect = getVisualBounds();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the pixel bounds of the glyph with the specified index in
+     * this GlyphVector which is rendered with the specified
+     * FontRenderContext at the specified location.
+     * 
+     * @param index the glyph index in this GlyphVector.
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return a Rectangle bounds.
+     */
+    public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, 
+            float x, float y) {
+        Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the visual bounds of the GlyphVector. 
+     * 
+     * @return the visual bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Gets the logical bounds of the GlyphVector. 
+     * 
+     * @return the logical bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Sets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * @param newPos the new position of the glyph at the specified glyphIndex.
+     */
+    public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
+
+    /**
+     * Gets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the position of the specified glyph in this GlyphVector.
+     */
+    public abstract Point2D getGlyphPosition(int glyphIndex);
+
+    /**
+     * Sets the affine transform to a glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param trans the AffineTransform to be assigned to the
+     * specified glyph.
+     */
+    public abstract void setGlyphTransform(int glyphIndex, 
+            AffineTransform trans);
+
+    /**
+     * Gets the transform of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the new transform of the glyph.
+     */
+    public abstract AffineTransform getGlyphTransform(int glyphIndex);
+
+    /**
+     * Compares this GlyphVector with the specified GlyphVector objects.
+     * 
+     * @param glyphVector the GlyphVector object to be compared.
+     * 
+     * @return true, if this GlyphVector is equal to the specified GlyphVector
+     * object, false otherwise.
+     */
+    public abstract boolean equals(GlyphVector glyphVector);
+
+    /**
+     * Gets the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex index in this GlyphVector.
+     * 
+     * @return the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     */
+    public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
+
+    /**
+     * Gets the justification information of the glyph 
+     * whose index is specified.
+     * 
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the GlyphJustificationInfo for the specified glyph. 
+     */
+    public abstract GlyphJustificationInfo getGlyphJustificationInfo(
+            int glyphIndex);
+
+    /**
+     * Gets the FontRenderContext of this GlyphVector.
+     * 
+     * @return the FontRenderContext of this GlyphVector.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector, translated a 
+     * distance of x in the X direction and y in the Y direction. 
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param x the distance in the X direction to translate the 
+     * shape object before returning it.
+     * @param y the distance in the Y direction to translate the 
+     * shape object before returning it.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public Shape getGlyphOutline(int glyphIndex, float x, float y) {
+        Shape initialShape = getGlyphOutline(glyphIndex);
+        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
+        return trans.createTransformedShape(initialShape);
+    }
+
+    /**
+     * Gets the visual bounds of the specified glyph in the GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the glyph visual bounds of the glyph with the specified
+     * index in the GlyphVector.
+     */
+    public abstract Shape getGlyphVisualBounds(int glyphIndex);
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector. 
+     *  
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public abstract Shape getGlyphOutline(int glyphIndex);
+
+    /**
+     * Gets the logical bounds of the specified glyph in 
+     * the GlyphVector. 
+     * 
+     * @param glyphIndex the index in this GlyphVector of the glyph from which 
+     * to retrieve its logical bounds
+     * 
+     * @return the logical bounds of the specified glyph in 
+     * the GlyphVector.
+     */
+    public abstract Shape getGlyphLogicalBounds(int glyphIndex);
+
+    /**
+     * Gets the visual representation of this GlyphVector rendered in
+     * x, y location as a Shape object.
+     * 
+     * @param x the x coordinate of the GlyphVector.
+     * @param y the y coordinate of the GlyphVector.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline(float x, float y);
+
+    /**
+     * Gets the visual representation of this GlyphVector as a Shape object.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline();
+
+    /**
+     * Gets the font of this GlyphVector.
+     * 
+     * @return the font of this GlyphVector.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets an array of the glyph codes of the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index into this GlyphVector at which 
+     * to start retrieving glyph codes.
+     * @param numEntries the number of glyph codes.
+     * @param codeReturn the array into which the resulting 
+     * glyphcodes will be written.
+     * 
+     * @return the array of the glyph codes.
+     */
+    public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn);
+
+    /**
+     * Gets an array of the character indices of 
+     * the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyph indices to return.
+     * @param codeReturn the array into which the resulting character 
+     * indices will be written.
+     * 
+     * @return an array of character indices for the specifies glyphs.
+     */
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn) {
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++){
+            codeReturn[i] = getGlyphCharIndex(i+beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Gets an array of the positions of the specified glyphs in 
+     * this GlyphVector.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyphs to return information for.
+     * @param positionReturn the array where the result will be stored. 
+     * 
+     * @return an array of glyph positions.
+     */
+    public abstract float[] getGlyphPositions(int beginGlyphIndex, 
+            int numEntries, float[] positionReturn);
+
+    /**
+     * Gets the glyph code of the specified glyph.
+     * 
+     * @param glyphIndex the index in this GlyphVector which corresponds 
+     * to the glyph from which to retrieve the glyphcode.
+     * 
+     * @return the glyphcode of the specified glyph.
+     */
+    public abstract int getGlyphCode(int glyphIndex);
+
+    /**
+     * Gets the first logical character's index of the specified glyph. 
+     *  
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the the first logical character's index.
+     */
+    public int getGlyphCharIndex(int glyphIndex){
+        // default implemetation one-to-one
+        return glyphIndex;
+    }
+
+    /**
+     * Sets default layout to this GlyphVector. 
+     */
+    public abstract void performDefaultLayout();
+
+    /**
+     * Gets the number of glyphs in the GlyphVector.
+     * 
+     * @return the number of glyphs in the GlyphVector.
+     */
+    public abstract int getNumGlyphs();
+
+    /**
+     * Gets flags which describe the global state of the GlyphVector. 
+     * The default implementation returns 0.
+     * 
+     * @return the layout flags
+     */
+    public int getLayoutFlags(){
+        // default implementation - returned value is 0
+        return 0;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..2f41951
--- /dev/null
+++ b/awt/java/awt/font/GraphicAttribute.java
@@ -0,0 +1,196 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicAttribute abstract class provides an opportunity to
+ * insert graphical elements in printed text.   
+ */
+public abstract class GraphicAttribute {
+
+    /** 
+     * The Constant TOP_ALIGNMENT indicates using the top line to 
+     * calculate placement of graphics.
+     */
+    public static final int TOP_ALIGNMENT = -1;
+
+    /** 
+     * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to 
+     * calculate placement of graphics. 
+     */
+    public static final int BOTTOM_ALIGNMENT = -2;
+
+    /** 
+     * The Constant ROMAN_BASELINE indicates the placement of the roman 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** 
+     * The Constant CENTER_BASELINE indicates the placement of the center 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int CENTER_BASELINE = 1;
+
+    /** 
+     * The Constant HANGING_BASELINE indicates the placement of the hanging 
+     * baseline with respect to the graphics origin. 
+     */
+    public static final int HANGING_BASELINE = 2;
+
+    // the alignment of this GraphicAttribute
+    /** The alignment. */
+    private int alignment;
+
+    /**
+     * Instantiates a new graphic attribute with the specified alignment.
+     * 
+     * @param align the specified alignment.
+     */
+    protected GraphicAttribute(int align) {
+        if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
+            // awt.198=Illegal alignment argument
+            throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
+        }
+        this.alignment = align;
+    }
+
+    /**
+     * Draws the GraphicAttribute at the specified location.
+     * 
+     * @param graphics the Graphics.
+     * @param x the X coordinate of GraphicAttribute location.
+     * @param y the Y coordinate of GraphicAttribute location.
+     */
+    public abstract void draw(Graphics2D graphics, float x, float y);
+
+    /**
+     * Gets the GraphicAttribute's advance. It's the distance from the point 
+     * at which the graphic is rendered and the point where the next character 
+     * or graphic is rendered.
+     * 
+     * @return the GraphicAttribute's advance.
+     */
+    public abstract float getAdvance();
+
+    /**
+     * Gets the alignment of this GraphicAttribute.
+     * 
+     * @return the alignment of this GraphicAttribute.
+     */
+    public final int getAlignment() {
+        return this.alignment;
+    }
+
+    /**
+     * Gets the ascent of this GraphicAttribute.
+     * 
+     * @return the ascent of this GraphicAttribute.
+     */
+    public abstract float getAscent();
+
+    /**
+     * Gets the bounds of this GraphicAttribute.
+     * 
+     * @return the bounds of this GraphicAttribute.
+     */
+    public Rectangle2D getBounds() {
+        float ascent = getAscent();
+        float advance = getAdvance();
+        float descent = getDescent();
+
+        // Default implementation - see API documentation.
+        return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
+    }
+
+    /**
+     * Gets the descent of this GraphicAttribute.
+     * 
+     * @return the descent of this GraphicAttribute.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the GlyphJustificationInfo of this GraphicAttribute.
+     * 
+     * @return the GlyphJustificationInfo of this GraphicAttribute.
+     */
+    public GlyphJustificationInfo getJustificationInfo() {
+        
+        /* Default implementation.
+         * Since documentation doesn't describe default values,
+         * they were calculated based on 1.5 release 
+         * behavior and can be obtained using next test sample:
+         * 
+         *    // Create GraphicAttribute class implementation
+         *    public class MyGraphicAttribute extends GraphicAttribute {
+         *        protected MyGraphicAttribute(int align) {
+         *            super(align);
+         *        }
+         *
+         *        public float getDescent() {
+         *           return 0;
+         *        }
+         *
+         *        public float getAdvance() {
+         *           return 1;
+         *        }
+         *
+         *        public void draw(Graphics2D g2, float x, float y) {
+         *        }
+         *
+         *        public float getAscent() {
+         *            return 0;
+         *        }
+         *    }
+         *
+         *    MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0);
+         *    // print justification parameters
+         *    System.out.println(myGA.getJustificationInfo().growAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().growLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().growPriority);
+         *    System.out.println(myGA.getJustificationInfo().growRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkPriority);
+         *    System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().weight);
+         */
+        float advance = getAdvance();
+        return new GlyphJustificationInfo(
+                                    advance,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_INTERCHAR,
+                                    advance / 3,
+                                    advance / 3,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_WHITESPACE,
+                                    0,
+                                    0);
+    }
+
+}
+
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..41f90b8
--- /dev/null
+++ b/awt/java/awt/font/ImageGraphicAttribute.java
@@ -0,0 +1,179 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ImageGraphicAttribute class provides an opportunity to insert 
+ * images to a text.
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute {
+
+    // Image object rendered by this ImageGraphicAttribute
+    /** The image. */
+    private Image fImage;
+
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // the width of the image object
+    /** The img width. */
+    private float fImgWidth;
+
+    // the height of the image object
+    /** The img height. */
+    private float fImgHeight;
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image,
+     * alignment and origins.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     * @param originX the origin X coordinate in the image of
+     * ImageGraphicAttribute.  
+     * @param originY the origin Y coordinate in the image of
+     * ImageGraphicAttribute.  
+     */
+    public ImageGraphicAttribute(Image image, int alignment, float originX, 
+            float originY) {
+        super(alignment);
+
+        this.fImage = image;
+        this.fOriginX = originX;
+        this.fOriginY = originY;
+
+        this.fImgWidth = fImage.getWidth(null);
+        this.fImgHeight = fImage.getHeight(null);
+
+    }
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image and
+     * alignment.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     */
+    public ImageGraphicAttribute(Image image, int alignment) {
+        this(image, alignment, 0, 0);
+    }
+
+    /**
+     * Returns a hash code of this ImageGraphicAttribute object.
+     * 
+     * @return the hash code of this ImageGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fImage.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares the specified ImageGraphicAttribute object with this
+     * ImageGraphicAttribute object.
+     * 
+     * @param iga the ImageGraphicAttribute object to be compared.
+     * 
+     * @return true, if the specified ImageGraphicAttribute object is equal to
+     * this ImageGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ImageGraphicAttribute iga) {
+        if (iga == null) {
+            return false;
+        }
+
+        if (iga == this) {
+            return true;
+        }
+
+        return (fOriginX == iga.fOriginX &&
+                fOriginY == iga.fOriginY &&
+                getAlignment() == iga.getAlignment() &&
+                fImage.equals(iga.fImage));
+    }
+
+    /**
+     * Compares the specified Object with this ImageGraphicAttribute object.
+     *  
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to this
+     * ImageGraphicAttribute object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ImageGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getAdvance()
+     */
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fImgWidth - fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getDescent()
+     */
+    @Override
+    public float getDescent() {
+        return Math.max(0, fImgHeight - fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..efce615
--- /dev/null
+++ b/awt/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+//???AWT: import java.text.BreakIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class LineBreakMeasurer provides methods to measure the graphical 
+ * representation of a text in order to determine where to add line 
+ * breaks so the resulting line of text fits its wrapping width. 
+ * The wrapping width defines the visual width of the paragraph.
+ */
+public final class LineBreakMeasurer {
+    
+    /** The tm. */
+    private TextMeasurer tm = null;
+    //???AWT private BreakIterator bi = null;
+    /** The position. */
+    private int position = 0;
+    
+    /** The maxpos. */
+    int maxpos = 0;
+
+    /**
+     * Instantiates a new LineBreakMeasurer object for the specified text.
+     * 
+     * @param text the AttributedCharacterIterator object which contains
+     * text with at least one character.
+     * @param frc the FontRenderContext represented information
+     * about graphic device.
+     */
+    public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        //???AWT: this(text, BreakIterator.getLineInstance(), frc);
+    }
+
+    /* ???AWT
+    public LineBreakMeasurer(
+            AttributedCharacterIterator text,
+            BreakIterator bi,
+            FontRenderContext frc
+    ) {
+        tm = new TextMeasurer(text, frc);
+        this.bi = bi;
+        this.bi.setText(text);
+        position = text.getBeginIndex();
+        maxpos = tm.aci.getEndIndex();
+    }
+    */
+
+    /**
+     * Deletes a character from the specified position of the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is deleted.
+     */
+    public void deleteChar(AttributedCharacterIterator newText, int pos) {
+        tm.deleteChar(newText, pos);
+        //???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos--;
+    }
+
+    /**
+     * Gets current position of this LineBreakMeasurer.
+     * 
+     * @return current position of this LineBreakMeasurer
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    /**
+     * Insertes a character at the specified position in the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is inserted.
+     */
+    public void insertChar(AttributedCharacterIterator newText, int pos) {
+        tm.insertChar(newText, pos);
+//      ???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos++;
+    }
+
+    /**
+     * Returns the next line of text, updates current position in this 
+     * LineBreakMeasurer.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, null is returned (the entire word at the current 
+     * position does not fit within the wrapping width);  
+     * if false, a valid layout is returned that includes at least the 
+     * character at the current position.
+     * 
+     * @return the next TextLayout which begins at the current position and 
+     * represents the next line of text with width wrappingWidth, null is 
+     * returned if the entire word at the current position does not fit within 
+     * the wrapping width.
+     */
+    public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (position == maxpos) {
+            return null;
+        }
+
+        int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
+
+        if (nextPosition == position) {
+            return null;
+        }
+        TextLayout layout = tm.getLayout(position, nextPosition);
+        position = nextPosition;
+        return layout;
+    }
+
+    /**
+     * Returns the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the next line of text.
+     */
+    public TextLayout nextLayout(float wrappingWidth) {
+        return nextLayout(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the end position of the next line of text.
+     */
+    public int nextOffset(float wrappingWidth) {
+        return nextOffset(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, the current position is returned 
+     * if the entire next word does not fit within wrappingWidth; 
+     * if false, the offset returned is at least one greater than the current
+     * position.
+     * 
+     * @return the end position of the next line of text.
+     * 
+     * @throws IllegalArgumentException if the offsetLimit is less than 
+     * the current position.
+     */
+    public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (offsetLimit <= position) {
+            // awt.203=Offset limit should be greater than current position. 
+            throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
+        }
+
+        if (position == maxpos) {
+            return position;
+        }
+
+        int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
+        int correctedPos = breakPos;
+
+        // This check is required because bi.preceding(maxpos) throws an exception
+        /* ???AWT
+        if (breakPos == maxpos) {
+            correctedPos = maxpos;
+        } else if (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
+            correctedPos = bi.following(breakPos);
+        } else {
+            correctedPos = bi.preceding(breakPos);
+        }
+        */
+        
+        if (position >= correctedPos) {
+            if (requireNextWord) {
+                correctedPos = position;
+            } else {
+                correctedPos = Math.max(position+1, breakPos);
+            }
+        }
+
+        return Math.min(correctedPos, offsetLimit);
+    }
+
+    /**
+     * Sets the new position of this LineBreakMeasurer.
+     * 
+     * @param pos the new position of this LineBreakMeasurer.
+     */
+    public void setPosition(int pos) {
+        if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
+            // awt.33=index is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
+        }
+        position = pos;
+    }
+}
+
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..2857187
--- /dev/null
+++ b/awt/java/awt/font/LineMetrics.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The LineMetrics class provides information such as concerning how the text 
+ * is positioned with respect to the base line, such as ascent, descent, 
+ * and leading.
+ * 
+ */
+public abstract class LineMetrics {
+
+    /**
+     * Gets the baseline offsets of the text according to the 
+     * the baseline of this text.
+     * 
+     * @return the baseline offsets of the text according to the 
+     * the baseline of this text.
+     */
+    public abstract float[] getBaselineOffsets();
+
+    /**
+     * Gets the number of characters of the text.
+     * 
+     * @return the number of characters of the text.
+     */
+    public abstract int getNumChars();
+
+    /**
+     * Gets the baseline index, returns one of the following 
+     * index: ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
+     * 
+     * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE
+     * or HANGING_BASELINE.
+     */
+    public abstract int getBaselineIndex();
+
+    /**
+     * Gets the thickness of the underline.
+     * 
+     * @return the thickness of the underline.
+     */
+    public abstract float getUnderlineThickness();
+
+    /**
+     * Gets the offset of the underline.
+     * 
+     * @return the offset of the underline.
+     */
+    public abstract float getUnderlineOffset();
+
+    /**
+     * Gets the thickness of strike through line.
+     * 
+     * @return the thickness of strike through line.
+     */
+    public abstract float getStrikethroughThickness();
+
+    /**
+     * Gets the offset of the strike through line.
+     * 
+     * @return the offset of the strike through line.
+     */
+    public abstract float getStrikethroughOffset();
+
+    /**
+     * Gets the leading of the text.
+     * 
+     * @return the leading of the text.
+     */
+    public abstract float getLeading();
+
+    /**
+     * Gets the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     * 
+     * @return the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     */
+    public abstract float getHeight();
+
+    /**
+     * Gets the descent of the text.
+     * 
+     * @return the descent of the text.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the ascent of the text.
+     * 
+     * @return the ascent of the text.
+     */
+    public abstract float getAscent();
+
+}
+
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..773bfcf
--- /dev/null
+++ b/awt/java/awt/font/MultipleMaster.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * The MultipleMaster interface provides methods to manipulate MultipleMaster 
+ * type fonts and retrieve graphical and design data from them.
+ */
+public interface MultipleMaster {
+
+    /**
+     * Derives a new multiple master font based on the specified 
+     * parameters.
+     * 
+     * @param glyphWidths float array which represents width of each glyph
+     * in font space.
+     * @param avgStemWidth the average stem width in font space.
+     * @param typicalCapHeight the typical upper case char height.
+     * @param typicalXHeight the typical lower case char height.
+     * @param italicAngle the slope angle for italics.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] glyphWidths, float avgStemWidth,
+            float typicalCapHeight, float typicalXHeight, float italicAngle);
+
+    /**
+     * Derives a new multiple master font based on the design axis values 
+     * contained in the specified array. 
+     * 
+     * @param axes an float array which contains axis values.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] axes);
+
+    /**
+     * Gets default design values for the axes.
+     * 
+     * @return the default design values for the axes.
+     */
+    public float[] getDesignAxisDefaults();
+
+    /**
+     * Gets the array of design axis names. 
+     * 
+     * @return the array of design axis names. 
+     */
+    public String[] getDesignAxisNames();
+
+    /**
+     * Gets the array of design axis ranges. 
+     * 
+     * @return the array of design axis ranges.
+     */
+    public float[] getDesignAxisRanges();
+
+    /**
+     * Gets the number of multiple master design controls. 
+     * 
+     * @return the number of multiple master design controls.
+     */
+    public int getNumDesignAxes();
+
+}
+
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
new file mode 100644
index 0000000..53cb6c0
--- /dev/null
+++ b/awt/java/awt/font/OpenType.java
@@ -0,0 +1,410 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The OpenType interface provides constants and methods for getting 
+ * instance data for fonts of type OpenType and TrueType. For more information,
+ * see the <a href="http://partners.adobe.com/public/developer/opentype/index_spec.html">OpenType specification</a>.
+ */
+public interface OpenType {
+
+    /** 
+     * The Constant TAG_ACNT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_ACNT = 1633906292;
+
+    /** 
+     * The Constant TAG_AVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_AVAR = 1635148146;
+
+    /** 
+     * The Constant TAG_BASE indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BASE = 1111577413;
+
+    /** 
+     * The Constant TAG_BDAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BDAT = 1650745716;
+
+    /** 
+     * The Constant TAG_BLOC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BLOC = 1651273571;
+
+    /** 
+     * The Constant TAG_BSLN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BSLN = 1651731566;
+
+    /** 
+     * The Constant TAG_CFF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CFF = 1128678944;
+
+    /** 
+     * The Constant TAG_CMAP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CMAP = 1668112752;
+
+    /** 
+     * The Constant TAG_CVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVAR = 1668702578;
+
+    /** 
+     * The Constant TAG_CVT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVT = 1668707360;
+
+    /** 
+     * The Constant TAG_DSIG indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_DSIG = 1146308935;
+
+    /** 
+     * The Constant TAG_EBDT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBDT = 1161970772;
+
+    /** 
+     * The Constant TAG_EBLC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBLC = 1161972803;
+
+    /** 
+     * The Constant TAG_EBSC  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBSC = 1161974595;
+
+    /** 
+     * The Constant TAG_FDSC indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_FDSC = 1717859171;
+
+    /** 
+     * The Constant TAG_FEAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FEAT = 1717920116;
+
+    /** 
+     * The Constant TAG_FMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FMTX = 1718449272;
+
+    /** 
+     * The Constant TAG_FPGM indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FPGM = 1718642541;
+
+    /** 
+     * The Constant TAG_FVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FVAR = 1719034226;
+
+    /** 
+     * The Constant TAG_GASP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GASP = 1734439792;
+
+    /** 
+     * The Constant TAG_GDEF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GDEF = 1195656518;
+
+    /** 
+     * The Constant TAG_GLYF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GLYF = 1735162214;
+
+    /** 
+     * The Constant TAG_GPOS indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GPOS = 1196445523;
+
+    /** 
+     * The Constant TAG_GSUB indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GSUB = 1196643650;
+
+    /** 
+     * The Constant TAG_GVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_GVAR = 1735811442;
+
+    /** 
+     * The Constant TAG_HDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HDMX = 1751412088;
+
+    /** 
+     * The Constant TAG_HEAD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HEAD = 1751474532;
+
+    /** 
+     * The Constant TAG_HHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HHEA = 1751672161;
+
+    /** 
+     * The Constant TAG_HMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HMTX = 1752003704;
+
+    /** 
+     * The Constant TAG_JSTF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JSTF = 1246975046;
+
+    /** 
+     * The Constant TAG_JUST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JUST = 1786082164;
+
+    /** 
+     * The Constant TAG_KERN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_KERN = 1801810542;
+
+    /** 
+     * The Constant TAG_LCAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LCAR = 1818452338;
+
+    /** 
+     * The Constant TAG_LOCA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LOCA = 1819239265;
+
+    /** 
+     * The Constant TAG_LTSH indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LTSH = 1280594760;
+
+    /** 
+     * The Constant TAG_MAXP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MAXP = 1835104368;
+
+    /** 
+     * The Constant TAG_MMFX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMFX = 1296909912;
+
+    /** 
+     * The Constant TAG_MMSD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMSD = 1296913220;
+
+    /** 
+     * The Constant TAG_MORT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MORT = 1836020340;
+
+    /** 
+     * The Constant TAG_NAME indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_NAME = 1851878757;
+
+    /** 
+     * The Constant TAG_OPBD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_OPBD = 1836020340;
+
+    /** 
+     * The Constant TAG_OS2 indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_OS2 = 1330851634;
+
+    /** 
+     * The Constant TAG_PCLT  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PCLT = 1346587732;
+
+    /** 
+     * The Constant TAG_POST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_POST = 1886352244;
+
+    /** 
+     * The Constant TAG_PREP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PREP = 1886545264;
+
+    /** 
+     * The Constant TAG_PROP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PROP = 1886547824;
+
+    /** 
+     * The Constant TAG_TRAK indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TRAK = 1953653099;
+
+    /** 
+     * The Constant TAG_TYP1 indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TYP1 = 1954115633;
+
+    /** 
+     * The Constant TAG_VDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VDMX = 1447316824;
+
+    /** 
+     * The Constant TAG_VHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VHEA = 1986553185;
+
+    /** 
+     * The Constant TAG_VMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VMTX = 1986884728;
+
+    /**
+     * Returns the OpenType font version.
+     * 
+     * @return the the OpenType font version.
+     */
+    public int getVersion();
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(int sfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(int sfntTag, int offset, int count);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items.
+     * 
+     * @param strSfntTag the str sfnt tag as a String.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(String strSfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param strSfntTag the sfnt tag as a String.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(String strSfntTag, int offset, int count);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param strSfntTag the sfnt tag as a String.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(String strSfntTag);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(int sfntTag);
+
+}
+
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..45199fd
--- /dev/null
+++ b/awt/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The ShapeGraphicAttribute class provides an opportunity to insert 
+ * shapes to a text.
+ */
+public final class ShapeGraphicAttribute extends GraphicAttribute {
+
+    // shape to render
+    /** The shape. */
+    private Shape fShape;
+    
+    // flag, if the shape should be stroked (true) or filled (false)
+    /** The stroke. */
+    private boolean fStroke;
+
+    // bounds of the shape
+    /** The bounds. */
+    private Rectangle2D fBounds;
+    
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+    
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // width of the shape
+    /** The shape width. */
+    private float fShapeWidth;
+    
+    // height of the shape
+    /** The shape height. */
+    private float fShapeHeight;
+
+    /** 
+     * The Constant STROKE indicates whether the Shape is stroked 
+     * or not. 
+     */
+    public static final boolean STROKE = true;
+
+    /** 
+     * The Constant FILL indicates whether the Shape is filled 
+     * or not. */
+    public static final boolean FILL = false;
+
+    /**
+     * Instantiates a new ShapeGraphicAttribute object for the specified 
+     * Shape.
+     * 
+     * @param shape the shape to be rendered by this 
+     * ShapeGraphicAttribute.
+     * @param alignment the alignment of this ShapeGraphicAttribute.
+     * @param stroke true if the Shape is stroked,
+     *  false if the Shape is filled.
+     */
+    public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
+        super(alignment);
+
+        this.fShape = shape;
+        this.fStroke = stroke;
+
+        this.fBounds  = fShape.getBounds2D();
+
+        this.fOriginX = (float)fBounds.getMinX();
+        this.fOriginY = (float)fBounds.getMinY();
+
+        this.fShapeWidth = (float)fBounds.getWidth();
+        this.fShapeHeight = (float)fBounds.getHeight();
+    }
+
+    /**
+     * Returns a hash code of this ShapeGraphicAttribute object.
+     * 
+     * @return a hash code of this ShapeGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fShape.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * ShapeGraphicAttribute object.
+     * 
+     * @param sga the ShapeGraphicAttribute object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified ShapeGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ShapeGraphicAttribute sga) {
+        if (sga == null) {
+            return false;
+        }
+
+        if (sga == this) {
+            return true;
+        }
+
+        return ( fStroke == sga.fStroke &&
+                getAlignment() == sga.getAlignment() &&
+                fShape.equals(sga.fShape));
+
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ShapeGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+        if (fStroke == STROKE){
+            Stroke oldStroke = g2.getStroke();
+            g2.setStroke(new BasicStroke());
+            g2.draw(at.createTransformedShape(fShape));
+            g2.setStroke(oldStroke);
+        } else {
+            g2.fill(at.createTransformedShape(fShape));
+        }
+
+    }
+
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fShapeWidth + fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, -fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return (Rectangle2D)fBounds.clone();
+    }
+
+    @Override
+    public float getDescent() {
+        return Math.max(0, fShapeHeight + fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..17bbf71
--- /dev/null
+++ b/awt/java/awt/font/TextHitInfo.java
@@ -0,0 +1,216 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The TextHitInfo class provides information about a caret position 
+ * in a text model for insertion or deletion of a character in a text.
+ * The TextHitInfo defines two biases of the character: leading or trailing.
+ * Leading position means the left edge of the specified character 
+ * (TextHitInfo.leading(2) method for "text" returns the left side of "x").
+ * Trailing position means the right edge of the specified character
+ * (TextHitInfo.trailing(2) method for "text" returns the right side of "x").
+ */
+public final class TextHitInfo {
+    
+    /** The char idx. */
+    private int charIdx; // Represents character index in the line
+    
+    /** The is trailing. */
+    private boolean isTrailing;
+
+    /**
+     * Instantiates a new text hit info.
+     * 
+     * @param idx the idx
+     * @param isTrailing the is trailing
+     */
+    private TextHitInfo(int idx, boolean isTrailing) {
+        charIdx = idx;
+        this.isTrailing = isTrailing;
+    }
+
+    /**
+     * To string.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return new String(
+                "TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
+                (isTrailing?"Trailing":"Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        );
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified object is a TextHitInfo object 
+     * with the same data values as this TextHitInfo, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof TextHitInfo) {
+            return equals((TextHitInfo) obj);
+        }
+        return false;
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified TextHitInfo
+     * object.
+     * 
+     * @param thi the TextHitInfo object to be compared.
+     * 
+     * @return true, if this TextHitInfo object has the same data values as the
+     * specified TextHitInfo object, false otherwise.
+     */
+    public boolean equals(TextHitInfo thi) {
+        return
+                thi != null &&
+                thi.charIdx == charIdx &&
+                thi.isTrailing == isTrailing;
+    }
+
+    /**
+     * Gets a TextHitInfo object with its character index 
+     * at the specified offset from the character index of 
+     * this TextHitInfo.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo. 
+     */
+    public TextHitInfo getOffsetHit(int offset) {
+        return new TextHitInfo(charIdx + offset, isTrailing);
+    }
+
+    /**
+     * Gets a TextHitInfo associated with the other side of 
+     * the insertion point. 
+     *  
+     * @return the other hit.
+     */
+    public TextHitInfo getOtherHit() {
+        return isTrailing ?
+                new TextHitInfo(charIdx+1, false) :
+                new TextHitInfo(charIdx-1, true);
+    }
+
+    /**
+     * Returns true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     * 
+     * @return true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     */
+    public boolean isLeadingEdge() {
+        return !isTrailing;
+    }
+
+    /**
+     * Hash code.
+     * 
+     * @return the int
+     */
+    @Override
+    public int hashCode() {
+        return HashCode.combine(charIdx, isTrailing);
+    }
+
+    /**
+     * Gets the insertion index.
+     * 
+     * @return the insertion index: character index if the leading edge
+     * is hit, or character index + 1 if the trailing edge is hit.   
+     */
+    public int getInsertionIndex() {
+        return isTrailing ? charIdx+1 : charIdx;
+    }
+
+    /**
+     * Gets the index of the character hit.
+     * 
+     * @return the character hit's index.
+     */
+    public int getCharIndex() {
+        return charIdx;
+    }
+
+    /**
+     * Returns a TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     */
+    public static TextHitInfo trailing(int charIndex) {
+        return new TextHitInfo(charIndex, true);
+    }
+
+    /**
+     * Returns a TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     */
+    public static TextHitInfo leading(int charIndex) {
+        return new TextHitInfo(charIndex, false);
+    }
+
+    /**
+     * Returns a (trailing) TextHitInfo object associated with the character 
+     * before the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * before the specified offset.
+     */
+    public static TextHitInfo beforeOffset(int offset) {
+        return new TextHitInfo(offset-1, true);
+    }
+
+    /**
+     * Returns a (leading) TextHitInfo object associated with the character 
+     * after the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * after the specified offset.
+     */
+    public static TextHitInfo afterOffset(int offset) {
+        return new TextHitInfo(offset, false);
+    }
+}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..e80afd0
--- /dev/null
+++ b/awt/java/awt/font/TextLayout.java
@@ -0,0 +1,916 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.font.BasicMetrics;
+import org.apache.harmony.awt.gl.font.CaretManager;
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TextLayout class defines the graphical representation of character data.
+ * This class provides method for obtaining information about cursor 
+ * positioning and movement, split cursors for text with different directions, 
+ * logical and visual highlighting, multiple baselines, hits, justification, 
+ * ascent, descent, and advance, and rendering. A TextLayout object can be 
+ * rendered using Graphics context. 
+ */
+public final class TextLayout implements Cloneable {
+
+    /**
+     * The CaretPolicy class provides a policy for obtaining the 
+     * caret location. The single getStrongCaret method specifies 
+     * the policy.
+     */
+    public static class CaretPolicy {
+
+        /**
+         * Instantiates a new CaretPolicy.
+         */
+        public CaretPolicy() {
+            // Nothing to do
+        }
+
+        /**
+         * Returns whichever of the two specified TextHitInfo objects 
+         * has the stronger caret (higher character level) in the 
+         * specified TextLayout.
+         * 
+         * @param hit1 the first TextHitInfo of the specified TextLayout.
+         * @param hit2 the second TextHitInfo of the specified TextLayout.
+         * @param layout the TextLayout.
+         * 
+         * @return the TextHitInfo with the stronger caret.
+         */
+        public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
+            // Stronger hit is the one with greater level.
+            // If the level is same, leading edge is stronger.
+
+            int level1 = layout.getCharacterLevel(hit1.getCharIndex());
+            int level2 = layout.getCharacterLevel(hit2.getCharIndex());
+
+            if (level1 == level2) {
+                return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
+            }
+            return level1 > level2 ? hit1 : hit2;
+        }
+
+    }
+
+    /** 
+     * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
+     */
+    public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+
+    /** The breaker. */
+    private TextRunBreaker breaker;
+    
+    /** The metrics valid. */
+    private boolean metricsValid = false;
+    
+    /** The tmc. */
+    private TextMetricsCalculator tmc;
+    
+    /** The metrics. */
+    private BasicMetrics metrics;
+    
+    /** The caret manager. */
+    private CaretManager caretManager;
+    
+    /** The justification width. */
+    float justificationWidth = -1;
+
+    /**
+     * Instantiates a new TextLayout object from the specified string
+     * and Font.
+     * 
+     * @param string the string to be displayed.
+     * @param font the font of the text.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(String string, Font font, FontRenderContext frc) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (font == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        AttributedString as = new AttributedString(string);
+        as.addAttribute(TextAttribute.FONT, font);
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the specified text and 
+     * a map of attributes.
+     * 
+     * @param string the string to be displayed.
+     * @param attributes the attributes to be used for obtaining the text 
+     * style.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(
+            String string,
+            Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
+            FontRenderContext frc ) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (attributes == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        
+        AttributedString as = new AttributedString(string);
+        as.addAttributes(attributes, 0, string.length());
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the AttributedCharacterIterator.
+     * 
+     * @param text the AttributedCharacterIterator.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
+        if (text == null){
+            // awt.03='{0}' iterator parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (text.getBeginIndex() == text.getEndIndex()){
+            // awt.04='{0}' iterator parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        this.breaker = new TextRunBreaker(text, frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new text layout.
+     * 
+     * @param breaker the breaker
+     */
+    TextLayout(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        caretManager = new CaretManager(this.breaker);
+    }
+
+    /**
+     * Returns a hash code of this TextLayout object.
+     * 
+     * @return a hash code of this TextLayout object.
+     */
+    @Override
+    public int hashCode() {
+        return breaker.hashCode();
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        TextLayout res = new TextLayout((TextRunBreaker) breaker.clone());
+
+        if (justificationWidth >= 0) {
+            res.handleJustify(justificationWidth);
+        }
+
+        return res;
+    }
+
+    /**
+     * Compares this TextLayout object to the specified TextLayout object.
+     * 
+     * @param layout the TextLayout object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified TextLayout object, false otherwise.
+     */
+    public boolean equals(TextLayout layout) {
+        if (layout == null) {
+            return false;
+        }
+        return this.breaker.equals(layout.breaker);
+    }
+
+    /**
+     * Compares this TextLayout object to the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof TextLayout ? equals((TextLayout) obj) : false;
+    }
+
+    /**
+     * Gets the string representation for this TextLayout.
+     * 
+     * @return the string representation for this TextLayout.
+     */
+    @Override
+    public String toString() { // what for?
+        return super.toString();
+    }
+
+    /**
+     * Draws this TextLayout at the specified location with the 
+     * specified Graphics2D context. 
+     * 
+     * @param g2d the Graphics2D object which renders this TextLayout.
+     * @param x the X coordinate of the TextLayout origin. 
+     * @param y the Y coordinate of the TextLayout origin.
+     */
+    public void draw(Graphics2D g2d, float x, float y) {
+        updateMetrics();
+        breaker.drawSegments(g2d, x ,y);
+    }
+
+    /**
+     * Update metrics.
+     */
+    private void updateMetrics() {
+        if (!metricsValid) {
+            breaker.createAllSegments();
+            tmc = new TextMetricsCalculator(breaker);
+            metrics = tmc.createMetrics();
+            metricsValid = true;
+        }
+    }
+
+    /**
+     * Gets the advance of this TextLayout object.
+     * 
+     * @return the advance of this TextLayout object.
+     */
+    public float getAdvance() {
+        updateMetrics();
+        return metrics.getAdvance();
+    }
+
+    /**
+     * Gets the ascent of this TextLayout object.
+     * 
+     * @return the ascent of this TextLayout object.
+     */
+    public float getAscent() {
+        updateMetrics();
+        return metrics.getAscent();
+    }
+
+    /**
+     * Gets the baseline of this TextLayout object.
+     * 
+     * @return the baseline of this TextLayout object.
+     */
+    public byte getBaseline() {
+        updateMetrics();
+        return (byte) metrics.getBaseLineIndex();
+    }
+
+    /**
+     * Gets the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     * 
+     * @return the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     */
+    public float[] getBaselineOffsets() {
+        updateMetrics();
+        return tmc.getBaselineOffsets();
+    }
+
+    /**
+     * Gets the black box bounds of the characters in the specified area. 
+     * The black box bounds is an Shape which contains all 
+     * bounding boxes of all the glyphs of the characters 
+     * between firstEndpoint and secondEndpoint parameters values.     
+     *  
+     * @param firstEndpoint the first point of the area.
+     * @param secondEndpoint the second point of the area.
+     * 
+     * @return the Shape which contains black box bounds.
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        if (firstEndpoint < secondEndpoint) {
+            return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+        }
+        return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
+    }
+
+    /**
+     * Gets the bounds of this TextLayout.
+     * 
+     * @return the bounds of this TextLayout.
+     */
+    public Rectangle2D getBounds() {
+        updateMetrics();
+        return breaker.getVisualBounds();
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the information about the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo
+     * of a character in this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo of a character in this TextLayout.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * default caret policy and null bounds: the first element 
+     * is the strong caret, the second is the weak caret or null. 
+     * 
+     * @param offset an offset in the TextLayout.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset) {
+        return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * the default caret policy: the first element is the strong 
+     * caret, the second is the weak caret or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
+        return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets: the first
+     * element is the strong caret, the second is the weak caret 
+     * or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * @param policy the specified CaretPolicy.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        updateMetrics();
+        return caretManager.getCaretShapes(offset, bounds, policy, this);
+    }
+
+    /**
+     * Gets the number of characters in this TextLayout.
+     * 
+     * @return the number of characters in this TextLayout.
+     */
+    public int getCharacterCount() {
+        return breaker.getCharCount();
+    }
+
+    /**
+     * Gets the level of the character with the specified index. 
+     *  
+     * @param index the specified index of the character.
+     * 
+     * @return the level of the character.
+     */
+    public byte getCharacterLevel(int index) {
+        if (index == -1 || index == getCharacterCount()) {
+            return (byte) breaker.getBaseLevel();
+        }
+        return breaker.getLevel(index);
+    }
+
+    /**
+     * Gets the descent of this TextLayout.
+     * 
+     * @return the descent of this TextLayout.
+     */
+    public float getDescent() {
+        updateMetrics();
+        return metrics.getDescent();
+    }
+
+    /**
+     * Gets the TextLayout wich is justified with the specified
+     * width related to this TextLayout.
+     * 
+     * @param justificationWidth the width which is used 
+     * for justification.
+     * 
+     * @return a TextLayout justified to the specified width.
+     * 
+     * @throws Error the error occures if this TextLayout has been
+     * already justified.
+     */
+    public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return this;
+        }
+
+        TextLayout justifiedLayout = new TextLayout((TextRunBreaker) breaker.clone());
+        justifiedLayout.handleJustify(justificationWidth);
+        return justifiedLayout;
+    }
+
+    /**
+     * Gets the leading of this TextLayout.
+     * 
+     * @return the leading of this TextLayout.
+     */
+    public float getLeading() {
+        updateMetrics();
+        return metrics.getLeading();
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the natural 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the specified 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * @param bounds the specified bounds of this TextLayout.
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(
+            int firstEndpoint,
+            int secondEndpoint,
+            Rectangle2D bounds
+    ) {
+        updateMetrics();
+
+        if (firstEndpoint > secondEndpoint) {
+            if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
+                // awt.197=Endpoints are out of range
+                throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+            }
+            return caretManager.getLogicalHighlightShape(
+                    secondEndpoint,
+                    firstEndpoint,
+                    bounds,
+                    this
+            );
+        }
+        if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
+            // awt.197=Endpoints are out of range
+            throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+        }
+        return caretManager.getLogicalHighlightShape(
+                firstEndpoint,
+                secondEndpoint,
+                bounds,
+                this
+        );
+    }
+
+    /**
+     * Gets the logical ranges of text which corresponds to a visual 
+     * selection.
+     * 
+     * @param hit1 the first endpoint of the visual range.
+     * @param hit2 the second endpoint of the visual range.
+     * 
+     * @return the logical ranges of text which corresponds to a visual 
+     * selection.
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset) {
+        return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextLeftHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the left of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
+
+        if (nextLeftHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextRightHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset) {
+        return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextRightHit = getNextRightHit(strongHit);
+
+        if (nextRightHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the outline of this TextLayout as a Shape.
+     * 
+     * @param xform the AffineTransform to be used to transform 
+     * the outline before returning it, or null if no transformation
+     * is desired.
+     * 
+     * @return the outline of this TextLayout as a Shape.
+     */
+    public Shape getOutline(AffineTransform xform) {
+        breaker.createAllSegments();
+
+        GeneralPath outline = breaker.getOutline();
+
+        if (outline != null && xform != null) {
+            outline.transform(xform);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Gets the visible advance of this TextLayout which is defined as
+     * diffence between leading (advance) and trailing whitespace.
+     * 
+     * @return the visible advance of this TextLayout.
+     */
+    public float getVisibleAdvance() {
+        updateMetrics();
+
+        // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
+        // base direction, so it is also trailing
+        // in logical representation. We use this fact.
+        int lastNonWhitespace = breaker.getLastNonWhitespace();
+
+        if (lastNonWhitespace < 0) {
+            return 0;
+        } else if (lastNonWhitespace == getCharacterCount()-1) {
+            return getAdvance();
+        } else if (justificationWidth >= 0) { // Layout is justified
+            return justificationWidth;
+        } else {
+            breaker.pushSegments(
+                    breaker.getACI().getBeginIndex(),
+                    lastNonWhitespace + breaker.getACI().getBeginIndex() + 1
+            );
+
+            breaker.createAllSegments();
+
+            float visAdvance = tmc.createMetrics().getAdvance();
+
+            breaker.popSegments();
+            return visAdvance;
+        }
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text and extends to the bounds.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * @param bounds the rectangle that the highlighted area should be 
+     * extended or restricted to.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
+        return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
+        breaker.createAllSegments();
+        return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
+    }
+
+    /**
+     * Gets the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     * 
+     * @param hitInfo the specified TextHitInfo.
+     * 
+     * @return the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        return caretManager.getVisualOtherHit(hitInfo);
+    }
+
+    /**
+     * Justifies the text; this method should be overridden
+     * by subclasses.
+     * 
+     * @param justificationWidth the width for justification.
+     */
+    protected void handleJustify(float justificationWidth) {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return;
+        }
+
+        float gap = (justificationWidth - getVisibleAdvance()) * justification;
+        breaker.justify(gap);
+        this.justificationWidth = justificationWidth;
+
+        // Correct metrics
+        tmc = new TextMetricsCalculator(breaker);
+        tmc.correctAdvance(metrics);
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y) {
+        return hitTestChar(x, y, getBounds());
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates within 
+     * the specified text rectangle.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * @param bounds the bounds of the text area.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
+        if (x > bounds.getMaxX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo.leading(0);
+        }
+
+        if (x < bounds.getMinX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.leading(0) : TextHitInfo.trailing(breaker.getCharCount() - 1);
+        }
+
+        return breaker.hitTest(x, y);
+    }
+
+    /**
+     * Returns true if this TextLayout has a "left to right" 
+     * direction.
+     * 
+     * @return true if this TextLayout has a "left to right" 
+     * direction, false if this TextLayout has a "right to left" 
+     * direction. 
+     */
+    public boolean isLeftToRight() {
+        return breaker.isLTR();
+    }
+
+    /**
+     * Returns true if this TextLayout is vertical, false otherwise.
+     * 
+     * @return true if this TextLayout is vertical, false if horizontal.
+     */
+    public boolean isVertical() {
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..017f3d9
--- /dev/null
+++ b/awt/java/awt/font/TextMeasurer.java
@@ -0,0 +1,167 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/*
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+
+/**
+ * The TextMeasurer class provides utilities for line break operations.
+ */
+public final class TextMeasurer implements Cloneable {
+    
+    /** The aci. */
+    AttributedCharacterIterator aci;
+    
+    /** The frc. */
+    FontRenderContext frc;
+    
+    /** The breaker. */
+    TextRunBreaker breaker = null;
+    
+    /** The tmc. */
+    TextMetricsCalculator tmc = null;
+
+    /**
+     * Instantiates a new text measurer from the specified text.
+     * 
+     * @param text the source text.
+     * @param frc the FontRenderContext.
+     */
+    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        this.aci = text;
+        this.frc = frc;
+        breaker = new TextRunBreaker(aci, this.frc);
+        tmc = new TextMetricsCalculator(breaker);
+    }
+
+    /**
+     * Replaces the current text with the new text, inserting a break
+     * character at the specified insert position.  
+     * 
+     * @param newParagraph the new paragraph text. 
+     * @param insertPos the position in the text where the character is inserted. 
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.insertChar(newParagraph, insertPos);
+        }
+    }
+
+    /**
+     * Replaces the current text with the new text and deletes a
+     * character at the specified position.  
+     * 
+     * @param newParagraph the paragraph text after deletion. 
+     * @param deletePos the position in the text where the character is removed. 
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.deleteChar(newParagraph, deletePos);
+        }
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        return new TextMeasurer((AttributedCharacterIterator) aci.clone(), frc);
+    }
+
+    /**
+     * Returns a TextLayout of the specified character range.
+     * 
+     * @param start the index of the first character.
+     * @param limit the index after the last character. 
+     * 
+     * @return a TextLayout for the characters beginning at "start" up 
+     * to "end".
+     */
+    public TextLayout getLayout(int start, int limit) {
+        breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        TextLayout layout = new TextLayout((TextRunBreaker) breaker.clone());
+
+        breaker.popSegments();
+        return layout;
+    }
+
+    /**
+     * Returns the graphical width of a line beginning at "start" 
+     * parameter and including characters up to "end" parameter. 
+     * "start" and "end" are absolute indices, not relative to the 
+     * "start" of the paragraph.
+     * 
+     * @param start the character index at which to start measuring.
+     * @param end the character index at which to stop measuring.
+     * 
+     * @return the graphical width of a line beginning at "start"  
+     * and including characters up to "end".
+     */
+    public float getAdvanceBetween(int start, int end) {
+        breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        float retval = tmc.createMetrics().getAdvance();
+
+        breaker.popSegments();
+        return retval;
+    }
+
+    /**
+     * Returns the index of the first character which is not fit on 
+     * a line beginning at start and possible measuring up to maxAdvance 
+     * in graphical width.
+     * 
+     * @param start he character index at which to start measuring. 
+     * @param maxAdvance the graphical width in which the line must fit. 
+     * 
+     * @return the index after the last character that is fit on a line 
+     * beginning at start, which is not longer than maxAdvance in graphical
+     * width.
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        breaker.createAllSegments();
+        return breaker.getLineBreakIndex(
+                start - aci.getBeginIndex(), maxAdvance) + aci.getBeginIndex();
+    }
+}
+
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..7c9b0bd
--- /dev/null
+++ b/awt/java/awt/font/TransformAttribute.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TransformAttribute class is a wrapper for the AffineTransform class in
+ * order to use it as attribute.
+ */
+public final class TransformAttribute implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3356247357827709530L;
+
+    // affine transform of this TransformAttribute instance
+    /** The transform. */
+    private AffineTransform fTransform;
+
+    /**
+     * Instantiates a new TransformAttribute from the specified
+     * AffineTransform.
+     * 
+     * @param transform the AffineTransform to be wrapped.
+     */
+    public TransformAttribute(AffineTransform transform) {
+        if (transform == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        if (!transform.isIdentity()){
+            this.fTransform = new AffineTransform(transform);
+        }
+    }
+
+    /**
+     * Gets the initial AffineTransform which is wrapped.
+     * 
+     * @return the initial AffineTransform which is wrapped.
+     */
+    public AffineTransform getTransform() {
+        if (fTransform != null){
+            return new AffineTransform(fTransform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Checks if this transform is an identity transform.
+     * 
+     * @return true, if this transform is an identity transform,
+     * false otherwise.
+     */
+    public boolean isIdentity() {
+        return (fTransform == null);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
new file mode 100644
index 0000000..5fd3934
--- /dev/null
+++ b/awt/java/awt/geom/AffineTransform.java
@@ -0,0 +1,1158 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Shape;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class AffineTransform represents a linear transformation 
+ * (rotation, scaling, or shear) followed by a translation that 
+ * acts on a coordinate space. It preserves colinearity of points 
+ * and ratios of distances between collinear points: so if A, B, 
+ * and C are on a line, then after the space has been transformed 
+ * via the affine transform, the images of the three points will 
+ * still be on a line, and the ratio of the distance from A to B
+ * with the distance from B to C will be the same as the corresponding
+ * ratio in the image space.
+ */
+public class AffineTransform implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1330973210523860834L;
+
+    /** The Constant TYPE_IDENTITY. */
+    public static final int TYPE_IDENTITY = 0;
+    
+    /** The Constant TYPE_TRANSLATION. */
+    public static final int TYPE_TRANSLATION = 1;
+    
+    /** The Constant TYPE_UNIFORM_SCALE. */
+    public static final int TYPE_UNIFORM_SCALE = 2;
+    
+    /** The Constant TYPE_GENERAL_SCALE. */
+    public static final int TYPE_GENERAL_SCALE = 4;
+    
+    /** The Constant TYPE_QUADRANT_ROTATION. */
+    public static final int TYPE_QUADRANT_ROTATION = 8;
+    
+    /** The Constant TYPE_GENERAL_ROTATION. */
+    public static final int TYPE_GENERAL_ROTATION = 16;
+    
+    /** The Constant TYPE_GENERAL_TRANSFORM. */
+    public static final int TYPE_GENERAL_TRANSFORM = 32;
+    
+    /** The Constant TYPE_FLIP. */
+    public static final int TYPE_FLIP = 64;
+    
+    /** The Constant TYPE_MASK_SCALE. */
+    public static final int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
+    
+    /** The Constant TYPE_MASK_ROTATION. */
+    public static final int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
+
+    /** The <code>TYPE_UNKNOWN</code> is an initial type value. */
+    static final int TYPE_UNKNOWN = -1;
+    
+    /** The min value equivalent to zero. If absolute value less then ZERO it considered as zero. */
+    static final double ZERO = 1E-10;
+   
+    /** The values of transformation matrix. */
+    double m00;
+    
+    /** The m10. */
+    double m10;
+    
+    /** The m01. */
+    double m01;
+    
+    /** The m11. */
+    double m11;
+    
+    /** The m02. */
+    double m02;
+    
+    /** The m12. */
+    double m12;
+
+    /** The transformation <code>type</code>. */
+    transient int type;
+
+    /**
+     * Instantiates a new affine transform of type <code>TYPE_IDENTITY</code>
+     * (which leaves coordinates unchanged).
+     */
+    public AffineTransform() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Instantiates a new affine transform that has the same data as
+     * the given AffineTransform.
+     * 
+     * @param t the transform to copy.
+     */
+    public AffineTransform(AffineTransform t) {
+        this.type = t.type;
+        this.m00 = t.m00;
+        this.m10 = t.m10;
+        this.m01 = t.m01;
+        this.m11 = t.m11;
+        this.m02 = t.m02;
+        this.m12 = t.m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as floats. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as doubles. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of floats. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six floats giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(float[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of doubles. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six doubles giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(double[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+
+    /**
+     * Returns type of the affine transformation.
+     * <p>
+     * The type is computed as follows: Label the entries of the 
+     * transformation matrix as three rows (m00, m01), (m10, m11), and
+     * (m02, m12). Then if the original basis vectors are (1, 0) and (0, 1), 
+     * the new basis vectors after transformation are given by (m00, m01) 
+     * and (m10, m11), and the translation vector is (m02, m12).
+     * <p>
+     * The types are classified as follows: <br/> 
+     *   TYPE_IDENTITY - no change<br/>
+     *   TYPE_TRANSLATION - The translation vector isn't zero<br/>
+     *   TYPE_UNIFORM_SCALE - The new basis vectors have equal length<br/>
+     *   TYPE_GENERAL_SCALE - The new basis vectors dont' have equal length<br/>
+     *   TYPE_FLIP - The new basis vector orientation differs from the original one<br/>
+     *   TYPE_QUADRANT_ROTATION - The new basis is a rotation of the original by 90, 180, 270, or 360 degrees<br/>   
+     *   TYPE_GENERAL_ROTATION - The new basis is a rotation of the original by an arbitrary angle<br/>
+     *   TYPE_GENERAL_TRANSFORM - The transformation can't be inverted.<br/>
+     *   <p>
+     * Note that multiple types are possible, thus the types can be combined 
+     * using bitwise combinations.
+     * 
+     * @return the type of the Affine Transform.
+     */
+    public int getType() {
+        if (type != TYPE_UNKNOWN) {
+            return type;
+        }
+
+        int type = 0;
+
+        if (m00 * m01 + m10 * m11 != 0.0) {
+            type |= TYPE_GENERAL_TRANSFORM;
+            return type;
+        }
+
+        if (m02 != 0.0 || m12 != 0.0) {
+            type |= TYPE_TRANSLATION;
+        } else
+            if (m00 == 1.0 && m11 == 1.0 && m01 == 0.0 && m10 == 0.0) {
+                type = TYPE_IDENTITY;
+                return type;
+            }
+
+        if (m00 * m11 - m01 * m10 < 0.0) {
+            type |= TYPE_FLIP;
+        }
+
+        double dx = m00 * m00 + m10 * m10;
+        double dy = m01 * m01 + m11 * m11;
+        if (dx != dy) {
+            type |= TYPE_GENERAL_SCALE;
+        } else
+            if (dx != 1.0) {
+                type |= TYPE_UNIFORM_SCALE;
+            }
+
+        if ((m00 == 0.0 && m11 == 0.0) ||
+            (m10 == 0.0 && m01 == 0.0 && (m00 < 0.0 || m11 < 0.0)))
+        {
+            type |= TYPE_QUADRANT_ROTATION;
+        } else
+            if (m01 != 0.0 || m10 != 0.0) {
+                type |= TYPE_GENERAL_ROTATION;
+            }
+
+        return type;
+    }
+
+    /**
+     * Gets the scale x entry of the transformation matrix
+     * (the upper left matrix entry).
+     * 
+     * @return the scale x value.
+     */
+    public double getScaleX() {
+        return m00;
+    }
+
+    /**
+     * Gets the scale y entry of the transformation matrix
+     * (the lower right entry of the linear transformation).
+     * 
+     * @return the scale y value.
+     */
+    public double getScaleY() {
+        return m11;
+    }
+
+    /**
+     * Gets the shear x entry of the transformation matrix
+     * (the upper right entry of the linear transformation).
+     * 
+     * @return the shear x value.
+     */
+    public double getShearX() {
+        return m01;
+    }
+
+    /**
+     * Gets the shear y entry of the transformation matrix
+     * (the lower left entry of the linear transformation).
+     * 
+     * @return the shear y value.
+     */
+    public double getShearY() {
+        return m10;
+    }
+
+    /**
+     * Gets the x coordinate of the translation vector.
+     * 
+     * @return the x coordinate of the translation vector.
+     */
+    public double getTranslateX() {
+        return m02;
+    }
+
+    /**
+     * Gets the y coordinate of the translation vector.
+     * 
+     * @return the y coordinate of the translation vector.
+     */
+    public double getTranslateY() {
+        return m12;
+    }
+
+    /**
+     * Checks if the AffineTransformation is the identity.
+     * 
+     * @return true, if the AffineTransformation is the identity.
+     */
+    public boolean isIdentity() {
+        return getType() == TYPE_IDENTITY;
+    }
+
+    /**
+     * Writes the values of the transformation matrix into the given 
+     * array of doubles. If the array has length 4, only the linear
+     * transformation part will be written into it. If it has length 
+     * greater than 4, the translation vector will be included as well.
+     * 
+     * @param matrix the array to fill with the values of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public void getMatrix(double[] matrix) {
+        matrix[0] = m00;
+        matrix[1] = m10;
+        matrix[2] = m01;
+        matrix[3] = m11;
+        if (matrix.length > 4) {
+            matrix[4] = m02;
+            matrix[5] = m12;
+        }
+    }
+
+    /**
+     * Gets the determinant of the linear transformation matrix.
+     * 
+     * @return the determinant of the linear transformation matrix.
+     */
+    public double getDeterminant() {
+        return m00 * m11 - m01 * m10;
+    }
+
+    /**
+     * Sets the transform in terms of a list of double values.
+     * 
+     * @param m00 the m00 coordinate of the transformation matrix.
+     * @param m10 the m10 coordinate of the transformation matrix.
+     * @param m01 the m01 coordinate of the transformation matrix.
+     * @param m11 the m11 coordinate of the transformation matrix.
+     * @param m02 the m02 coordinate of the transformation matrix.
+     * @param m12 the m12 coordinate of the transformation matrix.
+     */
+    public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Sets the transform's data to match the data of the transform 
+     * sent as a parameter.
+     * 
+     * @param t the transform that gives the new values.
+     */
+    public void setTransform(AffineTransform t) {
+        type = t.type;
+        setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12);
+    }
+
+    /**
+     * Sets the transform to the identity transform.
+     */
+    public void setToIdentity() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Sets the transformation to a translation alone.
+     * Sets the linear part of the transformation to identity 
+     * and the translation vector to the values sent as parameters.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void setToTranslation(double mx, double my) {
+        m00 = m11 = 1.0;
+        m01 = m10 = 0.0;
+        m02 = mx;
+        m12 = my;
+        if (mx == 0.0 && my == 0.0) {
+            type = TYPE_IDENTITY;
+        } else {
+            type = TYPE_TRANSLATION;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a scale alone, eliminating 
+     * rotation, shear, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void setToScale(double scx, double scy) {
+        m00 = scx;
+        m11 = scy;
+        m10 = m01 = m02 = m12 = 0.0;
+        if (scx != 1.0 || scy != 1.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a shear alone, eliminating 
+     * rotation, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void setToShear(double shx, double shy) {
+        m00 = m11 = 1.0;
+        m02 = m12 = 0.0;
+        m01 = shx;
+        m10 = shy;
+        if (shx != 0.0 || shy != 0.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a rotation alone, eliminating 
+     * shearing, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void setToRotation(double angle) {
+        double sin = Math.sin(angle);
+        double cos = Math.cos(angle);
+        if (Math.abs(cos) < ZERO) {
+            cos = 0.0;
+            sin = sin > 0.0 ? 1.0 : -1.0;
+        } else
+            if (Math.abs(sin) < ZERO) {
+                sin = 0.0;
+                cos = cos > 0.0 ? 1.0 : -1.0;
+            }
+        m00 = m11 = cos;
+        m01 = -sin;
+        m10 = sin;
+        m02 = m12 = 0.0;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Sets the transformation to being a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void setToRotation(double angle, double px, double py) {
+        setToRotation(angle);
+        m02 = px * (1.0 - m00) + py * m10;
+        m12 = py * (1.0 - m00) - px * m10;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a translation alone
+     * with the translation vector given by the values sent as parameters.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getTranslateInstance(double mx, double my) {
+        AffineTransform t = new AffineTransform();
+        t.setToTranslation(mx, my);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a scale alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scY the scaling factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getScaleInstance(double scx, double scY) {
+        AffineTransform t = new AffineTransform();
+        t.setToScale(scx, scY);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a shear alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getShearInstance(double shx, double shy) {
+        AffineTransform m = new AffineTransform();
+        m.setToShear(shx, shy);
+        return m;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param x the distance to translate in the x direction.
+     * @param y the distance to translate in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle, double x, double y) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle, x, y);
+        return t;
+    }
+
+    /**
+     * Applies a translation to this AffineTransformation.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void translate(double mx, double my) {
+        concatenate(AffineTransform.getTranslateInstance(mx, my));
+    }
+
+    /**
+     * Applies a scaling transformation to this AffineTransformation.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void scale(double scx, double scy) {
+        concatenate(AffineTransform.getScaleInstance(scx, scy));
+    }
+
+    /**
+     * Applies a shearing transformation to this AffineTransformation.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void shear(double shx, double shy) {
+        concatenate(AffineTransform.getShearInstance(shx, shy));
+    }
+
+    /**
+     * Applies a rotation transformation to this AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void rotate(double angle) {
+        concatenate(AffineTransform.getRotateInstance(angle));
+    }
+
+    /**
+     * Applies a rotation and translation transformation to this 
+     * AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void rotate(double angle, double px, double py) {
+        concatenate(AffineTransform.getRotateInstance(angle, px, py));
+    }
+
+    /**
+     * Multiplies the matrix representations of two AffineTransform objects.
+     * 
+     * @param t1 - the AffineTransform object is a multiplicand
+     * @param t2 - the AffineTransform object is a multiplier
+     * 
+     * @return an AffineTransform object that is the result of t1 multiplied by the matrix t2.
+     */
+    AffineTransform multiply(AffineTransform t1, AffineTransform t2) {
+        return new AffineTransform(
+                t1.m00 * t2.m00 + t1.m10 * t2.m01,          // m00
+                t1.m00 * t2.m10 + t1.m10 * t2.m11,          // m01
+                t1.m01 * t2.m00 + t1.m11 * t2.m01,          // m10
+                t1.m01 * t2.m10 + t1.m11 * t2.m11,          // m11
+                t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02
+                t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12
+    }
+
+    /**
+     * Applies the given AffineTransform to this AffineTransform
+     * via matrix multiplication.
+     * 
+     * @param t the AffineTransform to apply to this AffineTransform.
+     */
+    public void concatenate(AffineTransform t) {
+        setTransform(multiply(t, this));
+    }
+
+    /**
+     * Changes the current AffineTransform the one obtained by 
+     * taking the transform t and applying this AffineTransform to it.
+     * 
+     * @param t the AffineTransform that this AffineTransform is multiplied by.
+     */
+    public void preConcatenate(AffineTransform t) {
+        setTransform(multiply(this, t));
+    }
+
+    /**
+     * Creates an AffineTransform that is the inverse of this transform.
+     * 
+     * @return the affine transform that is the inverse of this AffineTransform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public AffineTransform createInverse() throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+        return new AffineTransform(
+                 m11 / det, // m00
+                -m10 / det, // m10
+                -m01 / det, // m01
+                 m00 / det, // m11
+                (m01 * m12 - m11 * m02) / det, // m02
+                (m10 * m02 - m00 * m12) / det  // m12
+        );
+    }
+
+    /**
+     * Apply the current AffineTransform to the point.
+     * 
+     * @param src the original point.
+     * @param dst Point2D object to be filled with the destination
+     * coordinates (where the original point is sent by this AffineTransform). May be null.
+     * 
+     * @return the point in the AffineTransform's image space where the
+     * original point is sent.
+     */
+    public Point2D transform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+        return dst;
+    }
+
+    /**
+     * Applies this AffineTransform to an array of points.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length > src.length</code> or
+     * <code>dstOff + length > dst.length</code>.
+     */
+    public void transform(Point2D[] src, int srcOff, Point2D[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            Point2D srcPoint = src[srcOff++]; 
+            double x = srcPoint.getX();
+            double y = srcPoint.getY();
+            Point2D dstPoint = dst[dstOff]; 
+            if (dstPoint == null) {
+                if (srcPoint instanceof Point2D.Double) {
+                    dstPoint = new Point2D.Double();
+                } else {
+                    dstPoint = new Point2D.Float();
+                }
+            }
+            dstPoint.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+            dst[dstOff++] = dstPoint;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+     public void transform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            double x = src[srcOff + 0];
+            double y = src[srcOff + 1];
+            dst[dstOff + 0] = x * m00 + y * m01 + m02;
+            dst[dstOff + 1] = x * m10 + y * m11 + m12;
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            float x = src[srcOff + 0];
+            float y = src[srcOff + 1];
+            dst[dstOff + 0] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff + 1] = (float)(x * m10 + y * m11 + m12);
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>double</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            float x = src[srcOff++];
+            float y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01 + m02;
+            dst[dstOff++] = x * m10 + y * m11 + m12;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>float</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(double[] src, int srcOff, float[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff++] = (float)(x * m10 + y * m11 + m12);
+        }
+    }
+
+    /**
+     * Transforms the point according to the linear transformation
+     * part of this AffineTransformation (without applying the translation).
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the delta transform
+     * is written.
+     * 
+     * @return the result of applying the delta transform (linear part 
+     * only) to the original point.
+     */
+    // TODO: is this right? if dst is null, we check what it's an
+    // instance of? Shouldn't it be src instanceof Point2D.Double?
+    public Point2D deltaTransform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (dst instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
+        return dst;
+    }
+
+    /**
+     * Applies the linear transformation part of this AffineTransform 
+     * (ignoring the translation part) to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the delta transformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void deltaTransform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01;
+            dst[dstOff++] = x * m10 + y * m11;
+        }
+    }
+
+    /**
+     * Transforms the point according to the inverse of this AffineTransformation.
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the inverse transform
+     * is written (may be null).
+     * 
+     * @return the result of applying the inverse transform.
+     * Inverse transform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public Point2D inverseTransform(Point2D src, Point2D dst) throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX() - m02;
+        double y = src.getY() - m12;
+
+        dst.setLocation((x * m11 - y * m01) / det, (y * m00 - x * m10) / det);
+        return dst;
+    }
+
+    /**
+     * Applies the inverse of this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the inverse of the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public void inverseTransform(double[] src, int srcOff, double[] dst, int dstOff, int length)
+        throws NoninvertibleTransformException
+    {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        while (--length >= 0) {
+            double x = src[srcOff++] - m02;
+            double y = src[srcOff++] - m12;
+            dst[dstOff++] = (x * m11 - y * m01) / det;
+            dst[dstOff++] = (y * m00 - x * m10) / det;
+        }
+    }
+
+    /**
+     * Creates a new shape whose data is given by applying this 
+     * AffineTransform to the specified shape.
+     * 
+     * @param src the original shape whose data is to be transformed.
+     * 
+     * @return the new shape found by applying this AffineTransform to 
+     * the original shape.
+     */
+    public Shape createTransformedShape(Shape src) {
+        if (src == null) {
+            return null;
+        }
+        if (src instanceof GeneralPath) {
+            return ((GeneralPath)src).createTransformedShape(this);
+        }
+        PathIterator path = src.getPathIterator(this);
+        GeneralPath dst = new GeneralPath(path.getWindingRule());
+        dst.append(path, false);
+        return dst;
+    }
+
+    @Override
+    public String toString() {
+        return
+            getClass().getName() +
+            "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                + m10 + ", " + m11 + ", " + m12 + "]]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(m00);
+        hash.append(m01);
+        hash.append(m02);
+        hash.append(m10);
+        hash.append(m11);
+        hash.append(m12);
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof AffineTransform) {
+            AffineTransform t = (AffineTransform)obj;
+            return
+                m00 == t.m00 && m01 == t.m01 &&
+                m02 == t.m02 && m10 == t.m10 &&
+                m11 == t.m11 && m12 == t.m12;
+        }
+        return false;
+    }
+
+    
+    /**
+     * Writes the AffineTrassform object to the output steam.
+     * 
+     * @param stream - the output stream
+     * 
+     * @throws IOException - if there are I/O errors while writing to the output strem
+     */
+    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+    }
+
+    
+    /**
+     * Read the AffineTransform object from the input stream.
+     * 
+     * @param stream - the input steam
+     * 
+     * @throws IOException - if there are I/O errors while reading from the input strem
+     * @throws ClassNotFoundException - if class could not be found
+     */
+    private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        type = TYPE_UNKNOWN;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Arc2D.java b/awt/java/awt/geom/Arc2D.java
new file mode 100644
index 0000000..bc1e95c
--- /dev/null
+++ b/awt/java/awt/geom/Arc2D.java
@@ -0,0 +1,1028 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Arc2D represents a segment of a curve inscribed 
+ * in a rectangle. The curve is defined by a start angle and an 
+ * extent angle (the end angle minus the start angle) as 
+ * a pie wedge whose point is in the center of the rectangle.
+ * The Arc2D as a shape may be either OPEN (including nothing 
+ * but the curved arc segment itself), CHORD (the curved arc
+ * segment closed by a connecting segment from the end to the 
+ * beginning of the arc, or PIE (the segments from the end 
+ * of the arc to the center of the rectangle and from the
+ * center of the rectangle back to the arc's start point are 
+ * included).
+ */
+public abstract class Arc2D extends RectangularShape {
+
+    /** The arc type OPEN indicates that the shape includes only the 
+     * curved arc segment. */
+    public final static int OPEN = 0;
+    
+    /** The arc type CHORD indicates that as a shape the connecting
+     * segment from the end point of the curved arc to the beginning
+     * point is included. */
+    public final static int CHORD = 1;
+    
+    /** The arc type PIE indicates that as a shape the two segments 
+     * from the arc's endpoint to the center of the rectangle and from 
+     * the center of the rectangle to the arc's endpoint are included. */
+    public final static int PIE = 2;
+
+    /**
+     * The Class Float is a subclass of Arc2D in which all of the 
+     * data values are given as floats.
+     * @see Arc2D.Double
+     */
+    public static class Float extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public float width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public float height;
+        
+        /** The start angle of the arc in degrees. */
+        public float start;
+        
+        /** The width angle of the arc in degrees. */
+        public float extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with float values.
+         */
+        public Float() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with float values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified float-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(float x, float y, float width, float height, float start, float extent, int type) {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(Rectangle2D bounds, float start, float extent, int type) {
+            super(type);
+            this.x = (float)bounds.getX();
+            this.y = (float)bounds.getY();
+            this.width = (float)bounds.getWidth();
+            this.height = (float)bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+       @Override
+       public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.start = (float)start;
+            this.extent = (float)extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = (float)start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = (float)extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Float((float)x, (float)y, (float)width, (float)height);
+        }
+
+    }
+
+    /**
+     * The Class Double is a subclass of Arc2D in which all of the 
+     * data values are given as doubles.
+     * @see Arc2D.Float
+     */
+    public static class Double extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public double width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public double height;
+        
+        /** The start angle of the arc in degrees. */
+        public double start;
+        
+        /** The width angle of the arc in degrees. */
+        public double extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with double values.
+         */
+        public Double() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with double values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified double-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(Rectangle2D bounds, double start, double extent, int type) {
+            super(type);
+            this.x = bounds.getX();
+            this.y = bounds.getY();
+            this.width = bounds.getWidth();
+            this.height = bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * The Class Iterator is the subclass of PathIterator that is used to 
+     * traverse the boundary of a shape of type Arc2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the center of the arc's bounding rectangle. */
+        double x;
+
+        /** The y coordinate of the center of the arc's bounding rectangle. */
+        double y;
+
+        /** Half of the width of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double width;
+        
+        /** Half of the height of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double height;
+        
+        /** The start angle of the arc in degrees. */
+        double angle;
+        
+        /** The angle extent in degrees. */
+        double extent;
+         
+        /** The closure type of the arc. */
+        int type;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /** The number of arc segments the source arc subdivided to be approximated by Bezier curves. Depends on extent value. */
+        int arcCount;
+        
+        /** The number of line segments. Depends on closure type. */
+        int lineCount;
+        
+        /** The step to calculate next arc subdivision point. */
+        double step;
+        
+        /** The temporary value of cosinus of the current angle. */
+        double cos;
+
+        /** The temporary value of sinus of the current angle. */
+        double sin;
+        
+        /** The coefficient to calculate control points of Bezier curves. */
+        double k;
+        
+        /** The temporary value of x coordinate of the Bezier curve control vector. */
+        double kx;
+
+        /** The temporary value of y coordinate of the Bezier curve control vector. */
+        double ky;
+        
+        /** The x coordinate of the first path point (MOVE_TO). */
+        double mx;
+        
+        /** The y coordinate of the first path point (MOVE_TO). */
+        double my;
+
+        /**
+         * Constructs a new Arc2D.Iterator for given line and transformation
+         * 
+         * @param a - the source Arc2D object
+         * @param t the AffineTransformation.
+         */
+        Iterator(Arc2D a, AffineTransform t) {
+            if (width < 0 || height < 0) {
+                arcCount = 0;
+                lineCount = 0;
+                index = 1;
+                return;
+            }
+
+            this.width = a.getWidth() / 2.0;
+            this.height = a.getHeight() / 2.0;
+            this.x = a.getX() + width;
+            this.y = a.getY() + height;
+            this.angle = -Math.toRadians(a.getAngleStart());
+            this.extent = -a.getAngleExtent();
+            this.type = a.getArcType();
+            this.t = t;
+
+            if (Math.abs(extent) >= 360.0) {
+                arcCount = 4;
+                k = 4.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+                step = Math.PI / 2.0;
+                if (extent < 0.0) {
+                    step = -step;
+                    k = -k;
+                }
+            } else {
+                arcCount = (int)Math.rint(Math.abs(extent) / 90.0);
+                step = Math.toRadians(extent / arcCount);
+                k = 4.0 / 3.0 * (1.0 - Math.cos(step / 2.0))
+                        / Math.sin(step / 2.0);
+            }
+
+            lineCount = 0;
+            if (type == Arc2D.CHORD) {
+                lineCount++;
+            } else if (type == Arc2D.PIE) {
+                lineCount += 2;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > arcCount + lineCount;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = mx = x + cos * width;
+                coords[1] = my = y + sin * height;
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = mx - kx;
+                coords[1] = my + ky;
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = mx = x + cos * width;
+                coords[5] = my = y + sin * height;
+                coords[2] = mx + kx;
+                coords[3] = my - ky;
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = x;
+                coords[1] = y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = (float)(mx = x + cos * width);
+                coords[1] = (float)(my = y + sin * height);
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = (float)(mx - kx);
+                coords[1] = (float)(my + ky);
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = (float)(mx = x + cos * width);
+                coords[5] = (float)(my = y + sin * height);
+                coords[2] = (float)(mx + kx);
+                coords[3] = (float)(my - ky);
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /** The closure type of the arc. */
+    private int type;
+
+    /**
+     * Instantiates a new arc2D.
+     * 
+     * @param type the closure type.
+     */
+    protected Arc2D(int type) {
+        setArcType(type);
+    }
+
+    /**
+     * Takes the double-valued data and creates the corresponding Rectangle2D
+     * object with values either of type float or of type double depending on
+     * whether this Arc2D instance is of type Float or Double.
+     * 
+     * @param x the x coordinate of the upper left corner of the bounding rectangle.
+     * @param y the y coordinate of the upper left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * 
+     * @return the corresponding Rectangle2D object.
+     */
+    protected abstract Rectangle2D makeBounds(double x, double y, double width, double height);
+
+    /**
+     * Gets the start angle.
+     * 
+     * @return the start angle.
+     */
+    public abstract double getAngleStart();
+
+    /**
+     * Gets the width angle.
+     * 
+     * @return the width angle.
+     */
+    public abstract double getAngleExtent();
+
+    /**
+     * Sets the start angle.
+     * 
+     * @param start the new start angle.
+     */
+    public abstract void setAngleStart(double start);
+
+    /**
+     * Sets the width angle.
+     * 
+     * @param extent the new width angle.
+     */
+    public abstract void setAngleExtent(double extent);
+
+    /**
+     * Sets the data values that define the arc.
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param y the y coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param width the width of the rectangle that
+     * contains the arc.
+     * @param height the height of the rectangle that
+     * contains the arc.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the width angle of the arc in degrees.
+     * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public abstract void setArc(double x, double y, double width,
+            double height, double start, double extent, int type);
+
+    /**
+     * Gets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @return the arc type.
+     */
+    public int getArcType() {
+        return type;
+    }
+
+    /**
+     * Sets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @param type the new arc type.
+     */
+    public void setArcType(int type) {
+        if (type != OPEN && type != CHORD && type != PIE) {
+            // awt.205=Invalid type of Arc: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.205", type)); //$NON-NLS-1$
+        }
+        this.type = type;
+    }
+
+    /**
+     * Gets the start point of the arc as a Point2D.
+     * 
+     * @return the start point of the curved arc segment.
+     */
+    public Point2D getStartPoint() {
+        double a = Math.toRadians(getAngleStart());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    /**
+     * Gets the end point of the arc as a Point2D.
+     * 
+     * @return the end point of the curved arc segment.
+     */
+    public Point2D getEndPoint() {
+        double a = Math.toRadians(getAngleStart() + getAngleExtent());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    public Rectangle2D getBounds2D() {
+        if (isEmpty()) {
+            return makeBounds(getX(), getY(), getWidth(), getHeight());
+        }
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        double bx1 = containsAngle(180.0) ? rx1 : Math.min(p1.getX(), p2.getX());
+        double by1 = containsAngle(90.0)  ? ry1 : Math.min(p1.getY(), p2.getY());
+        double bx2 = containsAngle(0.0)   ? rx2 : Math.max(p1.getX(), p2.getX());
+        double by2 = containsAngle(270.0) ? ry2 : Math.max(p1.getY(), p2.getY());
+
+        if (type == PIE) {
+            double cx = getCenterX();
+            double cy = getCenterY();
+            bx1 = Math.min(bx1, cx);
+            by1 = Math.min(by1, cy);
+            bx2 = Math.max(bx2, cx);
+            by2 = Math.max(by2, cy);
+        }
+        return makeBounds(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param point the upper left corner of the bounding rectangle.
+     * @param size the size of the bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Point2D point, Dimension2D size, double start, double extent, int type) {
+        setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param rect the arc's bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Rectangle2D rect, double start, double extent, int type) {
+        setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc by copying it from another Arc2D.
+     * 
+     * @param arc the arc whose data is copied into this arc.
+     */
+    public void setArc(Arc2D arc) {
+        setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc
+                .getAngleStart(), arc.getAngleExtent(), arc.getArcType());
+    }
+
+    /**
+     * Sets the data for a circular arc by giving its center and radius.
+     * 
+     * @param x the x coordinate of the center of the circle.
+     * @param y the y coordinate of the center of the circle.
+     * @param radius the radius of the circle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArcByCenter(double x, double y, double radius, double start, double extent, int type) {
+        setArc(x - radius, y - radius, radius * 2.0, radius * 2.0, start, extent, type);
+    }
+
+    /**
+     * Sets the arc data for a circular arc based on two tangent lines
+     * and the radius. The two tangent lines are the lines from p1 
+     * to p2 and from p2 to p3, which determine a unique circle 
+     * with the given radius. The start and end points of the arc 
+     * are the points where the circle touches the two lines, and 
+     * the arc itself is the shorter of the two circle segments 
+     * determined by the two points (in other words, it is the 
+     * piece of the circle that is closer to the lines' intersection 
+     * point p2 and forms a concave shape with the segments from p1 to p2 
+     * and from p2 to p3).
+     * 
+     * @param p1 a point which determines one of the two tanget lines (with p2).
+     * @param p2 the point of intersection of the two tangent lines.
+     * @param p3 a point which determines one of the two tanget lines (with p2).
+     * @param radius the radius of the circular arc.
+     */
+    public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double radius) {
+        // Used simple geometric calculations of arc center, radius and angles by tangents
+        double a1 = -Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
+        double a2 = -Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
+        double am = (a1 + a2) / 2.0;
+        double ah = a1 - am;
+        double d = radius / Math.abs(Math.sin(ah));
+        double x = p2.getX() + d * Math.cos(am);
+        double y = p2.getY() - d * Math.sin(am);
+        ah = ah >= 0.0 ? Math.PI * 1.5 - ah : Math.PI * 0.5 - ah;
+        a1 = getNormAngle(Math.toDegrees(am - ah));
+        a2 = getNormAngle(Math.toDegrees(am + ah));
+        double delta = a2 - a1;
+        if (delta <= 0.0) {
+            delta += 360.0;
+        }
+        setArcByCenter(x, y, radius, a1, delta, type);
+    }
+
+    /**
+     * Sets a new start angle to be the angle given by the the vector 
+     * from the current center point to the specified point.
+     * 
+     * @param point the point that determines the new start angle.
+     */
+    public void setAngleStart(Point2D point) {
+        double angle = Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
+        setAngleStart(getNormAngle(-Math.toDegrees(angle)));
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points (x1, y1) and (x2, y2). The start angle is given 
+     * by the vector from the current center to the point (x1, y1) and
+     * the end angle is given by the vector from the center to the point
+     * (x2, y2).
+     * 
+     * @param x1 the x coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param y1 the y coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param x2 the x coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     * @param y2 the y coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(double x1, double y1, double x2, double y2) {
+        double cx = getCenterX();
+        double cy = getCenterY();
+        double a1 = getNormAngle(-Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
+        double a2 = getNormAngle(-Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
+        a2 -= a1;
+        if (a2 <= 0.0) {
+            a2 += 360.0;
+        }
+        setAngleStart(a1);
+        setAngleExtent(a2);
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points p1 and p2. The start angle is given 
+     * by the vector from the current center to the point p1 and
+     * the end angle is given by the vector from the center to the point
+     * p2.
+     * 
+     * @param p1 the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param p2 the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(Point2D p1, Point2D p2) {
+        setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Normalizes the angle by removing extra winding (past 360 degrees)
+     * and placing it in the positive degree range.
+     * 
+     * @param angle - the source angle in degrees
+     * 
+     * @return an angle between 0 and 360 degrees which corresponds
+     * to the same direction vector as the source angle.
+     */
+    double getNormAngle(double angle) {
+        double n = Math.floor(angle / 360.0);
+        return angle - n * 360.0;
+    }
+
+    /**
+     * Determines whether the given angle is contained in the span of the arc.
+     * 
+     * @param angle the angle to test in degrees.
+     * 
+     * @return true, if the given angle is between the start angle and 
+     * the end angle of the arc.
+     */
+    public boolean containsAngle(double angle) {
+        double extent = getAngleExtent();
+        if (extent >= 360.0) {
+            return true;
+        }
+        angle = getNormAngle(angle);
+        double a1 = getNormAngle(getAngleStart());
+        double a2 = a1 + extent;
+        if (a2 > 360.0) {
+            return angle >= a1 || angle <= a2 - 360.0;
+        }
+        if (a2 < 0.0) {
+            return angle >= a2 + 360.0 || angle <= a1;
+        }
+        return extent > 0.0 ? a1 <= angle && angle <= a2 : a2 <= angle
+                && angle <= a1;
+    }
+
+    public boolean contains(double px, double py) {
+        // Normalize point
+        double nx = (px - getX()) / getWidth() - 0.5;
+        double ny = (py - getY()) / getHeight() - 0.5;
+
+        if ((nx * nx + ny * ny) > 0.25) {
+            return false;
+        }
+
+        double extent = getAngleExtent();
+        double absExtent = Math.abs(extent);
+        if (absExtent >= 360.0) {
+            return true;
+        }
+
+        boolean containsAngle = containsAngle(Math.toDegrees(-Math
+                .atan2(ny, nx)));
+        if (type == PIE) {
+            return containsAngle;
+        }
+        if (absExtent <= 180.0 && !containsAngle) {
+            return false;
+        }
+
+        Line2D l = new Line2D.Double(getStartPoint(), getEndPoint());
+        int ccw1 = l.relativeCCW(px, py);
+        int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
+        return ccw1 == 0 || ccw2 == 0
+                || ((ccw1 + ccw2) == 0 ^ absExtent > 180.0);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+
+        if (!(contains(rx, ry) && contains(rx + rw, ry)
+                && contains(rx + rw, ry + rh) && contains(rx, ry + rh))) {
+            return false;
+        }
+
+        double absExtent = Math.abs(getAngleExtent());
+        if (type != PIE || absExtent <= 180.0 || absExtent >= 360.0) {
+            return true;
+        }
+
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        if (r.contains(cx, cy)) {
+            return false;
+        }
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        return !r.intersectsLine(cx, cy, p1.getX(), p1.getY())
+                && !r.intersectsLine(cx, cy, p2.getX(), p2.getY());
+    }
+
+    @Override
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        // Check: Does arc contain rectangle's points
+        if (contains(rx, ry) || contains(rx + rw, ry) || contains(rx, ry + rh)
+                || contains(rx + rw, ry + rh)) {
+            return true;
+        }
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        // Check: Does rectangle contain arc's points
+        if (r.contains(p1) || r.contains(p2) || (type == PIE && r.contains(cx, cy))) {
+            return true;
+        }
+
+        if (type == PIE) {
+            if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy) ||
+                r.intersectsLine(p2.getX(), p2.getY(), cx, cy))
+            {
+                return true;
+            }
+        } else {
+            if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
+                return true;
+            }
+        }
+
+        // Nearest rectangle point
+        double nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
+        double ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
+        return contains(nx, ny);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Area.java b/awt/java/awt/geom/Area.java
new file mode 100644
index 0000000..bc27d4e
--- /dev/null
+++ b/awt/java/awt/geom/Area.java
@@ -0,0 +1,317 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Area provides a minimal implementation for a generic shape.
+ */
+public class Area implements Shape, Cloneable {
+
+    /** The source Shape object. */
+    Shape s;
+
+    /**
+     * The Class NullIterator.
+     */
+    private static class NullIterator implements PathIterator {
+
+        /**
+         * Instantiates a new null iterator.
+         */
+        NullIterator() {
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return true;
+        }
+
+        public void next() {
+            // nothing
+        }
+
+        public int currentSegment(double[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+        public int currentSegment(float[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+    }
+
+    /**
+     * Instantiates a new area with no data.
+     */
+    public Area() {
+    }
+
+    /**
+     * Instantiates a new area with data given by the specified shape.
+     * 
+     * @param s the shape that gives the data for this Area
+     */
+    public Area(Shape s) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        this.s = s;
+    }
+
+    public boolean contains(double x, double y) {
+        return s == null ? false : s.contains(x, y);
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        return s == null ? false : s.contains(x, y, width, height);
+    }
+
+    public boolean contains(Point2D p) {
+        if (p == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(p);
+    }
+
+    public boolean contains(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(r);
+    }
+
+    /**
+     * Tests whether the object is equal to this Area.
+     * 
+     * @param obj the object to compare
+     * 
+     * @return true, if successful
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        return s == null ? false : s.intersects(x, y, width, height);
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.intersects(r);
+    }
+
+    public Rectangle getBounds() {
+        return s == null ? new Rectangle() : s.getBounds();
+    }
+
+    public Rectangle2D getBounds2D() {
+        return s == null ? new Rectangle2D.Double(): s.getBounds2D();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return s == null ? new NullIterator() : s.getPathIterator(t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
+    }
+
+    /**
+     * Adds the specified area to this area.
+     * 
+     * @param area the area to add to this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Performs an exclusive or operation between this shape and the
+     * specified shape.
+     * 
+     * @param area the area to XOR against this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Extracts a Rectangle2D from the source shape if the underlying shape
+     * data describes a rectangle.
+     * 
+     * @return a Rectangle2D object if the source shape is rectangle, 
+     * or null if shape is empty or not rectangle.
+     */
+    Rectangle2D extractRectangle() {
+        if (s == null) {
+            return null;
+        }
+        float[] points = new float[12];
+        int count = 0;
+        PathIterator p = s.getPathIterator(null);
+        float[] coords = new float[6];
+        while(!p.isDone()) {
+            int type = p.currentSegment(coords);
+            if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
+                return null;
+            }
+            points[count++] = coords[0];
+            points[count++] = coords[1];
+            p.next();
+        }
+        if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4] &&
+            points[1] == points[3] && points[3] == points[9] && points[5] == points[7])
+        {
+            return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7] - points[1]);
+        }
+        return null;
+    }
+    
+    /**
+     * Reduces the size of this Area by intersecting it with the 
+     * specified Area if they are both rectangles.
+     * 
+     * @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D, Rectangle2D)
+     * 
+     * @param area the area
+     */
+    public void intersect(Area area) {
+        Rectangle2D src1 = extractRectangle();
+        Rectangle2D src2 = area.extractRectangle();
+        if (src1 != null && src2 != null) {
+            Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
+        }
+    }
+
+    /**
+     * Subtract the specified area from this area.
+     * 
+     * @param area the area to subtract
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is empty.
+     * 
+     * @return true, if this Area is empty
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is polygonal.
+     * 
+     * @return true, if this Area is polygonal
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is rectangular.
+     * 
+     * @return true, if this Area is rectangular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is singular.
+     * 
+     * @return true, if this Area is singular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Resets the data of this Area.
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Transforms the data of this Area according to the specified 
+     * AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     */
+    public void transform(AffineTransform t) {
+        s = t.createTransformedShape(s);
+    }
+
+    /**
+     * Creates a new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     * 
+     * @return the new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     */
+    public Area createTransformedArea(AffineTransform t) {
+        return s == null ? new Area() : new Area(t.createTransformedShape(s));
+    }
+
+    @Override
+    public Object clone() {
+        return new Area(this);
+    }
+
+}
diff --git a/awt/java/awt/geom/CubicCurve2D.java b/awt/java/awt/geom/CubicCurve2D.java
new file mode 100644
index 0000000..3e440c8
--- /dev/null
+++ b/awt/java/awt/geom/CubicCurve2D.java
@@ -0,0 +1,945 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class CubicCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by four points:
+ * a start point, an end point, and two control points. 
+ * The control points give information about the tangent and next 
+ * derivative at the endpoints according to the standard theory of 
+ * Bezier curves. For more information on Bezier curves, 
+ * see <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">this article</a>.
+ */
+public abstract class CubicCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of CubicCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the first control point. */
+        public float ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public float ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public float ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public float ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Float(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Float(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx1 = (float)ctrlx1;
+            this.ctrly1 = (float)ctrly1;
+            this.ctrlx2 = (float)ctrlx2;
+            this.ctrly2 = (float)ctrly2;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setCurve(float x1, float y1, float ctrlx1, float ctrly1,
+                float ctrlx2, float ctrly2, float x2, float y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            float ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            float rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            float ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of CubicCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the first control point. */
+        public double ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public double ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public double ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public double ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Double(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Double(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            double ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            double rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            double ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Double(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /*
+     * CubicCurve2D path iterator 
+     */
+    /**
+     * The Iterator class for the Shape CubicCurve2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source CubicCurve2D object. */
+        CubicCurve2D c;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new CubicCurve2D.Iterator for given line and transformation
+         * 
+         * @param c - the source CubicCurve2D object
+         * @param t the t
+         */
+        Iterator(CubicCurve2D c, AffineTransform t) {
+            this.c = c;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = c.getCtrlX1();
+                coords[1] = c.getCtrlY1();
+                coords[2] = c.getCtrlX2();
+                coords[3] = c.getCtrlY2();
+                coords[4] = c.getX2();
+                coords[5] = c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = (float)c.getCtrlX1();
+                coords[1] = (float)c.getCtrlY1();
+                coords[2] = (float)c.getCtrlX2();
+                coords[3] = (float)c.getCtrlY2();
+                coords[4] = (float)c.getX2();
+                coords[5] = (float)c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new 2-D cubic curve.
+     */
+    protected CubicCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the first control point.
+     * 
+     * @return the x coordinate of the first control point
+     */
+    public abstract double getCtrlX1();
+
+    /**
+     * Gets the y coordinate of the first control point.
+     * 
+     * @return the y coordinate of the first control point
+     */
+    public abstract double getCtrlY1();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP1();
+
+    /**
+     * Gets the x coordinate of the second control point.
+     * 
+     * @return the x coordinate of the second control point
+     */
+    public abstract double getCtrlX2();
+
+    /**
+     * Gets the y coordinate of the second control point.
+     * 
+     * @return the y coordinate of the second control point
+     */
+    public abstract double getCtrlY2();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP2();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2);
+
+    /**
+     * Sets the data of the curve as point objects.
+     * 
+     * @param p1 the starting point
+     * @param cp1 the first control point
+     * @param cp2 the second control point
+     * @param p2 the end point
+     * 
+     * @throws NullPointerException if any of the points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
+        setCurve(
+                p1.getX(), p1.getY(),
+                cp1.getX(), cp1.getY(),
+                cp2.getX(), cp2.getY(),
+                p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 8.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(Point2D, Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY(),
+                points[offset + 3].getX(), points[offset + 3].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another CubicCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(CubicCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX1(), curve.getCtrlY1(),
+                curve.getCtrlX2(), curve.getCtrlY2(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the square of the flatness
+     */
+    public double getFlatnessSq() {
+        return getFlatnessSq(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the square of the flatness
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.max(
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1),
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx2, ctrly2));
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatnessSq(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return getFlatnessSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Gets the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the flatness of this curve
+     */
+    public double getFlatness() {
+        return getFlatness(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the flatness
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatness(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return getFlatness(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of this curve is left unchanged.
+     * 
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged.
+     * 
+     * @param src the original curve to be divided in two
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx1 = src.getCtrlX1();
+        double cy1 = src.getCtrlY1();
+        double cx2 = src.getCtrlX2();
+        double cy2 = src.getCtrlY2();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged. The data for the 
+     * three curves is read/written in the usual order: { x1, y1, 
+     * ctrlx1, ctrly1, ctrlx2, crtry2, x2, y3 }
+     * 
+     * @param src the array that gives the data values for the source curve
+     * @param srcOff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 8
+     * or if left.length < leftOff + 8 or if right.length < rightOff + 8.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcOff, double left[], int leftOff, double right[], int rightOff) {
+        double x1 = src[srcOff + 0];
+        double y1 = src[srcOff + 1];
+        double cx1 = src[srcOff + 2];
+        double cy1 = src[srcOff + 3];
+        double cx2 = src[srcOff + 4];
+        double cy2 = src[srcOff + 5];
+        double x2 = src[srcOff + 6];
+        double y2 = src[srcOff + 7];
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = ax;
+            left[leftOff + 5] = ay;
+            left[leftOff + 6] = cx;
+            left[leftOff + 7] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = bx;
+            right[rightOff + 3] = by;
+            right[rightOff + 4] = cx2;
+            right[rightOff + 5] = cy2;
+            right[rightOff + 6] = x2;
+            right[rightOff + 7] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveCubic(double eqn[]) {
+        return solveCubic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        return Crossing.solveCubic(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(at), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/geom/Dimension2D.java b/awt/java/awt/geom/Dimension2D.java
new file mode 100644
index 0000000..eef63e6
--- /dev/null
+++ b/awt/java/awt/geom/Dimension2D.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class Dimension2D represents a size (width and height) of a 
+ * geometric object. It stores double-valued data in order to be compatible
+ * with high-precision geometric operations.
+ */
+public abstract class Dimension2D implements Cloneable {
+
+    /**
+     * Instantiates a new dimension 2d with no data.
+     */
+    protected Dimension2D() {
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    public abstract double getHeight();
+
+    /**
+     * Sets the width and height.
+     * 
+     * @param width the width
+     * @param height the height
+     */
+    public abstract void setSize(double width, double height);
+
+    /**
+     * Sets the width and height based on the data of another 
+     * Dimension2D object.
+     * 
+     * @param d the Dimension2D object providing the data to copy 
+     * into this Dimension2D object
+     */
+    public void setSize(Dimension2D d) {
+        setSize(d.getWidth(), d.getHeight());
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
+
diff --git a/awt/java/awt/geom/Ellipse2D.java b/awt/java/awt/geom/Ellipse2D.java
new file mode 100644
index 0000000..33464af
--- /dev/null
+++ b/awt/java/awt/geom/Ellipse2D.java
@@ -0,0 +1,403 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Ellipse2D describes an ellipse defined by a rectangular
+ * area in which it is inscribed.
+ */
+public abstract class Ellipse2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of Ellipse2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public float width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new float-valued Ellipse2D.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Ellipse2D with the specified data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        /**
+         * Sets the data of the ellipse's bounding rectangle.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public void setFrame(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Ellipse2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public double width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new double-valued Ellipse2D.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Ellipse2D with the specified
+         * data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * Ellipse2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse an Ellipse2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Ellipse is subdivided into four quarters by x and y axis. Each part approximated by
+         * cubic Bezier curve. Arc in first quarter is started in (a, 0) and finished in (0, b) points.
+         * Control points for cubic curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
+         * calculated based on requirement Bezier curve in point 0.5 should lay on the arc.
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        final double points[][] = {
+                { 1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0 },
+                { 0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5 },
+                { 0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0 },
+                { 0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5 }
+        };
+
+        /** The x coordinate of left-upper corner of the ellipse bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the ellipse bounds. */
+        double y;
+        
+        /** The width of the ellipse bounds. */
+        double width;
+        
+        /** The height of the ellipse bounds. */
+        double height;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Ellipse2D.Iterator for given ellipse and transformation
+         * 
+         * @param e - the source Ellipse2D object
+         * @param t the t
+         */
+        Iterator(Ellipse2D e, AffineTransform t) {
+            this.x = e.getX();
+            this.y = e.getY();
+            this.width = e.getWidth();
+            this.height = e.getHeight();
+            this.t = t;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = x + p[4] * width;
+                coords[1] = y + p[5] * height;
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                double p[] = points[index - 1];
+                int j = 0;
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = x + p[j++] * width;
+                    coords[j] = y + p[j++] * height;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = (float)(x + p[4] * width);
+                coords[1] = (float)(y + p[5] * height);
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                int j = 0;
+                double p[] = points[index - 1];
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = (float)(x + p[j++] * width);
+                    coords[j] = (float)(y + p[j++] * height);
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Ellipse2D.
+     */
+    protected Ellipse2D() {
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double a = (px - getX()) / getWidth() - 0.5;
+        double b = (py - getY()) / getHeight() - 0.5;
+
+        return a * a + b * b < 0.25;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double cx = getX() + getWidth() / 2.0;
+        double cy = getY() + getHeight() / 2.0;
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+}
+
diff --git a/awt/java/awt/geom/FlatteningPathIterator.java b/awt/java/awt/geom/FlatteningPathIterator.java
new file mode 100644
index 0000000..ca5c7c2
--- /dev/null
+++ b/awt/java/awt/geom/FlatteningPathIterator.java
@@ -0,0 +1,326 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class FlatteningPathIterator takes a PathIterator for traversing 
+ * a curved shape and flattens it by estimating the curve as a series 
+ * of line segments. The flattening factor indicates how far the 
+ * estimating line segments are allowed to be from the actual curve:
+ * the FlatteningPathIterator will keep dividing each curved segment 
+ * into smaller and smaller flat segments until either the segments 
+ * are withing the flattening factor of the curve or until the buffer
+ * limit is reached.
+ */
+public class FlatteningPathIterator implements PathIterator {
+
+    /** The default points buffer size. */
+    private static final int BUFFER_SIZE = 16;
+    
+    /** The default curve subdivision limit. */
+    private static final int BUFFER_LIMIT = 16;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 16;
+    
+    /** The type of current segment to be flat. */
+    int bufType;
+    
+    /** The curve subdivision limit. */
+    int bufLimit;
+    
+    /** The current points buffer size. */
+    int bufSize;
+    
+    /** The inner cursor position in points buffer. */
+    int bufIndex;
+    
+    /** The current subdivision count. */
+    int bufSubdiv;
+
+    /** The points buffer. */
+    double buf[];
+    
+    /** The indicator of empty points buffer. */
+    boolean bufEmpty = true;
+    
+    /** The source PathIterator. */
+    PathIterator p;
+    
+    /** The flatness of new path. */
+    double flatness;
+    
+    /** The square of flatness. */
+    double flatness2;
+    
+    /** The x coordinate of previous path segment. */
+    double px;
+
+    /** The y coordinate of previous path segment. */
+    double py;
+    
+    /** The tamporary buffer for getting points from PathIterator. */
+    double coords[] = new double[6];
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * which indicates how close together the points on the curve 
+     * should be chosen. The buffer limit defaults to 16 which means 
+     * that each curve will be divided into no more than 16 segments 
+     * regardless of the flattening factor.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * 
+     * @throws IllegalArgumentException if the flatness is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness) {
+        this(path, flatness, BUFFER_LIMIT);
+    }
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * and a buffer limit. The FlatteningPathIterator will keep 
+     * dividing each curved segment into smaller and smaller flat segments 
+     * until either the segments are withing the flattening factor of the 
+     * curve or until the buffer limit is reached.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * @param limit the maximum number of flat segments to divide each 
+     * curve into
+     * 
+     * @throws IllegalArgumentException if the flatness or limit is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
+        if (flatness < 0.0) {
+            // awt.206=Flatness is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
+        }
+        if (limit < 0) {
+            // awt.207=Limit is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
+        }
+        if (path == null) {
+            // awt.208=Path is null
+            throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
+        }
+        this.p = path;
+        this.flatness = flatness;
+        this.flatness2 = flatness * flatness;
+        this.bufLimit = limit;
+        this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
+        this.buf = new double[bufSize];
+        this.bufIndex = bufSize;
+    }
+
+    /**
+     * Gets the flattening factor.
+     * 
+     * @return the flattening factor
+     */
+    public double getFlatness() {
+        return flatness;
+    }
+
+    /**
+     * Gets the maximum number of subdivisions per curved segment.
+     * 
+     * @return the maximum number of subdivisions per curved segment
+     */
+    public int getRecursionLimit() {
+        return bufLimit;
+    }
+
+    public int getWindingRule() {
+        return p.getWindingRule();
+    }
+
+    public boolean isDone() {
+        return bufEmpty && p.isDone();
+    }
+
+    /**
+     * Calculates flat path points for current segment of the source shape.
+     * 
+     * Line segment is flat by itself. Flatness of quad and cubic curves evaluated by getFlatnessSq() method.
+     * Curves subdivided until current flatness is bigger than user defined and subdivision limit isn't exhausted.
+     * Single source segment translated to series of buffer points. The less flatness the bigger serries.
+     * Every currentSegment() call extract one point from the buffer. When series completed evaluate() takes next source shape segment.
+     */
+    void evaluate() {
+        if (bufEmpty) {
+            bufType = p.currentSegment(coords);
+        }
+
+        switch (bufType) {
+        case SEG_MOVETO:
+        case SEG_LINETO:
+            px = coords[0];
+            py = coords[1];
+            break;
+        case SEG_QUADTO:
+            if (bufEmpty) {
+                bufIndex -= 6;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 4) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
+
+                bufIndex -= 4;
+                bufSubdiv++;
+            }
+
+            bufIndex += 4;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        case SEG_CUBICTO:
+            if (bufEmpty) {
+                bufIndex -= 8;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 6) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
+
+                bufIndex -= 6;
+                bufSubdiv++;
+            }
+
+            bufIndex += 6;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        }
+
+    }
+
+    public void next() {
+        if (bufEmpty) {
+            p.next();
+        }
+    }
+
+    public int currentSegment(float[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = (float)px;
+            coords[1] = (float)py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+
+    public int currentSegment(double[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = px;
+            coords[1] = py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+}
+
diff --git a/awt/java/awt/geom/GeneralPath.java b/awt/java/awt/geom/GeneralPath.java
new file mode 100644
index 0000000..36b01c4
--- /dev/null
+++ b/awt/java/awt/geom/GeneralPath.java
@@ -0,0 +1,566 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class GeneralPath represents a shape whose outline is given 
+ * by different types of curved and straight segments.
+ */
+public final class GeneralPath implements Shape, Cloneable {
+
+    /** The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}. */
+    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+    
+    /** The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}. */
+    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+    /** The buffers size. */
+    private static final int BUFFER_SIZE = 10;
+    
+    /** The buffers capacity. */
+    private static final int BUFFER_CAPACITY = 10;
+
+    /** The point's types buffer. */
+    byte[] types;
+    
+    /** The points buffer. */
+    float[] points;
+    
+    /** The point's type buffer size. */
+    int typeSize;
+    
+    /** The points buffer size. */
+    int pointSize;
+    
+    /** The path rule. */
+    int rule;
+
+    /** The space amount in points buffer for different segmenet's types. */
+    static int pointShift[] = {
+            2,  // MOVETO
+            2,  // LINETO
+            4,  // QUADTO
+            6,  // CUBICTO
+            0}; // CLOSE
+
+    /*
+     * GeneralPath path iterator 
+     */
+    /**
+     * The Class Iterator is the subclass of Iterator for traversing the 
+     * outline of a GeneralPath.
+     */
+    class Iterator implements PathIterator {
+
+        /** The current cursor position in types buffer. */
+        int typeIndex;
+        
+        /** The current cursor position in points buffer. */
+        int pointIndex;
+        
+        /** The source GeneralPath object. */
+        GeneralPath p;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path
+         * 
+         * @param path - the source GeneralPath object
+         */
+        Iterator(GeneralPath path) {
+            this(path, null);
+        }
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path and transformation
+         * 
+         * @param path - the source GeneralPath object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(GeneralPath path, AffineTransform at) {
+            this.p = path;
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return p.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return typeIndex >= p.typeSize;
+        }
+
+        public void next() {
+            typeIndex++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            for (int i = 0; i < count; i++) {
+                coords[i] = p.points[pointIndex + i];
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            System.arraycopy(p.points, pointIndex, coords, 0, count);
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new general path with the winding rule set 
+     * to {@link PathIterator#WIND_NON_ZERO} and the initial capacity
+     * (number of segments) set to the default value 10.
+     */
+    public GeneralPath() {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     *  and the initial capacity (number of segments) set to the 
+     *  default value 10.
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public GeneralPath(int rule) {
+        this(rule, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     * and initial capacity (number of segments).
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     * @param initialCapacity the number of segments the path is set to hold
+     */
+    public GeneralPath(int rule, int initialCapacity) {
+        setWindingRule(rule);
+        types = new byte[initialCapacity];
+        points = new float[initialCapacity * 2];
+    }
+
+    /**
+     * Creates a new GeneralPath from the outline of the given shape.
+     * 
+     * @param shape the shape
+     */
+    public GeneralPath(Shape shape) {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+        PathIterator p = shape.getPathIterator(null);
+        setWindingRule(p.getWindingRule());
+        append(p, false);
+    }
+
+    /**
+     * Sets the winding rule, which determines how to decide whether 
+     * a point that isn't on the path itself is inside or outside of 
+     * the shape.
+     * 
+     * @param rule the new winding rule
+     * 
+     * @throws IllegalArgumentException if the winding rule is neither
+     * {@link PathIterator#WIND_EVEN_ODD} nor {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public void setWindingRule(int rule) {
+        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
+            // awt.209=Invalid winding rule value
+            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
+        }
+        this.rule = rule;
+    }
+
+    /**
+     * Gets the winding rule.
+     * 
+     * @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public int getWindingRule() {
+        return rule;
+    }
+
+    /**
+     * Checks the point data buffer sizes to see whether pointCount additional
+     * point-data elements can fit. (Note that the number of point data 
+     * elements to add is more than one per point -- it depends on the type 
+     * of point being added.) Reallocates the buffers to enlarge the size if necessary.
+     * 
+     * @param pointCount - the number of point data elements to be added
+     * @param checkMove whether to check for existing points
+     * 
+     * @throws IllegalPathStateException checkMove is true and the 
+     * path is currently empty.
+     */
+    void checkBuf(int pointCount, boolean checkMove) {
+        if (checkMove && typeSize == 0) {
+            // awt.20A=First segment should be SEG_MOVETO type
+            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
+        }
+        if (typeSize == types.length) {
+            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
+            System.arraycopy(types, 0, tmp, 0, typeSize);
+            types = tmp;
+        }
+        if (pointSize + pointCount > points.length) {
+            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
+            System.arraycopy(points, 0, tmp, 0, pointSize);
+            points = tmp;
+        }
+    }
+
+    /**
+     * Appends a new point to the end of this general path, disconnected
+     * from the existing path.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void moveTo(float x, float y) {
+        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
+            points[pointSize - 2] = x;
+            points[pointSize - 1] = y;
+        } else {
+            checkBuf(2, false);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = x;
+            points[pointSize++] = y;
+        }
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a straight line segment from the current endpoint to the 
+     * given new point.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void lineTo(float x, float y) {
+        checkBuf(2, true);
+        types[typeSize++] = PathIterator.SEG_LINETO;
+        points[pointSize++] = x;
+        points[pointSize++] = y;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a quadratic curve from the current endpoint to the point (x2, y2)
+     * using the point (x1, y1) as the quadratic curve's control point.
+     * 
+     * @param x1 the x coordinate of the quadratic curve's control point
+     * @param y1 the y coordinate of the quadratic curve's control point
+     * @param x2 the x coordinate of the quadratic curve's end point
+     * @param y2 the y coordinate of the quadratic curve's end point
+     */
+    public void quadTo(float x1, float y1, float x2, float y2) {
+        checkBuf(4, true);
+        types[typeSize++] = PathIterator.SEG_QUADTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a cubic curve from the current endpoint to the point (x3, y3)
+     * using (x1, y1) and (x2, y2) as control points.
+     * 
+     * @see java.awt.geom.CubicCurve2D
+     * 
+     * @param x1 the x coordinate of the new cubic segment's first control point
+     * @param y1 the y coordinate of the new cubic segment's first control point
+     * @param x2 the x coordinate of the new cubic segment's second control point
+     * @param y2 the y coordinate of the new cubic segment's second control point
+     * @param x3 the x coordinate of the new cubic segment's end point
+     * @param y3 the y coordinate of the new cubic segment's end point
+     */
+    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+        checkBuf(6, true);
+        types[typeSize++] = PathIterator.SEG_CUBICTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+        points[pointSize++] = x3;
+        points[pointSize++] = y3;
+    }
+
+    /**
+     * Appends the type information to declare that the current
+     * endpoint closes the curve.
+     */
+    public void closePath() {
+        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
+            checkBuf(0, true);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+    }
+
+    /**
+     * Appends the outline of the specified shape onto the end 
+     * of this GeneralPath.
+     * 
+     * @param shape the shape whose outline is to be appended
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     * 
+     * @throws NullPointerException if the shape parameter is null
+     */
+    public void append(Shape shape, boolean connect) {
+        PathIterator p = shape.getPathIterator(null);
+        append(p, connect);
+    }
+
+    /**
+     * Appends the path defined by the specified PathIterator onto the end 
+     * of this GeneralPath.
+     * 
+     * @param path the PathIterator that defines the new path to append
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     */
+    public void append(PathIterator path, boolean connect) {
+        while (!path.isDone()) {
+            float coords[] = new float[6];
+            switch (path.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!connect || typeSize == 0) {
+                    moveTo(coords[0], coords[1]);
+                    break;
+                }
+                if (types[typeSize - 1] != PathIterator.SEG_CLOSE &&
+                    points[pointSize - 2] == coords[0] &&
+                    points[pointSize - 1] == coords[1])
+                {
+                    break;
+                }
+            // NO BREAK;
+            case PathIterator.SEG_LINETO:
+                lineTo(coords[0], coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                quadTo(coords[0], coords[1], coords[2], coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                closePath();
+                break;
+            }
+            path.next();
+            connect = false;
+        }
+    }
+
+    /**
+     * Gets the current end point of the path.
+     * 
+     * @return the current end point of the path
+     */
+    public Point2D getCurrentPoint() {
+        if (typeSize == 0) {
+            return null;
+        }
+        int j = pointSize - 2;
+        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
+
+            for (int i = typeSize - 2; i > 0; i--) {
+                int type = types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    break;
+                }
+                j -= pointShift[type];
+            }
+        }
+        return new Point2D.Float(points[j], points[j + 1]);
+    }
+
+    /**
+     * Resets the GeneralPath to being an empty path. The underlying
+     * point and segment data is not deleted but rather the end indices
+     * of the data arrays are set to zero.
+     */
+    public void reset() {
+        typeSize = 0;
+        pointSize = 0;
+    }
+
+    /**
+     * Transform all of the coordinates of this path according to the
+     * specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     */
+    public void transform(AffineTransform t) {
+        t.transform(points, 0, points, 0, pointSize / 2);
+    }
+
+    /**
+     * Creates a new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     * 
+     * @return the new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform
+     */
+    public Shape createTransformedShape(AffineTransform t) {
+        GeneralPath p = (GeneralPath)clone();
+        if (t != null) {
+            p.transform(t);
+        }
+        return p;
+    }
+
+    public Rectangle2D getBounds2D() {
+        float rx1, ry1, rx2, ry2;
+        if (pointSize == 0) {
+            rx1 = ry1 = rx2 = ry2 = 0.0f;
+        } else {
+            int i = pointSize - 1;
+            ry1 = ry2 = points[i--];
+            rx1 = rx2 = points[i--];
+            while (i > 0) {
+                float y = points[i--];
+                float x = points[i--];
+                if (x < rx1) {
+                    rx1 = x;
+                } else
+                    if (x > rx2) {
+                        rx2 = x;
+                    }
+                if (y < ry1) {
+                    ry1 = y;
+                } else
+                    if (y > ry2) {
+                        ry2 = y;
+                    }
+            }
+        }
+        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    /**
+     * Checks the cross count (number of times a ray from the point 
+     * crosses the shape's boundary) to determine whether the number 
+     * of crossings corresponds to a point inside the shape or not
+     * (according to the shape's path rule).
+     * 
+     * @param cross - the point's cross count
+     * 
+     * @return true if the point is inside the path, or false otherwise
+     */
+    boolean isInside(int cross) {
+        if (rule == WIND_NON_ZERO) {
+            return Crossing.isInsideNonZero(cross);
+        }
+        return Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(double px, double py) {
+        return isInside(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && isInside(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || isInside(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            GeneralPath p = (GeneralPath) super.clone();
+            p.types = types.clone();
+            p.points = points.clone();
+            return p;
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/IllegalPathStateException.java b/awt/java/awt/geom/IllegalPathStateException.java
new file mode 100644
index 0000000..7f459e7
--- /dev/null
+++ b/awt/java/awt/geom/IllegalPathStateException.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class IllegalPathStateException indicates errors where the 
+ * current state of a path object is imcompatible with the desired 
+ * action, such as performing non-trivial actions on an empty path.
+ */
+public class IllegalPathStateException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5158084205220481094L;
+
+    /**
+     * Instantiates a new illegal path state exception.
+     */
+    public IllegalPathStateException() {
+    }
+
+    /**
+     * Instantiates a new illegal path state exception with the 
+     * specified detail message.
+     * 
+     * @param s the details of the error
+     */
+    public IllegalPathStateException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Line2D.java b/awt/java/awt/geom/Line2D.java
new file mode 100644
index 0000000..a53c470
--- /dev/null
+++ b/awt/java/awt/geom/Line2D.java
@@ -0,0 +1,871 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Line2D represents a line whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Line2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of Line2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * its data values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float x2, float y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Float(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values that define the line.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setLine(float x1, float y1, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Float(rx, ry, rw, rh);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Line2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued  Line2D with
+         * its data values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double x2, double y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Double(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Double(rx, ry, rw, rh);
+        }
+    }
+
+    /*
+     * Line2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a Line2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the start line point. */
+        double x1;
+        
+        /** The y coordinate of the start line point. */
+        double y1;
+        
+        /** The x coordinate of the end line point. */
+        double x2;
+        
+        /** The y coordinate of the end line point. */
+        double y2;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Line2D.Iterator for given line and transformation
+         * 
+         * @param l - the source Line2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(Line2D l, AffineTransform at) {
+            this.x1 = l.getX1();
+            this.y1 = l.getY1();
+            this.x2 = l.getX2();
+            this.y2 = l.getY2();
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x1;
+                coords[1] = y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = x2;
+                coords[1] = y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)x1;
+                coords[1] = (float)y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = (float)x2;
+                coords[1] = (float)y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Line2D.
+     */
+    protected Line2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x2
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the p the starting point.
+     * 
+     * @return the p the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the p end point.
+     * 
+     * @return the p end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setLine(double x1, double y1, double x2, double y2);
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param p1 the starting point
+     * @param p2 the end point
+     */
+    public void setLine(Point2D p1, Point2D p2) {
+        setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the line's endpoints by copying the data from another Line2D.
+     * 
+     * @param line the Line2D to copy the endpoint data from
+     */
+    public void setLine(Line2D line) {
+        setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
+    }
+
+    public Rectangle getBounds() {
+    return getBounds2D().getBounds();
+    }
+
+    /**
+     * Tells where the point is with respect to the line segment, 
+     * given the orientation of the line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to the line segment, 
+     * given the orientation of the line segment
+     */
+    public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2-x1, y2-y1) P = (px-x1, py-y1)
+         */
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double t = px * y2 - py * x2; // PxA
+        if (t == 0.0) {
+            t = px * x2 + py * y2; // P*A
+            if (t > 0.0) {
+                px -= x2; // B-A
+                py -= y2;
+                t = px * x2 + py * y2; // (P-A)*A
+                if (t < 0.0) {
+                    t = 0.0;
+                }
+            }
+        }
+
+        return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(double px, double py) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param p the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(Point2D p) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Tells whether the two line segments cross.
+     * 
+     * @param x1 the x coordinate of the starting point of the first segment
+     * @param y1 the y coordinate of the starting point of the first segment
+     * @param x2 the x coordinate of the end point of the first segment
+     * @param y2 the y coordinate of the end point of the first segment
+     * @param x3 the x coordinate of the starting point of the second segment
+     * @param y3 the y coordinate of the starting point of the second segment
+     * @param x4 the x coordinate of the end point of the second segment
+     * @param y4 the y coordinate of the end point of the second segment
+     * 
+     * @return true, if the two line segments cross
+     */
+    public static boolean linesIntersect(double x1, double y1, double x2,
+            double y2, double x3, double y3, double x4, double y4)
+    {
+        /*
+         * A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
+         * y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B
+         *
+         * Result is ((AxB) * (AxC) <=0) and ((DxE) * (DxF) <= 0)
+         *
+         * DxE = (C-B)x(-B) = BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB =
+         * AxB+BxC-AxC
+         */
+
+        x2 -= x1; // A
+        y2 -= y1;
+        x3 -= x1; // B
+        y3 -= y1;
+        x4 -= x1; // C
+        y4 -= y1;
+
+        double AvB = x2 * y3 - x3 * y2;
+        double AvC = x2 * y4 - x4 * y2;
+
+        // Online
+        if (AvB == 0.0 && AvC == 0.0) {
+            if (x2 != 0.0) {
+                return
+                    (x4 * x3 <= 0.0) ||
+                    ((x3 * x2 >= 0.0) &&
+                     (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2 || x4 >= x2));
+            }
+            if (y2 != 0.0) {
+                return
+                    (y4 * y3 <= 0.0) ||
+                    ((y3 * y2 >= 0.0) &&
+                     (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2 || y4 >= y2));
+            }
+            return false;
+        }
+
+        double BvC = x3 * y4 - x4 * y3;
+
+        return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the test segment
+     * @param y1 the y coordinate of the starting point of the test segment
+     * @param x2 the x coordinate of the end point of the test segment
+     * @param y2 the y coordinate of the end point of the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param l the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     * 
+     * @throws NullPointerException if l is null
+     */
+    public boolean intersectsLine(Line2D l) {
+        return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
+         */
+        x2 -= x1; // A = (x2, y2)
+        y2 -= y1;
+        px -= x1; // P = (px, py)
+        py -= y1;
+        double dist;
+        if (px * x2 + py * y2 <= 0.0) { // P*A
+            dist = px * px + py * py;
+        } else {
+            px = x2 - px; // P = A - P = (x2 - px, y2 - py)
+            py = y2 - py;
+            if (px * x2 + py * y2 <= 0.0) { // P*A
+                dist = px * px + py * py;
+            } else {
+                dist = px * y2 - py * x2;
+                dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
+            }
+        }
+        if (dist < 0) {
+            dist = 0;
+        }
+        return dist;
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(double px, double py) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(Point2D p) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(double px, double py) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(Point2D p) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double s = px * y2 - py * x2;
+        return s * s / (x2 * x2 + y2 * y2);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(double px, double py) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(Point2D p) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(double px, double py) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(Point2D p) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    public boolean contains(double px, double py) {
+        return false;
+    }
+
+    public boolean contains(Point2D p) {
+        return false;
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return false;
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        return false;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new Iterator(this, at);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/NoninvertibleTransformException.java b/awt/java/awt/geom/NoninvertibleTransformException.java
new file mode 100644
index 0000000..2b7b542
--- /dev/null
+++ b/awt/java/awt/geom/NoninvertibleTransformException.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class NoninvertibleTransformException is the exception that is thrown 
+ * when an action requires inverting an {@link AffineTransform} that is 
+ * not invertible (has determinant 0).
+ */
+public class NoninvertibleTransformException extends java.lang.Exception {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 6137225240503990466L;
+
+    /**
+     * Instantiates a new noninvertible transform exception.
+     * 
+     * @param s the error message
+     */
+    public NoninvertibleTransformException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/PathIterator.java b/awt/java/awt/geom/PathIterator.java
new file mode 100644
index 0000000..5a98083
--- /dev/null
+++ b/awt/java/awt/geom/PathIterator.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Interface PathIterator represents an iterator object that can 
+ * be used to traverse the outline of a {@link java.awt.Shape}. 
+ * It returns points along the boundary of the Shape 
+ * which may be actual vertices (in the case of a shape made of line 
+ * segments) or may be points on a curved segment with the distance 
+ * between the points determined by a chosen flattening factor. 
+ * <p>
+ * If the shape is closed, the outline is traversed in the counter-clockwise 
+ * direction. That means that moving forward along the boundary is to travel 
+ * in such a way that the interior of the shape is to the left of the 
+ * outline path and the exterior of the shape is to the right of the outline
+ * path. The interior and exterior of the shape are determined by a 
+ * winding rule. 
+ */
+public interface PathIterator {
+
+    /** The Constant WIND_EVEN_ODD indicates the winding rule that says 
+     * that a point is outside the shape if any infinite ray from the point 
+     * crosses the outline of the shape an even number of times, otherwise
+     * it is inside. */
+    public static final int WIND_EVEN_ODD = 0;
+    
+    /** The Constant WIND_NON_ZERO indicates the winding rule that says that
+     * a point is inside the shape if every infinite ray starting from that
+     * point crosses the outline of the shape a non-zero number of times. */
+    public static final int WIND_NON_ZERO = 1;
+
+    /** The Constant SEG_MOVETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should be placed directly on the current point. */
+    public static final int SEG_MOVETO  = 0;
+    
+    /** The Constant SEG_LINETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a straight line. */
+    public static final int SEG_LINETO  = 1;
+    
+    /** The Constant SEG_QUADTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a quadratic curve. */
+    public static final int SEG_QUADTO  = 2;
+    
+    /** The Constant SEG_CUBICTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a cubic curve. */
+    public static final int SEG_CUBICTO = 3;
+    
+    /** The Constant SEG_CLOSE indicates that the previous point was the end
+     * of the shape's outline. */
+    public static final int SEG_CLOSE   = 4;
+
+    /**
+     * Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     * {@link PathIterator#WIND_NON_ZERO}.
+     * 
+     * @return the winding rule
+     */
+    public int getWindingRule();
+
+    /**
+     * Checks if this PathIterator has been completely traversed.
+     * 
+     * @return true, if this PathIterator has been completely traversed
+     */
+    public boolean isDone();
+
+    /**
+     * Tells this PathIterator to skip to the next segment.
+     */
+    public void next();
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(float[] coords);
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(double[] coords);
+
+}
+
diff --git a/awt/java/awt/geom/Point2D.java b/awt/java/awt/geom/Point2D.java
new file mode 100644
index 0000000..7719e67
--- /dev/null
+++ b/awt/java/awt/geom/Point2D.java
@@ -0,0 +1,288 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Point2D represents a point whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Point2D implements Cloneable {
+
+    /**
+     * The Class Float is the subclass of Point2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Point2D {
+
+        /** The x coordinate. */
+        public float x;
+        
+        /** The y coordinate. */
+        public float y;
+
+        /**
+         * Instantiates a new float-valued Point2D with its data 
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Float(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        /**
+         * Sets the point's coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public void setLocation(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = (float)x;
+            this.y = (float)y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Point2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Point2D {
+
+        /** The x coordinate. */
+        public double x;
+        
+        /** The y coordinate. */
+        public double y;
+
+        /**
+         * Instantiates a new double-valued Point2D with its data 
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Double(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * Instantiates a new Point2D.
+     */
+    protected Point2D() {
+    }
+
+    /**
+     * Gets the x coordinate.
+     * 
+     * @return the x coordinate
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate.
+     * 
+     * @return the y coordinate
+     */
+    public abstract double getY();
+
+    /**
+     * Sets the point's coordinates.
+     * 
+     * @param x the x coordinate
+     * @param y the y coordinate
+     */
+    public abstract void setLocation(double x, double y);
+
+    /**
+     * Sets the point's coordinates by copying them from another point.
+     * 
+     * @param p the point to copy the data from
+     */
+    public void setLocation(Point2D p) {
+        setLocation(p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the square of the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the square of the distance between the two specified points
+     */
+    public static double distanceSq(double x1, double y1, double x2, double y2) {
+        x2 -= x1;
+        y2 -= y1;
+        return x2 * x2 + y2 * y2;
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(double px, double py) {
+        return Point2D.distanceSq(getX(), getY(), px, py);
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(Point2D p) {
+        return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the distance between the two specified points
+     */
+    public static double distance(double x1, double y1, double x2, double y2) {
+        return Math.sqrt(distanceSq(x1, y1, x2, y2));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(double px, double py) {
+        return Math.sqrt(distanceSq(px, py));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(Point2D p) {
+        return Math.sqrt(distanceSq(p));
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point2D) {
+            Point2D p = (Point2D) obj;
+            return getX() == p.getX() && getY() == p.getY();
+        }
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/geom/QuadCurve2D.java b/awt/java/awt/geom/QuadCurve2D.java
new file mode 100644
index 0000000..64ea6d6
--- /dev/null
+++ b/awt/java/awt/geom/QuadCurve2D.java
@@ -0,0 +1,824 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class QuadCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by three points:
+ * a start point, an end point, and a control point.  The line from the control 
+ * point to the starting point gives the tangent to the curve at the
+ * starting point, and the line from the control point to the end point 
+ * gives the tangent to the curve at the end point.
+ */
+public abstract class QuadCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of QuadCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public float x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public float y1;
+        
+        /** The x coordinate of the control point.  */
+        public float ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public float ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public float x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Float(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx = (float)ctrlx;
+            this.ctrly = (float)ctrly;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            float ry0 = Math.min(Math.min(y1, y2), ctrly);
+            float rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            float ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of QuadCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public double x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public double y1;
+        
+        /** The x coordinate of the control point. */
+        public double ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public double ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public double x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Double(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            double ry0 = Math.min(Math.min(y1, y2), ctrly);
+            double rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            double ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /*
+     * QuadCurve2D path iterator 
+     */
+    /**
+     * The PathIterator for a Quad2D curve.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source QuadCurve2D object. */
+        QuadCurve2D c;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segment index. */
+        int index;
+
+        /**
+         * Constructs a new QuadCurve2D.Iterator for given curve and transformation
+         * 
+         * @param q - the source QuadCurve2D object
+         * @param t the AffineTransform that acts on the coordinates before 
+         * returning them (or null)
+         */
+        Iterator(QuadCurve2D q, AffineTransform t) {
+            this.c = q;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return (index > 1);
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = c.getCtrlX();
+                coords[1] = c.getCtrlY();
+                coords[2] = c.getX2();
+                coords[3] = c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = (float)c.getCtrlX();
+                coords[1] = (float)c.getCtrlY();
+                coords[2] = (float)c.getX2();
+                coords[3] = (float)c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new quadratic curve.
+     */
+    protected QuadCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the control point.
+     * 
+     * @return the x coordinate of the control point
+     */
+    public abstract double getCtrlX();
+
+    /**
+     * Gets the y coordinate of the control point.
+     * 
+     * @return y coordinate of the control point
+     */
+    public abstract double getCtrlY();
+
+    /**
+     * Gets the control point.
+     * 
+     * @return the control point
+     */
+    public abstract Point2D getCtrlPt();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2);
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param p1 the starting point of the curved segment
+     * @param cp the control point
+     * @param p2 the end point of the curved segment
+     * 
+     * @throws NullPointerException if any of the three points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
+        setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + 3.
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another QuadCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(QuadCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX(), curve.getCtrlY(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * for this curve.
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public double getFlatnessSq() {
+        return Line2D.ptSegDistSq(
+                getX1(), getY1(),
+                getX2(), getY2(),
+                getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+        return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * by reading the coordinates of the points from an array of values.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return Line2D.ptSegDistSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D.
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D
+     */
+    public double getFlatness() {
+        return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx,
+            double ctrly, double x2, double y2)
+    {
+        return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return Line2D.ptSegDist(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to this curve's control point. The data of 
+     * this curve is left unchanged.
+     * 
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(QuadCurve2D left, QuadCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data of 
+     * the source curve is left unchanged.
+     * 
+     * @param src the curve that provides the initial data
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if one of the curves is null.
+     */
+    public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx = src.getCtrlX();
+        double cy = src.getCtrlY();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data
+     * for the three curves is read and written from arrays of values in 
+     * the usual order: x1, y1, cx, cy, x2, y2.
+     *  
+     * @param src the array that gives the data values for the source curve
+     * @param srcoff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 6
+     * or if left.length < leftOff + 6 or if right.length < rightOff + 6.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcoff, double left[],
+            int leftOff, double right[], int rightOff)
+    {
+        double x1 = src[srcoff + 0];
+        double y1 = src[srcoff + 1];
+        double cx = src[srcoff + 2];
+        double cy = src[srcoff + 3];
+        double x2 = src[srcoff + 4];
+        double y2 = src[srcoff + 5];
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = cx;
+            left[leftOff + 5] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = cx2;
+            right[rightOff + 3] = cy2;
+            right[rightOff + 4] = x2;
+            right[rightOff + 5] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveQuadratic(double eqn[]) {
+        return solveQuadratic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been written by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveQuadratic(double eqn[], double res[]) {
+        return Crossing.solveQuad(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Rectangle2D.java b/awt/java/awt/geom/Rectangle2D.java
new file mode 100644
index 0000000..d33dd91
--- /dev/null
+++ b/awt/java/awt/geom/Rectangle2D.java
@@ -0,0 +1,761 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Rectangle2D represents a rectangle whose coordinates are given 
+ * with the correct precision to be used with the Graphics2D classes.
+ */
+public abstract class Rectangle2D extends RectangularShape {
+
+    /** The Constant OUT_LEFT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its left. */
+    public static final int OUT_LEFT   = 1;
+    
+    /** The Constant OUT_TOP is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_TOP    = 2;
+    
+    /** The Constant OUT_RIGHT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its right. */
+    public static final int OUT_RIGHT  = 4;
+    
+    /** The Constant OUT_BOTTOM is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_BOTTOM = 8;
+
+    /**
+     * The Class Float is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as floats (with float-level
+     * precision).
+     */
+    public static class Float extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new empty rectangle with float-precision data fields.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the specified float-precision data.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the rectangle's data to the given values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public void setRect(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = (float)r.getX();
+            this.y = (float)r.getY();
+            this.width = (float)r.getWidth();
+            this.height = (float)r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0f) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0f) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Float(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.union(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Float().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as doubles (with double-precision-level
+     * precision).
+     */
+    public static class Double extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new empty rectangle with double-precision data fields.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the given double values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Double(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst = new Rectangle2D.Double();
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dest = new Rectangle2D.Double();
+            Rectangle2D.union(this, r, dest);
+            return dest;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Double().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Iterator provides 
+     * access to the coordinates of the Rectangle2D's boundary modified 
+     * by an AffineTransform. 
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        double y;
+        
+        
+        /** The width of the rectangle. */
+        double width;
+        
+        /** The height of the rectangle. */
+        double height;
+                
+        /** The AffineTransform that is used to modify the coordinates 
+         * that are returned by the path iterator. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /**
+         * Constructs a new Rectangle2D.Iterator for given rectangle and transformation.
+         * 
+         * @param r - the source Rectangle2D object
+         * @param at - the AffineTransform object to apply to the coordinates 
+         * before returning them
+         */
+        Iterator(Rectangle2D r, AffineTransform at) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+            this.t = at;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x;
+                coords[1] = y;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = x + width;
+                    coords[1] = y;
+                    break;
+                case 2:
+                    coords[0] = x + width;
+                    coords[1] = y + height;
+                    break;
+                case 3:
+                    coords[0] = x;
+                    coords[1] = y + height;
+                    break;
+                case 4:
+                    coords[0] = x;
+                    coords[1] = y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+                type = SEG_MOVETO;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)y;
+                    break;
+                case 2:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)(y + height);
+                    break;
+                case 3:
+                    coords[0] = (float)x;
+                    coords[1] = (float)(y + height);
+                    break;
+                case 4:
+                    coords[0] = (float)x;
+                    coords[1] = (float)y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new rectangle2 d.
+     */
+    protected Rectangle2D() {
+    }
+
+    /**
+     * Sets the rectangle's location and dimension.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     */
+    public abstract void setRect(double x, double y, double width, double height);
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param x the x coordinate of the point to check
+     * @param y the y coordinate of the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public abstract int outcode(double x, double y);
+
+    /**
+     * Creates an new rectangle that is the intersection of this rectangle
+     * with the given rectangle. The resulting rectangle may be empty. 
+     * The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to intersect with this rectangle.
+     * 
+     * @return the new rectangle given by intersection.
+     */
+    public abstract Rectangle2D createIntersection(Rectangle2D r);
+
+    /**
+     * Creates an new rectangle that is the union of this rectangle
+     * with the given rectangle. The new rectangle is the smallest 
+     * rectangle which contains both this rectangle and the rectangle
+     * specified as a parameter. The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to combine with this rectangle
+     * 
+     * @return the new rectangle given by union
+     */
+    public abstract Rectangle2D createUnion(Rectangle2D r);
+
+    /**
+     * Sets the data of this rectangle to match the data of the given 
+     * rectangle.
+     * 
+     * @param r the rectangle whose data is to be copied into this rectangle's fields.
+     */
+    public void setRect(Rectangle2D r) {
+        setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRect(x, y, width, height);
+    }
+
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D)clone();
+    }
+
+    /**
+     * Determines whether any part of the line segment  between (and including) 
+     * the two given points touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param x1 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y1 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * @param x2 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y2 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * 
+     * @return true, if at least one point of the line segment between the 
+     * two points matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+        return
+            (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2) ||
+            (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2) ||
+            Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2) ||
+            Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
+    }
+
+    /**
+     * Determines whether any part of the specified line segment touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param l the line segment to test
+     * 
+     * @return true, if at least one point of the given line segment 
+     * matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(Line2D l) {
+        return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+    }
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param p the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public int outcode(Point2D p) {
+        return outcode(p.getX(), p.getY());
+    }
+
+    public boolean contains(double x, double y) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x < x2 &&
+            y1 <= y && y < y2;
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x + width > x1 && x < x2 &&
+            y + height > y1 && y < y2;
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x + width <= x2 &&
+            y1 <= y && y + height <= y2;
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the intersection of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The resulting rectangle may be empty. 
+     * 
+     * @param src1 one of the two source rectangles giving the data to intersect
+     * @param src2 one of the two source rectangles giving the data to intersect
+     * @param dst the destination object where the data of the intersection is written
+     */
+    public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.max(src1.getMinX(), src2.getMinX());
+        double y1 = Math.max(src1.getMinY(), src2.getMinY());
+        double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the union of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The union is the smallest rectangle
+     * tha completely covers the two source rectangles. 
+     * 
+     * @param src1 one of the two source rectangles giving the data
+     * @param src2 one of the two source rectangles giving the data
+     * @param dst the destination object where the data of the union is written
+     */
+    public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.min(src1.getMinX(), src2.getMinX());
+        double y1 = Math.min(src1.getMinY(), src2.getMinY());
+        double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param x the x coordinate of the new point to be covered by the rectangle
+     * @param y the y coordinate of the new point to be covered by the rectangle
+     */
+    public void add(double x, double y) {
+        double x1 = Math.min(getMinX(), x);
+        double y1 = Math.min(getMinY(), y);
+        double x2 = Math.max(getMaxX(), x);
+        double y2 = Math.max(getMaxY(), y);
+        setRect(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param p the new point to be covered by the rectangle
+     */
+    public void add(Point2D p) {
+        add(p.getX(), p.getY());
+    }
+
+    /**
+     * Enlarges the rectangle so that it covers the given rectangle.
+     * 
+     * @param r the new rectangle to be covered by this rectangle
+     */
+    public void add(Rectangle2D r) {
+        union(this, r, this);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        hash.append(getWidth());
+        hash.append(getHeight());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle2D) {
+            Rectangle2D r = (Rectangle2D)obj;
+            return
+                getX() == r.getX() &&
+                getY() == r.getY() &&
+                getWidth() == r.getWidth() &&
+                getHeight() == r.getHeight();
+        }
+        return false;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RectangularShape.java b/awt/java/awt/geom/RectangularShape.java
new file mode 100644
index 0000000..0a77dfd
--- /dev/null
+++ b/awt/java/awt/geom/RectangularShape.java
@@ -0,0 +1,276 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+/**
+ * The Class RectangularShape represents a Shape whose data is 
+ * (at least partially) described by a rectangular frame. This includes 
+ * shapes which are obviously rectangular (such as Rectangle2D) as well as
+ * shapes like Arc2D which are largely determined by the rectangle they 
+ * fit inside.
+ */
+public abstract class RectangularShape implements Shape, Cloneable {
+
+    /**
+     * Instantiates a new rectangular shape.
+     */
+    protected RectangularShape() {
+    }
+
+    /**
+     * Gets the x coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the x coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the y coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getY();
+
+    /**
+     * Gets the width of the rectangle.
+     * 
+     * @return the width of the rectangle.
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height of the rectangle.
+     * 
+     * @return the height of the rectangle.
+     */
+    public abstract double getHeight();
+
+    /**
+     * Checks if this is an empty rectangle: one with zero as its width or height.
+     * 
+     * @return true, if the width or height is empty.
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * Sets the data for the bounding rectangle in terms of double values. 
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle.
+     * @param y the y coordinate of the upper left corner of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     */
+    public abstract void setFrame(double x, double y, double w, double h);
+
+    /**
+     * Gets the minimum x value of the bounding rectangle (the x 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum x value of the bounding rectangle.
+     */
+    public double getMinX() {
+        return getX();
+    }
+
+    /**
+     * Gets the minimum y value of the bounding rectangle (the y 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum y value of the bounding rectangle.
+     */
+    public double getMinY() {
+        return getY();
+    }
+
+    /**
+     * Gets the maximum x value of the bounding rectangle (the x
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's width).
+     * 
+     * @return the maximum x value of the bounding rectangle.
+     */
+    public double getMaxX() {
+        return getX() + getWidth();
+    }
+
+    /**
+     * Gets the maximum y value of the bounding rectangle (the y
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's height).
+     * 
+     * @return the maximum y value of the bounding rectangle.
+     */
+    public double getMaxY() {
+        return getY() + getHeight();
+    }
+
+    /**
+     * Gets the x coordinate of the center of the rectangle.
+     * 
+     * @return the x coordinate of the center of the rectangle.
+     */
+    public double getCenterX() {
+        return getX() + getWidth() / 2.0;
+    }
+
+    /**
+     * Gets the y coordinate of the center of the rectangle.
+     * 
+     * @return the y coordinate of the center of the rectangle.
+     */
+    public double getCenterY() {
+        return getY() + getHeight() / 2.0;
+    }
+
+    /**
+     * Places the rectangle's size and location data in a new Rectangle2D
+     * object and returns it.
+     * 
+     * @return the bounding rectangle as a new Rectangle2D object.
+     */
+    public Rectangle2D getFrame() {
+        return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle in terms of a Point2D which gives its
+     * upper left corner and a Dimension2D object giving its width and height.
+     * 
+     * @param loc the new upper left corner coordinate.
+     * @param size the new size dimensions.
+     */
+    public void setFrame(Point2D loc, Dimension2D size) {
+        setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle to match the data contained in the 
+     * specified Rectangle2D.
+     * 
+     * @param r the rectangle that gives the new frame data.
+     */
+    public void setFrame(Rectangle2D r) {
+        setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param x1 the x coordinate of one of the corner points.
+     * @param y1 the y coordinate of one of the corner points.
+     * @param x2 the x coordinate of the other corner point.
+     * @param y2 the y coordinate of the other corner point.
+     */
+    public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
+        double rx, ry, rw, rh;
+        if (x1 < x2) {
+            rx = x1;
+            rw = x2 - x1;
+        } else {
+            rx = x2;
+            rw = x1 - x2;
+        }
+        if (y1 < y2) {
+            ry = y1;
+            rh = y2 - y1;
+        } else {
+            ry = y2;
+            rh = y1 - y2;
+        }
+        setFrame(rx, ry, rw, rh);
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param p1 one of the corner points.
+     * @param p2 the other corner point.
+     */
+    public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
+        setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param centerX the x coordinate of the center point.
+     * @param centerY the y coordinate of the center point.
+     * @param cornerX the x coordinate of one of the corner points.
+     * @param cornerY the y coordinate of one of the corner points.
+     */
+    public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
+        double width = Math.abs(cornerX - centerX);
+        double height = Math.abs(cornerY - centerY);
+        setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param center the center point.
+     * @param corner a corner point.
+     */
+    public void setFrameFromCenter(Point2D center, Point2D corner) {
+        setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
+    }
+
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        int x1 = (int)Math.floor(getMinX());
+        int y1 = (int)Math.floor(getMinY());
+        int x2 = (int)Math.ceil(getMaxX());
+        int y2 = (int)Math.ceil(getMaxY());
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RoundRectangle2D.java b/awt/java/awt/geom/RoundRectangle2D.java
new file mode 100644
index 0000000..680a146
--- /dev/null
+++ b/awt/java/awt/geom/RoundRectangle2D.java
@@ -0,0 +1,552 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RoundRectangle2D describes a rectangle with rounded 
+ * corners with high-precision data that is appropriate for geometric
+ * operations.
+ */
+public abstract class RoundRectangle2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+        
+        /** The arcwidth of the rounded corners. */
+        public float arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public float archeight;
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * the specified data values
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the data of the round rect.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public void setRoundRect(float x, float y, float width, float height, float arcwidth, float archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.arcwidth = (float)arcwidth;
+            this.archeight = (float)archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = (float)rr.getX();
+            this.y = (float)rr.getY();
+            this.width = (float)rr.getWidth();
+            this.height = (float)rr.getHeight();
+            this.arcwidth = (float)rr.getArcWidth();
+            this.archeight = (float)rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+        
+        /** The arcwidth of the rounded corners. */
+        public double arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public double archeight;
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * the specified data values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Double(double x, double y, double width, double height, double arcwidth, double archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.arcwidth = rr.getArcWidth();
+            this.archeight = rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * RoundRectangle2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a RoundRectangle2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Path for round corners generated the same way as Ellipse2D
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        double points[][] = {
+                { 0.0,  0.5, 0.0,  0.0 }, // MOVETO
+                { 1.0, -0.5, 0.0,  0.0 }, // LINETO
+                { 1.0,   -u, 0.0,  0.0,   // CUBICTO
+                  1.0,  0.0, 0.0,    u,
+                  1.0,  0.0, 0.0,  0.5 },
+                { 1.0,  0.0, 1.0, -0.5 }, // LINETO
+                { 1.0,  0.0, 1.0,   -u,   // CUBICTO
+                  1.0,   -u, 1.0,  0.0,
+                  1.0, -0.5, 1.0,  0.0 },
+                { 0.0,  0.5, 1.0,  0.0 }, // LINETO
+                { 0.0,    u, 1.0,  0.0,   // CUBICTO
+                  0.0,  0.0, 1.0,   -u,
+                  0.0,  0.0, 1.0, -0.5 },
+                { 0.0,  0.0, 0.0,  0.5 }, // LINETO
+                { 0.0,  0.0, 0.0,    u,   // CUBICTO
+                  0.0,    u, 0.0,  0.0,
+                  0.0,  0.5, 0.0,  0.0 } };
+
+        /** The segment types correspond to points array. */
+        int types[] = {
+                SEG_MOVETO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO};
+
+        /** The x coordinate of left-upper corner of the round rectangle bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the round rectangle bounds. */
+        double y;
+        
+        /** The width of the round rectangle bounds. */
+        double width;
+        
+        /** The height of the round rectangle bounds. */
+        double height;
+        
+        /** The width of arc corners of the round rectangle. */
+        double aw;
+        
+        /** The height of arc corners of the round rectangle. */
+        double ah;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new RoundRectangle2D.Iterator for given round rectangle and transformation.
+         * 
+         * @param rr - the source RoundRectangle2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(RoundRectangle2D rr, AffineTransform at) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.aw = Math.min(width, rr.getArcWidth());
+            this.ah = Math.min(height, rr.getArcHeight());
+            this.t = at;
+            if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
+                index = points.length;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > points.length;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
+                coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
+                coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+    }
+
+    /**
+     * Instantiates a new RoundRectangle2D.
+     */
+    protected RoundRectangle2D() {
+    }
+
+    /**
+     * Gets the arc width.
+     * 
+     * @return the arc width
+     */
+    public abstract double getArcWidth();
+
+    /**
+     * Gets the arc height.
+     * 
+     * @return the arc height
+     */
+    public abstract double getArcHeight();
+
+    /**
+     * Sets the data of the RoundRectangle2D.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     * @param arcWidth the arcwidth of the rounded corners
+     * @param arcHeight the archeight of the rounded corners
+     */
+    public abstract void setRoundRect(double x, double y, double width, double height,
+            double arcWidth, double arcHeight);
+
+    /**
+     * Sets the data of the RoundRectangle2D by copying the values
+     * from an existing RoundRectangle2D.
+     * 
+     * @param rr the round rectangle to copy the data from
+     * 
+     * @throws NullPointerException if rr is null
+     */
+    public void setRoundRect(RoundRectangle2D rr) {
+        setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr
+                .getArcWidth(), rr.getArcHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
+            return false;
+        }
+
+        double aw = getArcWidth() / 2.0;
+        double ah = getArcHeight() / 2.0;
+
+        double cx, cy;
+
+        if (px < rx1 + aw) {
+            cx = rx1 + aw;
+        } else
+            if (px > rx2 - aw) {
+                cx = rx2 - aw;
+            } else {
+                return true;
+            }
+
+        if (py < ry1 + ah) {
+            cy = ry1 + ah;
+        } else
+            if (py > ry2 - ah) {
+                cy = ry2 - ah;
+            } else {
+                return true;
+            }
+
+        px = (px - cx) / aw;
+        py = (py - cy) / ah;
+        return px * px + py * py <= 1.0;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
+            return false;
+        }
+
+        double cx = (x1 + x2) / 2.0;
+        double cy = (y1 + y2) / 2.0;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
new file mode 100644
index 0000000..3468474
--- /dev/null
+++ b/awt/java/awt/im/InputContext.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.AWTEvent;
+//???AWT: import java.awt.Component;
+import java.util.Locale;
+
+import org.apache.harmony.awt.im.InputMethodContext;
+
+public class InputContext {
+    protected InputContext() {
+    }
+
+    public static InputContext getInstance() {
+        return new InputMethodContext();
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+    }
+
+    public void dispose() {
+    }
+
+    public void endComposition() {
+    }
+
+    public Object getInputMethodControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void reconvert() {
+    }
+
+    //???AWT
+    /*
+    public void removeNotify(Component client) {
+    }
+    */
+
+    public boolean selectInputMethod(Locale locale) {
+        return false;
+    }
+
+    public void setCharacterSubsets(Character.Subset[] subsets) {
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodHighlight.java b/awt/java/awt/im/InputMethodHighlight.java
new file mode 100644
index 0000000..53bb20b
--- /dev/null
+++ b/awt/java/awt/im/InputMethodHighlight.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.util.Map;
+import java.awt.font.TextAttribute;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodHighlight {
+
+    public static final int RAW_TEXT = 0;
+
+    public static final int CONVERTED_TEXT = 1;
+
+    public static final InputMethodHighlight
+        UNSELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(false, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(true, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        UNSELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(false, CONVERTED_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(true, CONVERTED_TEXT);
+    
+    private boolean selected;
+    private int state;
+    private int variation;
+    private Map<TextAttribute,?> style;
+
+    public InputMethodHighlight(boolean selected, int state, int variation) {
+        this(selected, state, variation, null);
+    }
+
+    public InputMethodHighlight(boolean selected, int state,
+                                int variation, Map<java.awt.font.TextAttribute, ?> style) {
+        if ((state != RAW_TEXT) && (state != CONVERTED_TEXT)) {
+            // awt.20B=unknown input method highlight state
+            throw new IllegalArgumentException(Messages.getString("awt.20B")); //$NON-NLS-1$
+        }
+        this.selected = selected;
+        this.state = state;
+        this.variation = variation;
+        this.style = style;
+    }
+
+    public InputMethodHighlight(boolean selected, int state) {
+        this(selected, state, 0, null);
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public Map<java.awt.font.TextAttribute, ?> getStyle() {
+        return style;
+    }
+
+    public int getVariation() {
+        return variation;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodRequests.java b/awt/java/awt/im/InputMethodRequests.java
new file mode 100644
index 0000000..bdd25e6
--- /dev/null
+++ b/awt/java/awt/im/InputMethodRequests.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.Rectangle;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+public interface InputMethodRequests {
+
+    public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes);
+
+    public int getCommittedTextLength();
+
+    public int getInsertPositionOffset();
+
+    public TextHitInfo getLocationOffset(int x, int y);
+
+    public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public Rectangle getTextLocation(TextHitInfo offset);
+}
+
diff --git a/awt/java/awt/im/InputSubset.java b/awt/java/awt/im/InputSubset.java
new file mode 100644
index 0000000..02a1049
--- /dev/null
+++ b/awt/java/awt/im/InputSubset.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+public final class InputSubset extends Character.Subset {
+
+    public static final InputSubset LATIN = new InputSubset("LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        LATIN_DIGITS = new InputSubset("LATIN_DIGITS"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        TRADITIONAL_HANZI = new InputSubset("TRADITIONAL_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        SIMPLIFIED_HANZI = new InputSubset("SIMPLIFIED_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset KANJI = new InputSubset("KANJI"); //$NON-NLS-1$
+
+    public static final InputSubset HANJA = new InputSubset("HANJA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        HALFWIDTH_KATAKANA = new InputSubset("HALFWIDTH_KATAKANA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_LATIN = new InputSubset("FULLWIDTH_LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_DIGITS = new InputSubset("FULLWIDTH_DIGITS"); //$NON-NLS-1$
+
+    private InputSubset(String name) {
+        super(name);
+    }
+}
+
diff --git a/awt/java/awt/im/spi/InputMethod.java b/awt/java/awt/im/spi/InputMethod.java
new file mode 100644
index 0000000..2c98c46
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethod.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTEvent;
+import java.awt.Rectangle;
+import java.util.Locale;
+
+public interface InputMethod {
+
+    public void activate();
+
+    public void deactivate(boolean isTemporary);
+
+    public void dispatchEvent(AWTEvent event);
+
+    public void dispose();
+
+    public void endComposition();
+
+    public Object getControlObject();
+
+    public Locale getLocale();
+
+    public void hideWindows();
+
+    public boolean isCompositionEnabled();
+
+    public void notifyClientWindowChange(Rectangle bounds);
+
+    public void reconvert();
+
+    public void removeNotify();
+
+    public void setCharacterSubsets(Character.Subset[] subsets);
+
+    public void setCompositionEnabled(boolean enable);
+
+    public void setInputMethodContext(InputMethodContext context);
+
+    public boolean setLocale(Locale locale);
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodContext.java b/awt/java/awt/im/spi/InputMethodContext.java
new file mode 100644
index 0000000..ca33e87
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodContext.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+//???AWT: import java.awt.Window;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodRequests;
+import java.text.AttributedCharacterIterator;
+//???AWT: import javax.swing.JFrame;
+
+public interface InputMethodContext extends InputMethodRequests {
+
+//    ???AWT: public JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
+
+//    ???AWT: public Window createInputMethodWindow(String title, boolean attachToInputContext);
+
+    public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition);
+
+    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
+
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodDescriptor.java b/awt/java/awt/im/spi/InputMethodDescriptor.java
new file mode 100644
index 0000000..3068cac
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodDescriptor.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.util.Locale;
+
+public interface InputMethodDescriptor {
+
+    public Locale[] getAvailableLocales() throws AWTException;
+
+    public InputMethod createInputMethod() throws Exception;
+
+    public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage);
+
+    public Image getInputMethodIcon(Locale inputLocale);
+
+    public boolean hasDynamicLocaleList();
+
+}
+
diff --git a/awt/java/awt/image/AffineTransformOp.java b/awt/java/awt/image/AffineTransformOp.java
new file mode 100644
index 0000000..546837a
--- /dev/null
+++ b/awt/java/awt/image/AffineTransformOp.java
@@ -0,0 +1,617 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky, Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AffineTransform class translates coordinates from 2D coordinates 
+ * in the source image or Raster to 2D coordinates in the destination 
+ * image or Raster using Affine transformation. The number of bands in 
+ * the source Raster should equal to the number of bands in the destination
+ * Raster.
+ */
+public class AffineTransformOp implements BufferedImageOp, RasterOp {
+    
+    /** 
+     * The Constant TYPE_NEAREST_NEIGHBOR indicates nearest-neighbor 
+     * interpolation type. 
+     */
+    public static final int TYPE_NEAREST_NEIGHBOR = 1;
+    
+    /** 
+     * The Constant TYPE_BILINEAR indicates bilinear interpolation type. 
+     */
+    public static final int TYPE_BILINEAR = 2;
+    
+    /** The Constant TYPE_BICUBIC indicates bicubic interpolation type. */
+    public static final int TYPE_BICUBIC = 3;
+
+    /** The i type. */
+    private int iType; // interpolation type
+    
+    /** The at. */
+    private AffineTransform at;
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO - uncomment
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and RenderingHints object which defines 
+     * the interpolation type.
+     * 
+     * @param xform the AffineTransform.
+     * @param hints the RenderingHints object which defines 
+     * the interpolation type.
+     */
+    public AffineTransformOp(AffineTransform xform, RenderingHints hints) {
+        this(xform, TYPE_NEAREST_NEIGHBOR);
+        this.hints = hints;
+
+        if (hints != null) {
+            Object hint = hints.get(RenderingHints.KEY_INTERPOLATION);
+            if (hint != null) {
+                // Nearest neighbor is default
+                if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+                    this.iType = TYPE_BILINEAR;
+                } else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+                    this.iType = TYPE_BICUBIC;
+                }
+            } else {
+                hint = hints.get(RenderingHints.KEY_RENDERING);
+                // Determine from rendering quality
+                if (hint == RenderingHints.VALUE_RENDER_QUALITY) {
+                    this.iType = TYPE_BILINEAR;
+                // For speed use nearest neighbor
+                }
+            }
+        }
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and a specified interpolation type from the 
+     * list of predefined interpolation types.
+     * 
+     * @param xform the AffineTransform.
+     * @param interp the one of predefined interpolation types:
+     * TYPE_NEAREST_NEIGHBOR, TYPE_BILINEAR, or TYPE_BICUBIC.
+     */
+    public AffineTransformOp(AffineTransform xform, int interp) {
+        if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
+            // awt.24F=Unable to invert transform {0}
+            throw new ImagingOpException(Messages.getString("awt.24F", xform)); //$NON-NLS-1$
+        }
+
+        this.at = (AffineTransform) xform.clone();
+
+        if (interp != TYPE_NEAREST_NEIGHBOR && interp != TYPE_BILINEAR && interp != TYPE_BICUBIC) {
+            // awt.250=Unknown interpolation type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.250", interp)); //$NON-NLS-1$
+        }
+
+        this.iType = interp;
+    }
+
+    /**
+     * Gets the interpolation type.
+     * 
+     * @return the interpolation type
+     */
+    public final int getInterpolationType() {
+        return iType;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        if (hints == null) {
+            Object value = null;
+
+            switch (iType) {
+                case TYPE_NEAREST_NEIGHBOR:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+                    break;
+                case TYPE_BILINEAR:
+                    value = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+                    break;
+                case TYPE_BICUBIC:
+                    value = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+                    break;
+                default:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+            }
+
+            hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, value);
+        }
+
+        return hints;
+    }
+
+    /**
+     * Gets the affine transform associated with this AffineTransformOp.
+     * 
+     * @return the AffineTransform.
+     */
+    public final AffineTransform getTransform() {
+        return (AffineTransform) at.clone();
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        return at.transform(srcPt, dstPt);
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        // We position source raster to (0,0) even if it is translated child raster.
+        // This means that we need only width and height of the src
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        float[] corners = {
+            0, 0,
+            width, 0,
+            width, height,
+            0, height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        Rectangle2D newBounds = getBounds2D(src);
+
+        // Destination image should include (0,0) + positive part
+        // of the area bounded by newBounds (in source coordinate system).
+        double dstWidth = newBounds.getX() + newBounds.getWidth();
+        double dstHeight = newBounds.getY() + newBounds.getHeight();
+
+        if (dstWidth <= 0 || dstHeight <= 0) {
+            // awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
+            throw new RasterFormatException(
+                    Messages.getString("awt.251", dstWidth, dstHeight)); //$NON-NLS-1$
+        }
+
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                    destCM.isAlphaPremultiplied(),
+                    null
+            );
+        }
+
+        ColorModel cm = src.getColorModel();
+
+        // Interpolation other than NN doesn't make any sense for index color
+        if (iType != TYPE_NEAREST_NEIGHBOR && cm instanceof IndexColorModel) {
+            return new BufferedImage((int)dstWidth, (int)dstHeight, BufferedImage.TYPE_INT_ARGB);
+        }
+
+        // OK, we can get source color model
+        return new BufferedImage(cm,
+                src.getRaster().createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                cm.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        // Here approach is other then in createCompatibleDestImage -
+        // destination should include only
+        // transformed image, but not (0,0) in source coordinate system
+
+        Rectangle2D newBounds = getBounds2D(src);
+        return src.createCompatibleWritableRaster(
+                (int) newBounds.getX(), (int) newBounds.getY(),
+                (int) newBounds.getWidth(), (int)newBounds.getHeight()
+        );
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (
+                srcCM instanceof IndexColorModel &&
+                (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)
+        ) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                   !(
+                     (src.getType() == BufferedImage.TYPE_INT_RGB ||
+                      src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                     (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                      dst.getType() == BufferedImage.TYPE_INT_ARGB)
+                    )
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            //throw new ImagingOpException ("Unable to transform source");
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.253=Different number of bands in source and destination
+            throw new IllegalArgumentException(Messages.getString("awt.253")); //$NON-NLS-1$
+        }
+
+        if (slowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+        //    throw new ImagingOpException("Unable to transform source");
+        }
+
+        return dst;
+    }
+
+    // TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize;
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize;
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    // No IPP function for this type
+                    if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = sppsm1.getNumBands();
+                    // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            sppsm1.getDataType() != sppsm2.getDataType() ||
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) {
+                        channels = 4;
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;
+
+                    srcStride = sppsm1.getScanlineStride() * dataTypeSize;
+                    dstStride = sppsm2.getScanlineStride() * dataTypeSize;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        double m00 = at.getScaleX();
+        double m01 = at.getShearX();
+        double m02 = at.getTranslateX();
+        double m10 = at.getShearY();
+        double m11 = at.getScaleY();
+        double m12 = at.getTranslateY();
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippAffineTransform(
+            m00, m01, m02, m10, m11, m12,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            iType, channels, skipChannel, offsets);
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        // TODO: make correct interpolation
+        // TODO: what if there are different data types?
+
+        Rectangle srcBounds = src.getBounds();
+        Rectangle dstBounds = dst.getBounds();
+        Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
+        Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);
+
+        AffineTransform inv = null;
+        try {
+             inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return -1;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int minSrcX = srcBounds.x;
+        int minSrcY = srcBounds.y;
+        int maxSrcX = srcBounds.x + srcBounds.width;
+        int maxSrcY = srcBounds.y + srcBounds.height;
+
+        int minX = bounds.x + dstBounds.x;
+        int minY = bounds.y + dstBounds.y;
+        int maxX = minX + bounds.width;
+        int maxY = minY + bounds.height;
+
+        int hx = (int)(m[0] * 256);
+        int hy = (int)(m[1] * 256);
+        int vx = (int)(m[2] * 256);
+        int vy = (int)(m[3] * 256);
+        int sx = (int)(m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
+        int sy = (int)(m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;
+
+        vx -= hx * bounds.width;
+        vy -= hy * bounds.width;
+
+        if (src.getTransferType() == dst.getTransferType()) {
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        Object val = src.getDataElements(px , py , null);
+                        dst.setDataElements(x, y, val);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        } else {
+            float pixel[] = null;
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        pixel = src.getPixel(px, py, pixel);
+                        dst.setPixel(x, y, pixel);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Ipp affine transform.
+     * 
+     * @param m00 the m00
+     * @param m01 the m01
+     * @param m02 the m02
+     * @param m10 the m10
+     * @param m11 the m11
+     * @param m12 the m12
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param iType the i type
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippAffineTransform(
+            double m00, double m01,
+            double m02, double m10,
+            double m11, double m12,
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int iType, int channels, boolean skipChannel,
+            int offsets[]);
+}
\ No newline at end of file
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..f4933db
--- /dev/null
+++ b/awt/java/awt/image/AreaAveragingScaleFilter.java
@@ -0,0 +1,253 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+
+/**
+ * The AreaAveragingScaleFilter class scales the source image using
+ * area averaging algorithm. This algorithm provides a source image
+ * with a new image containing the resampled image. 
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
+
+    /** The Constant rgbCM. */
+    private static final ColorModel rgbCM = ColorModel.getRGBdefault();
+    
+    /** The Constant averagingFlags. */
+    private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT |
+            ImageConsumer.COMPLETESCANLINES);
+
+    /** The reset. */
+    private boolean reset = true;   // Flag for used superclass filter
+    
+    /** The inited. */
+    private boolean inited = false; // All data inited
+
+    /** The sum_r. */
+    private int sum_r[]; // Array for average Red samples
+    
+    /** The sum_g. */
+    private int sum_g[]; // Array for average Green samples
+    
+    /** The sum_b. */
+    private int sum_b[]; // Array for average Blue samples
+    
+    /** The sum_a. */
+    private int sum_a[]; // Array for average Alpha samples
+
+    /** The buff. */
+    private int buff[];  // Stride buffer
+    
+    /** The avg factor. */
+    private int avgFactor;  // Global averaging factor
+
+    /** The cached dy. */
+    private int cachedDY;      // Cached number of the destination scanline 
+    
+    /** The cached dv rest. */
+    private int cachedDVRest;  // Cached value of rest src scanlines for sum 
+                               // pixel samples 
+                               // Because data if transfering by whole scanlines
+                               // we are caching only Y coordinate values
+    
+    /**
+     * Instantiates a new AreaAveragingScaleFilter object which scales
+     * a source image with the specified width and height.
+     * 
+     * @param width the scaled width of the image.
+     * @param height the scaled height of the image.
+     */
+    public AreaAveragingScaleFilter(int width, int height) {
+        super(width, height);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setHints(int hints) {
+        super.setHints(hints);
+        reset = ((hints & averagingFlags) != averagingFlags);
+    }
+
+    /**
+     * This method implements the Area Averaging Scale filter.
+     * The description of algorithm is presented in Java API Specification.
+     * 
+     * Arrays sum_r, sum_g, sum_b, sum_a have length equals width of destination
+     * image. In each array's element is accumulating pixel's component values,
+     * proportional to the area which source pixels will occupy in destination
+     * image. Then that values will divide by Global averaging
+     * factor (area of the destination image) for receiving
+     * average values of destination pixels.
+     * 
+     * @param x - Src pixels X coordinate
+     * @param y - Src pixels Y coordinate
+     * @param w - width of the area of Src pixels
+     * @param h - height of the area of Src pixels
+     * @param model - Color Model of Src pixels
+     * @param pixels - array of Src pixels
+     * @param off - offset into the Src pixels array
+     * @param scansize - length of scanline in the pixels array
+     */
+    private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off, int scansize){
+        if(!inited){
+            initialize();
+        }
+
+        int srcX, srcY, dx, dy;
+        int svRest, dvRest, shRest, dhRest, vDif, hDif;
+
+        if(y == 0){
+            dy = 0;
+            dvRest = srcHeight;
+        }else{
+            dy = cachedDY;
+            dvRest = cachedDVRest;
+        }
+
+        srcY = y;
+        svRest = destHeight;
+
+        int srcOff = off;
+        while (srcY < y + h) {
+            if (svRest < dvRest) {
+                vDif = svRest;
+            } else {
+                vDif = dvRest;
+            }
+
+            srcX = 0;
+            dx = 0;
+            shRest = destWidth;
+            dhRest = srcWidth;
+            while (srcX < w) {
+                if (shRest < dhRest) {
+                    hDif = shRest;
+                } else {
+                    hDif = dhRest;
+                }
+                int avg = hDif * vDif; // calculation of contribution factor
+
+                int rgb, pix;
+                if (pixels instanceof int[]) {
+                    pix = ((int[]) pixels)[srcOff + srcX];
+                } else {
+                    pix = ((byte[]) pixels)[srcOff + srcX] & 0xff;
+                }
+
+                rgb = model.getRGB(pix);
+                int a = rgb >>> 24;
+                int r = (rgb >> 16) & 0xff;
+                int g = (rgb >> 8) & 0xff;
+                int b = rgb & 0xff;
+
+                // accumulating pixel's component values
+                sum_a[dx] += a * avg;
+                sum_r[dx] += r * avg;
+                sum_g[dx] += g * avg;
+                sum_b[dx] += b * avg;
+
+                shRest -= hDif;
+                dhRest -= hDif;
+
+                if (shRest == 0) {
+                    srcX++;
+                    shRest = destWidth;
+                }
+
+                if (dhRest == 0) {
+                    dx++;
+                    dhRest = srcWidth;
+                }
+            }
+
+            svRest -= vDif;
+            dvRest -= vDif;
+
+            if (svRest == 0) {
+                svRest = destHeight;
+                srcY++;
+                srcOff += scansize;
+            }
+
+            if (dvRest == 0) {
+                // averaging destination pixel's values
+                for(int i = 0; i < destWidth; i++){
+                    int a = (sum_a[i] / avgFactor) & 0xff;
+                    int r = (sum_r[i] / avgFactor) & 0xff;
+                    int g = (sum_g[i] / avgFactor) & 0xff;
+                    int b = (sum_b[i] / avgFactor) & 0xff;
+                    int frgb = (a << 24) | (r << 16) | (g << 8) | b;
+                    buff[i] = frgb;
+                }
+                consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0,
+                        destWidth);
+                dy++;
+                dvRest = srcHeight;
+                Arrays.fill(sum_a, 0);
+                Arrays.fill(sum_r, 0);
+                Arrays.fill(sum_g, 0);
+                Arrays.fill(sum_b, 0);
+            }
+
+        }
+
+        cachedDY = dy;
+        cachedDVRest = dvRest;
+
+    }
+
+    /**
+     * Initialization of the auxiliary data.
+     */
+    private void initialize(){
+
+        sum_a = new int[destWidth]; 
+        sum_r = new int[destWidth]; 
+        sum_g = new int[destWidth]; 
+        sum_b = new int[destWidth]; 
+
+        buff = new int[destWidth];  
+        outpixbuf = buff;
+        avgFactor = srcWidth * srcHeight; 
+
+        inited = true;
+    }
+}
+
diff --git a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
new file mode 100644
index 0000000..ce85ddd
--- /dev/null
+++ b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
@@ -0,0 +1,153 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.gl.GLVolatileImage;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class not part of public API. It useful for receiving package private
+ * data from other packages.
+ */
+class AwtImageBackdoorAccessorImpl extends AwtImageBackdoorAccessor {
+
+    static void init(){
+        inst = new AwtImageBackdoorAccessorImpl();
+    }
+
+    @Override
+    public Surface getImageSurface(Image image) {
+        if (image instanceof BufferedImage){
+            return ((BufferedImage)image).getImageSurface();
+        } else if (image instanceof GLVolatileImage){
+            return ((GLVolatileImage)image).getImageSurface();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isGrayPallete(IndexColorModel icm){
+        return icm.isGrayPallete();
+    }
+
+    @Override
+    public Object getData(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        } else if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        } else if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        } else if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        } else if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        } else if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        } else {
+            // awt.235=Wrong Data Buffer type : {0}
+            throw new IllegalArgumentException(Messages.getString("awt.235", //$NON-NLS-1$
+                    db.getClass()));
+        }
+    }
+
+    @Override
+    public int[] getDataInt(DataBuffer db) {
+        if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public byte[] getDataByte(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataShort(DataBuffer db) {
+        if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataUShort(DataBuffer db) {
+        if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public double[] getDataDouble(DataBuffer db) {
+        if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public float[] getDataFloat(DataBuffer db) {
+        if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public void addDataBufferListener(DataBuffer db, DataBufferListener listener) {
+        db.addDataBufferListener(listener);
+    }
+
+    @Override
+    public void removeDataBufferListener(DataBuffer db) {
+        db.removeDataBufferListener();
+    }
+
+    @Override
+    public void validate(DataBuffer db) {
+        db.validate();
+    }
+
+    @Override
+    public void releaseData(DataBuffer db) {
+        db.releaseData();
+    }
+}
diff --git a/awt/java/awt/image/BandCombineOp.java b/awt/java/awt/image/BandCombineOp.java
new file mode 100644
index 0000000..cd77a21
--- /dev/null
+++ b/awt/java/awt/image/BandCombineOp.java
@@ -0,0 +1,610 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 20, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandCombineOp class translates coordinates from 
+ * coordinates in the source Raster to coordinates in 
+ * the destination Raster by an arbitrary linear combination 
+ * of the bands in a source Raster, using a specified matrix.
+ * The number of bands in the matrix should equal to 
+ * the number of bands in the source Raster plus 1.
+ */
+public class BandCombineOp implements RasterOp {
+    
+    /** The Constant offsets3c. */
+    static final int offsets3c[] = {16, 8, 0};
+    
+    /** The Constant offsets4ac. */
+    static final int offsets4ac[] = {16, 8, 0, 24};
+    
+    /** The Constant masks3c. */
+    static final int masks3c[] = {0xFF0000, 0xFF00, 0xFF};
+    
+    /** The Constant masks4ac. */
+    static final int masks4ac[] = {0xFF0000, 0xFF00, 0xFF, 0xFF000000};
+    
+    /** The Constant piOffsets. */
+    private static final int piOffsets[] = {0, 1, 2};
+    
+    /** The Constant piInvOffsets. */
+    private static final int piInvOffsets[] = {2, 1, 0};
+
+    /** The Constant TYPE_BYTE3C. */
+    private static final int TYPE_BYTE3C = 0;
+    
+    /** The Constant TYPE_BYTE4AC. */
+    private static final int TYPE_BYTE4AC = 1;
+    
+    /** The Constant TYPE_USHORT3C. */
+    private static final int TYPE_USHORT3C = 2;
+    
+    /** The Constant TYPE_SHORT3C. */
+    private static final int TYPE_SHORT3C = 3;
+
+    /** The mx width. */
+    private int mxWidth;
+    
+    /** The mx height. */
+    private int mxHeight;
+    
+    /** The matrix. */
+    private float matrix[][];
+    
+    /** The r hints. */
+    private RenderingHints rHints;
+
+    static {
+        // XXX - todo
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new BandCombineOp object with the specified
+     * matrix.
+     * 
+     * @param matrix the specified matrix for band combining.
+     * @param hints the RenderingHints.
+     */
+    public BandCombineOp(float matrix[][], RenderingHints hints) {
+        this.mxHeight = matrix.length;
+        this.mxWidth = matrix[0].length;
+        this.matrix = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++){
+            System.arraycopy(matrix[i], 0, this.matrix[i], 0, mxWidth);
+        }
+
+        this.rHints = hints;
+    }
+
+    public final RenderingHints getRenderingHints(){
+        return this.rHints;
+    }
+
+    /**
+     * Gets the matrix associated with this BandCombineOp object.
+     * 
+     * @return the matrix associated with this BandCombineOp object.
+     */
+    public final float[][] getMatrix() {
+        float res[][] = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++) {
+            System.arraycopy(matrix[i], 0, res[i], 0, mxWidth);
+        }
+
+        return res;
+    }
+
+    public final Point2D getPoint2D (Point2D srcPoint, Point2D dstPoint) {
+        if (dstPoint == null) {
+            dstPoint = new Point2D.Float();
+        }
+
+        dstPoint.setLocation(srcPoint);
+        return dstPoint;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src){
+        return src.getBounds();
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        int numBands = src.getNumBands();
+        if (mxWidth != numBands && mxWidth != (numBands+1) || numBands != mxHeight) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+    }
+
+    public WritableRaster filter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        if (mxWidth != numBands && mxWidth != (numBands+1)) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(
+                    Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (dst.getNumBands() != mxHeight) {
+            // awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.255", //$NON-NLS-1$
+                    new Object[]{dst.getNumBands(), mxWidth, mxHeight}));
+        }
+
+        // XXX - todo
+        //if (ippFilter(src, dst) != 0)
+        if (verySlowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * The Class SampleModelInfo.
+     */
+    private static final class SampleModelInfo {
+        
+        /** The channels. */
+        int channels;
+        
+        /** The channels order. */
+        int channelsOrder[];
+        
+        /** The stride. */
+        int stride;
+    }
+
+    /**
+     * Check sample model.
+     * 
+     * @param sm the sm
+     * 
+     * @return the sample model info
+     */
+    private final SampleModelInfo checkSampleModel(SampleModel sm) {
+        SampleModelInfo ret = new SampleModelInfo();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            // Check PixelInterleavedSampleModel
+            if (sm.getDataType() != DataBuffer.TYPE_BYTE) {
+                return null;
+            }
+
+            ret.channels = sm.getNumBands();
+            ret.stride = ((ComponentSampleModel) sm).getScanlineStride();
+            ret.channelsOrder = ((ComponentSampleModel) sm).getBandOffsets();
+
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) sm;
+
+            ret.channels = sppsm1.getNumBands();
+            if (sppsm1.getDataType() != DataBuffer.TYPE_INT) {
+                return null;
+            }
+
+            // Check sample models
+            for (int i=0; i<ret.channels; i++) {
+                if (sppsm1.getSampleSize(i) != 8) {
+                    return null;
+                }
+            }
+
+            ret.channelsOrder = new int[ret.channels];
+            int bitOffsets[] = sppsm1.getBitOffsets();
+            for (int i=0; i<ret.channels; i++) {
+                if (bitOffsets[i] % 8 != 0) {
+                    return null;
+                }
+
+                ret.channelsOrder[i] = bitOffsets[i] / 8;
+            }
+
+            ret.channels = 4;
+            ret.stride = sppsm1.getScanlineStride() * 4;
+        } else {
+            return null;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst) {
+        int res = 0;
+
+        SampleModelInfo srcInfo, dstInfo;
+        int offsets[] = null;
+
+        srcInfo = checkSampleModel(src.getSampleModel());
+        dstInfo = checkSampleModel(dst.getSampleModel());
+        if (srcInfo == null || dstInfo == null) {
+            return verySlowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+                    dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        int rmxWidth = (srcInfo.channels+1); // width of the reordered matrix
+        float reorderedMatrix[] = new float[rmxWidth*dstInfo.channels];
+        for (int j=0; j<dstInfo.channels; j++) {
+            if (j >= dstInfo.channelsOrder.length) {
+                continue;
+            }
+
+            for (int i=0; i<srcInfo.channels; i++) {
+                if (i >= srcInfo.channelsOrder.length) {
+                    break;
+                }
+
+                reorderedMatrix[dstInfo.channelsOrder[j]*rmxWidth + srcInfo.channelsOrder[i]] =
+                        matrix[j][i];
+            }
+            if (mxWidth == rmxWidth) {
+                reorderedMatrix[(dstInfo.channelsOrder[j]+1)*rmxWidth - 1] = matrix[j][mxWidth-1];
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        simpleCombineBands(
+                srcData, src.getWidth(), src.getHeight(), srcInfo.stride, srcInfo.channels,
+                dstData, dstInfo.stride, dstInfo.channels,
+                reorderedMatrix, offsets
+        );
+
+        return res;
+    }
+
+    /**
+     * Very slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int verySlowFilter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        int srcMinX = src.getMinX();
+        int srcY = src.getMinY();
+
+        int dstMinX = dst.getMinX();
+        int dstY = dst.getMinY();
+
+        int dX = src.getWidth();//< dst.getWidth() ? src.getWidth() : dst.getWidth();
+        int dY = src.getHeight();//< dst.getHeight() ? src.getHeight() : dst.getHeight();
+
+        float sample;
+        int srcPixels[] = new int[numBands*dX*dY];
+        int dstPixels[] = new int[mxHeight*dX*dY];
+
+        srcPixels = src.getPixels(srcMinX, srcY, dX, dY, srcPixels);
+
+        if (numBands == mxWidth) {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) sample;
+                }
+            }
+        } else {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) (sample + matrix[dstB][numBands]);
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstY, dX, dY, dstPixels);
+
+        return 0;
+    }
+
+    //TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst) {
+        boolean invertChannels;
+        boolean inPlace = (src == dst);
+        int type;
+        int srcStride, dstStride;
+        int offsets[] = null;
+
+        int srcBands = src.getNumBands();
+        int dstBands = dst.getNumBands();
+
+        if (
+                dstBands != 3 ||
+                (srcBands != 3 &&
+                !(srcBands == 4 &&
+                  matrix[0][3] == 0 &&
+                  matrix[1][3] == 0 &&
+                  matrix[2][3] == 0)
+                )
+        ) {
+            return slowFilter(src, dst);
+        }
+
+        SampleModel srcSM = src.getSampleModel();
+        SampleModel dstSM = dst.getSampleModel();
+
+        if (
+                srcSM instanceof SinglePixelPackedSampleModel &&
+                dstSM instanceof SinglePixelPackedSampleModel
+        ) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+            if (
+                    sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                    sppsm2.getDataType() != DataBuffer.TYPE_INT
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            // Check sample models
+            if (
+                    !Arrays.equals(sppsm2.getBitOffsets(), offsets3c) ||
+                    !Arrays.equals(sppsm2.getBitMasks(), masks3c)
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (srcBands == 3) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets3c) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks3c)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            } else if (srcBands == 4) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets4ac) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks4ac)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            }
+
+            type = TYPE_BYTE4AC;
+            invertChannels = true;
+
+            srcStride = sppsm1.getScanlineStride() * 4;
+            dstStride = sppsm2.getScanlineStride() * 4;
+        } else if (
+            srcSM instanceof PixelInterleavedSampleModel &&
+            dstSM instanceof PixelInterleavedSampleModel
+        ) {
+            if (srcBands != 3) {
+                return slowFilter(src, dst);
+            }
+
+            int srcDataType = srcSM.getDataType();
+
+            switch (srcDataType) {
+                case DataBuffer.TYPE_BYTE:
+                    type = TYPE_BYTE3C;
+                    break;
+                case DataBuffer.TYPE_USHORT:
+                    type = TYPE_USHORT3C;
+                    break;
+                case DataBuffer.TYPE_SHORT:
+                    type = TYPE_SHORT3C;
+                    break;
+                default:
+                    return slowFilter(src, dst);
+            }
+
+            // Check PixelInterleavedSampleModel
+            PixelInterleavedSampleModel pism1 = (PixelInterleavedSampleModel) srcSM;
+            PixelInterleavedSampleModel pism2 = (PixelInterleavedSampleModel) dstSM;
+
+            if (
+                    srcDataType != pism2.getDataType() ||
+                    pism1.getPixelStride() != 3 ||
+                    pism2.getPixelStride() != 3 ||
+                    !Arrays.equals(pism1.getBandOffsets(), pism2.getBandOffsets())
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (Arrays.equals(pism1.getBandOffsets(), piInvOffsets)) {
+                invertChannels = true;
+            } else if (Arrays.equals(pism1.getBandOffsets(), piOffsets)) {
+                invertChannels = false;
+            } else {
+                return slowFilter(src, dst);
+            }
+
+            int dataTypeSize = DataBuffer.getDataTypeSize(srcDataType) / 8;
+
+            srcStride = pism1.getScanlineStride() * dataTypeSize;
+            dstStride = pism2.getScanlineStride() * dataTypeSize;
+        } else { // XXX - todo - IPP allows support for planar data also
+            return slowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+               dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        float ippMatrix[] = new float[12];
+
+        if (invertChannels) {
+            // IPP treats big endian integers like BGR, so we have to
+            // swap columns 1 and 3 and rows 1 and 3
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[2-i][2];
+                ippMatrix[i*4+1] = matrix[2-i][1];
+                ippMatrix[i*4+2] = matrix[2-i][0];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[2-i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[2-i][4];
+                }
+            }
+        } else {
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[i][0];
+                ippMatrix[i*4+1] = matrix[i][1];
+                ippMatrix[i*4+2] = matrix[i][2];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[i][4];
+                }
+            }
+        }
+
+        return ippColorTwist(
+                srcData, src.getWidth(), src.getHeight(), srcStride,
+                dstData, dst.getWidth(), dst.getHeight(), dstStride,
+                ippMatrix, type, offsets, inPlace);
+    }
+
+    /**
+     * Ipp color twist.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dstData the dst data
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param ippMatrix the ipp matrix
+     * @param type the type
+     * @param offsets the offsets
+     * @param inPlace the in place
+     * 
+     * @return the int
+     */
+    private final native int ippColorTwist(
+            Object srcData, int srcWidth, int srcHeight, int srcStride,
+            Object dstData, int dstWidth, int dstHeight, int dstStride,
+            float ippMatrix[], int type, int offsets[], boolean inPlace
+    );
+
+    /**
+     * Simple combine bands.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param srcChannels the src channels
+     * @param dstData the dst data
+     * @param dstStride the dst stride
+     * @param dstChannels the dst channels
+     * @param m the m
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private final native int simpleCombineBands(
+            Object srcData, int srcWidth, int srcHeight, int srcStride, int srcChannels,
+            Object dstData, int dstStride, int dstChannels,
+            float m[], int offsets[]
+    );
+}
diff --git a/awt/java/awt/image/BandedSampleModel.java b/awt/java/awt/image/BandedSampleModel.java
new file mode 100644
index 0000000..392e44c
--- /dev/null
+++ b/awt/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,426 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandedSampleModel class provides samples of pixels in an image 
+ * which is stored in a band interleaved method. Each pixel's sample 
+ * takes one data element of the DataBuffer. The pixel stride for a 
+ * BandedSampleModel is one. 
+ */
+public final class BandedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Creates the indices.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createIndices(int numBands) {
+        int indices[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            indices[i] = i;
+        }
+        return indices;
+    }
+
+    /**
+     * Creates the offsets.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createOffsets(int numBands) {
+        int offsets[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            offsets[i] = 0;
+        }
+        return offsets;
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param numBands the number of bands.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int numBands) {
+        this(dataType, w, h, w, BandedSampleModel.createIndices(numBands),
+                BandedSampleModel.createOffsets(numBands));
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bankIndices the array of the bank indecies.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
+            int bankIndices[], int bandOffsets[]) {
+        super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new BandedSampleModel(dataType, w, h, w, bankIndices,
+                bandOffsets);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int[] bands) {
+        if (bands.length > numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new BandedSampleModel(dataType, width, height, scanlineStride,
+                indices, offsets);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte bdata[];
+
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+        }
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT: {
+            short sdata[];
+
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+        }
+        case DataBuffer.TYPE_INT: {
+            int idata[];
+
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fdata[];
+
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double ddata[];
+
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+        }
+
+        return obj;
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x55;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, bdata[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sdata[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, idata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, fdata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, ddata[i], data);
+            }
+            break;
+        }
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x +
+                       bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/BufferStrategy.java b/awt/java/awt/image/BufferStrategy.java
new file mode 100644
index 0000000..e0508f0
--- /dev/null
+++ b/awt/java/awt/image/BufferStrategy.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.BufferCapabilities;
+import java.awt.Graphics;
+
+/**
+ * The BufferStrategy abstract class provides an opportunity 
+ * to organize the buffers for a Canvas or Window. The BufferStrategy
+ * implementation depends on hardware and software limitations.
+ * These limitations are detectible through the capabilities 
+ * object which can be obtained by the GraphicsConfiguration of the Canvas 
+ * or Window.
+ */
+public abstract class BufferStrategy {
+
+    /**
+     * Returns true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics. 
+     * 
+     * @return true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics, false otherwise.
+     */
+    public abstract boolean contentsLost();
+
+    /**
+     * Returns true if the drawing buffer is restored from a lost state. 
+     * 
+     * @return true if the drawing buffer is restored from a lost state,
+     * false otherwise.
+     */
+    public abstract boolean contentsRestored();
+
+    /**
+     * Gets the BufferCapabilities of BufferStrategy.
+     * 
+     * @return the BufferCapabilities of BufferStrategy.
+     */
+    public abstract BufferCapabilities getCapabilities();
+
+    /**
+     * Gets the Graphics object to use to draw to the buffer.
+     * 
+     * @return the Graphics object to use to draw to the buffer.
+     */
+    public abstract Graphics getDrawGraphics();
+
+    /**
+     * Shows the next available buffer.
+     */
+    public abstract void show();
+
+}
diff --git a/awt/java/awt/image/BufferedImage.java b/awt/java/awt/image/BufferedImage.java
new file mode 100644
index 0000000..d305d66
--- /dev/null
+++ b/awt/java/awt/image/BufferedImage.java
@@ -0,0 +1,931 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.BufferedImageSource;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The BufferedImage class describes an Image which contains a buffer 
+ * of image data and includes a ColorModel and a Raster for this data.
+ * This class provides methods for obtaining and setting the Raster
+ * and for manipulating the ColorModel parameters.
+ */
+public class BufferedImage extends 
+Image implements WritableRenderedImage, Transparency{
+
+    /** 
+     * The Constant TYPE_CUSTOM indicates that Image type 
+     * is unknown. 
+     */
+    public static final int TYPE_CUSTOM = 0;
+
+    /** 
+     * The Constant TYPE_INT_RGB indicates an image with 
+     * 8 bit RGB color components, it has a DirectColorModel 
+     * without alpha. 
+     */
+    public static final int TYPE_INT_RGB = 1;
+
+    /** 
+     * The Constant TYPE_INT_ARGB indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha. 
+     */
+    public static final int TYPE_INT_ARGB = 2;
+
+    /** 
+     * The Constant TYPE_INT_ARGB_PRE indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha, and image data is premultiplied by alpha. 
+     */
+    public static final int TYPE_INT_ARGB_PRE = 3;
+
+    /** 
+     * The Constant TYPE_INT_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red). There is no 
+     * alpha. The image has a DirectColorModel. 
+     */
+    public static final int TYPE_INT_BGR = 4;
+
+    /** 
+     * The Constant TYPE_3BYTE_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red stored in 3 bytes). 
+     * There is no alpha. The image has a ComponentColorModel. 
+     */
+    public static final int TYPE_3BYTE_BGR = 5;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte of alpha.
+     * It has a ComponentColorModel with alpha.  
+     */
+    public static final int TYPE_4BYTE_ABGR = 6;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR_PRE indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte 
+     * for alpha. The image has a ComponentColorModel with alpha. 
+     * The color data is premultiplied with alpha.
+     */
+    public static final int TYPE_4BYTE_ABGR_PRE = 7;
+
+    /** 
+     * The Constant TYPE_USHORT_565_RGB indicates an image with 
+     * 565 RGB color components (5-bits red, 6-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_565_RGB = 8;
+
+    /** 
+     * The Constant TYPE_USHORT_555_RGB indicates an image with 
+     * 555 RGB color components (5-bits red, 5-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_555_RGB = 9;
+
+    /** 
+     * The Constant TYPE_BYTE_GRAY indicates a unsigned byte 
+     * image. This image has a ComponentColorModel with 
+     * a CS_GRAY ColorSpace. 
+     */
+    public static final int TYPE_BYTE_GRAY = 10;
+
+    /** 
+     * The Constant TYPE_USHORT_GRAY indicates an unsigned short 
+     * image. This image has a ComponentColorModel with a CS_GRAY 
+     * ColorSpace. 
+     */
+    public static final int TYPE_USHORT_GRAY = 11;
+
+    /** 
+     * The Constant TYPE_BYTE_BINARY indicates an opaque byte-packed
+     * 1, 2 or 4 bit image. The image has an IndexColorModel without 
+     * alpha.  
+     */
+    public static final int TYPE_BYTE_BINARY = 12;
+
+    /** 
+     * The Constant TYPE_BYTE_INDEXED indicates an indexed byte image. 
+     */
+    public static final int TYPE_BYTE_INDEXED = 13;
+
+    /** The Constant ALPHA_MASK. */
+    private static final int ALPHA_MASK = 0xff000000;
+
+    /** The Constant RED_MASK. */
+    private static final int RED_MASK = 0x00ff0000;
+
+    /** The Constant GREEN_MASK. */
+    private static final int GREEN_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_MASK. */
+    private static final int BLUE_MASK = 0x000000ff;
+
+    /** The Constant RED_BGR_MASK. */
+    private static final int RED_BGR_MASK = 0x000000ff;
+
+    /** The Constant GREEN_BGR_MASK. */
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_BGR_MASK. */
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+
+    /** The Constant RED_565_MASK. */
+    private static final int RED_565_MASK = 0xf800;
+
+    /** The Constant GREEN_565_MASK. */
+    private static final int GREEN_565_MASK = 0x07e0;
+
+    /** The Constant BLUE_565_MASK. */
+    private static final int BLUE_565_MASK = 0x001f;
+
+    /** The Constant RED_555_MASK. */
+    private static final int RED_555_MASK = 0x7c00;
+
+    /** The Constant GREEN_555_MASK. */
+    private static final int GREEN_555_MASK = 0x03e0;
+
+    /** The Constant BLUE_555_MASK. */
+    private static final int BLUE_555_MASK = 0x001f;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The raster. */
+    private final WritableRaster raster;
+
+    /** The image type. */
+    private final int imageType;
+
+    /** The properties. */
+    private Hashtable<?, ?> properties;
+
+    // Surface of the Buffered Image - used for blitting one Buffered Image 
+    // on the other one or on the Component
+    /** The image surf. */
+    private final ImageSurface imageSurf;
+
+    /**
+     * Instantiates a new BufferedImage with the specified ColorModel,
+     * and WritableRaster objects. The Raster data can be
+     * be divided or multiplied by alpha. It depends on the 
+     * alphaPremultiplied state in the ColorModel.
+     * 
+     * @param cm the ColorModel of the new image.
+     * @param raster the WritableRaster of the new image.
+     * @param isRasterPremultiplied if true the data of the specified
+     * Raster is premultiplied by alpha.
+     * @param properties the properties of new Image.
+     */
+    public BufferedImage(ColorModel cm, WritableRaster raster,
+            boolean isRasterPremultiplied, Hashtable<?, ?> properties) {
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+
+        if (raster.getMinX() != 0 || raster.getMinY() != 0) {
+            // awt.228=minX or minY of this raster not equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.228")); //$NON-NLS-1$
+        }
+
+        this.cm  = cm;
+        this.raster = raster;
+        this.properties = properties;
+
+        coerceData(isRasterPremultiplied);
+
+        imageType = Surface.getType(cm, raster);
+
+        imageSurf = createImageSurface(imageType);
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * predefined image type (TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED) 
+     * and the specified IndexColorModel.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     * @param cm the specified IndexColorModel.
+     */
+    public BufferedImage(int width, int height, int imageType,
+            IndexColorModel cm) {
+        switch (imageType) {
+        case TYPE_BYTE_BINARY:
+            if (cm.hasAlpha()) {
+                // awt.227=This image type can't have alpha
+                throw new IllegalArgumentException(Messages.getString("awt.227")); //$NON-NLS-1$
+            }
+            int pixel_bits = 0;
+            int mapSize = cm.getMapSize();
+            if (mapSize <= 2) {
+                pixel_bits = 1;
+            } else if (mapSize <= 4) {
+                pixel_bits = 2;
+            } else if (mapSize <= 16) {
+                pixel_bits = 4;
+            } else {
+                // awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
+                throw new IllegalArgumentException(Messages.getString("awt.221")); //$NON-NLS-1$
+            }
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, pixel_bits, null);
+            break;
+
+        case TYPE_BYTE_INDEXED:
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+            break;
+
+        default:
+            // awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
+            throw new IllegalArgumentException(Messages.getString("awt.222")); //$NON-NLS-1$
+
+        }
+
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.223=The imageType is not compatible with ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.223")); //$NON-NLS-1$
+        }
+
+        this.cm = cm;
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * and predefined image type.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     */
+    public BufferedImage(int width, int height, int imageType) {
+
+        switch (imageType) {
+        case TYPE_INT_RGB:
+            cm = new DirectColorModel(24, RED_MASK, GREEN_MASK, BLUE_MASK);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB:
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB_PRE:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    32,
+                    RED_MASK,
+                    GREEN_MASK,
+                    BLUE_MASK,
+                    ALPHA_MASK,
+                    true,
+                    DataBuffer.TYPE_INT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_BGR:
+            cm = new DirectColorModel(24,
+                    RED_BGR_MASK,
+                    GREEN_BGR_MASK,
+                    BLUE_BGR_MASK);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_3BYTE_BGR: {
+            int bits[] = { 8, 8, 8 };
+            int bandOffsets[] = { 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 3, 3, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    false, 
+                    Transparency.TRANSLUCENT, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR_PRE: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    true, 
+                    Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_USHORT_565_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    16,
+                    RED_565_MASK,
+                    GREEN_565_MASK,
+                    BLUE_565_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_USHORT_555_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    15,
+                    RED_555_MASK,
+                    GREEN_555_MASK,
+                    BLUE_555_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_BYTE_GRAY: {
+            int bits[] = { 8 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_USHORT_GRAY: {
+            int bits[] = { 16 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_USHORT);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_BYTE_BINARY: {
+            int colorMap[] = { 0, 0xffffff };
+            cm = new IndexColorModel(1, 2, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, 1, null);
+            }
+            break;
+
+        case TYPE_BYTE_INDEXED: {
+            int colorMap[] = new int[256];
+            int i = 0;
+            for (int r = 0; r < 256; r += 51) {
+                for (int g = 0; g < 256; g += 51) {
+                    for (int b = 0; b < 256; b += 51) {
+                        colorMap[i] = (r << 16) | (g << 8) | b;
+                        i++;
+                    }
+                }
+            }
+
+            int gray = 0x12;
+            for (; i < 256; i++, gray += 6) {
+                colorMap[i] = (gray << 16) | (gray << 8) | gray;
+            }
+            cm = new IndexColorModel(8, 256, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+
+            }
+            break;
+        default:
+            // awt.224=Unknown image type
+            throw new IllegalArgumentException(Messages.getString("awt.224")); //$NON-NLS-1$
+        }
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        return getProperty(name);
+    }
+
+    public Object getProperty(String name) {
+        if(name == null) {
+            // awt.225=Property name is null
+            throw new NullPointerException(Messages.getString("awt.225")); //$NON-NLS-1$
+        }
+        if (properties == null) {
+            return Image.UndefinedProperty;
+        }
+        Object property = properties.get(name);
+        if (property == null) {
+            property = Image.UndefinedProperty;
+        }
+        return property;
+    }
+
+    public WritableRaster copyData(WritableRaster outRaster) {
+        if (outRaster == null) {
+            outRaster = Raster.createWritableRaster(raster.getSampleModel(),
+                    new Point(raster.getSampleModelTranslateX(),
+                            raster.getSampleModelTranslateY()));
+        }
+
+        int w = outRaster.getWidth();
+        int h = outRaster.getHeight();
+        int minX = outRaster.getMinX();
+        int minY = outRaster.getMinY();
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outRaster.setDataElements(minX, minY, w, h, data);
+
+        return outRaster;
+    }
+
+    public Raster getData(Rectangle rect) {
+        int minX = rect.x;
+        int minY = rect.y;
+        int w = rect.width;
+        int h = rect.height;
+
+        SampleModel sm = raster.getSampleModel();
+        SampleModel nsm = sm.createCompatibleSampleModel(w, h);
+        WritableRaster outr = Raster.createWritableRaster(nsm, 
+                rect.getLocation());
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+        return outr;
+    }
+
+    public Vector<RenderedImage> getSources() {
+        return null;
+    }
+
+    public String[] getPropertyNames() {
+        if (properties == null) {
+            return null;
+        }
+        Vector<String> v = new Vector<String>();
+        for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
+            try {
+                v.add((String) e.nextElement());
+            } catch (ClassCastException ex) {
+            }
+        }
+        int size = v.size();
+        if (size > 0) {
+            String names[] = new String[size];
+            for (int i = 0; i < size; i++) {
+                names[i] = v.elementAt(i);
+            }
+            return names;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string representation of this BufferedImage object.
+     * 
+     * @return the string representation of this BufferedImage object.
+     */
+    @Override
+    public String toString() {
+        return "BufferedImage@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
+            ": type = " + imageType + " " + cm + " " + raster; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    public WritableRaster getWritableTile(int tileX, int tileY) {
+        return raster;
+    }
+
+    /**
+     * Gets the WritableRaster of this BufferedImage.
+     * 
+     * @return the WritableRaster of this BufferedImage.
+     */
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Gets a WritableRaster object which contains the alpha channel of 
+     * BufferedImage object with ColorModel objects that supports 
+     * a separate alpha channel such as ComponentColorModel 
+     * or DirectColorModel.
+     * 
+     * @return the WritableRaster object which contains the alpha 
+     * channel of this BufferedImage. 
+     */
+    public WritableRaster getAlphaRaster() {
+        return cm.getAlphaRaster(raster);
+    }
+
+    public void removeTileObserver(TileObserver to) {
+    }
+
+    public void addTileObserver(TileObserver to) {
+    }
+
+    public SampleModel getSampleModel() {
+        return raster.getSampleModel();
+    }
+
+    public void setData(Raster r) {
+
+        Rectangle from = r.getBounds();
+        Rectangle to = raster.getBounds();
+        Rectangle intersection = to.intersection(from);
+
+        int minX = intersection.x;
+        int minY = intersection.y;
+        int w = intersection.width;
+        int h = intersection.height;
+
+        Object data = null;
+
+        data = r.getDataElements(minX, minY, w, h, data);
+        raster.setDataElements(minX, minY, w, h, data);
+    }
+
+    public Raster getTile(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return raster;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public Raster getData() {
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        WritableRaster outr = Raster.createWritableRaster(
+                raster.getSampleModel(),
+                new Point(raster.getSampleModelTranslateX(),
+                raster.getSampleModelTranslateY()));
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+
+        return outr;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return new BufferedImageSource(this, properties);
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        return raster.getWidth();
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        return raster.getHeight();
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    /**
+     * Gets the rectangular area of this BufferedImage as a subimage.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width of the subimage.
+     * @param h the height of the subimage.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage getSubimage(int x, int y, int w, int h) {
+        WritableRaster wr = raster.createWritableChild(x, y, w, h, 0, 0, null);
+        return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);
+    }
+
+    public Point[] getWritableTileIndices() {
+        Point points[] = new Point[1];
+        points[0] = new Point(0, 0);
+        return points;
+    }
+
+    /**
+     * Creates the Graphics2D object which allows to draw into 
+     * this BufferedImage.
+     * 
+     * @return the graphics2D object.
+     */
+    public Graphics2D createGraphics() {
+        GraphicsEnvironment ge = 
+            GraphicsEnvironment.getLocalGraphicsEnvironment();
+        //return ge.createGraphics(this);
+        //???AWT hack, FIXME
+        //return AndroidGraphics2D.getInstance();
+        //throw new RuntimeException("Not implemented!");
+        return null;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    /**
+     * Coerces the data to achieve the state which is specified by 
+     * the isAlphaPremultiplied variable. 
+     * 
+     * @param isAlphaPremultiplied the is alpha premultiplied state.
+     */
+    public void coerceData(boolean isAlphaPremultiplied) {
+        if (cm.hasAlpha() && 
+                cm.isAlphaPremultiplied() != isAlphaPremultiplied) {
+            cm = cm.coerceData(raster, isAlphaPremultiplied);
+        }
+    }
+
+    /**
+     * Gets an array of colors in the TYPE_INT_ARGB color model and 
+     * default sRGB colorspace of the specified area of this
+     * BufferedImage. The result array is composed by the following
+     * algirithm:
+     * <p> 
+     * pixel   = rgbArray[offset + (y-startY)*scansize + (x-startX)]
+     * 
+     * @param startX the start X area coordinate. 
+     * @param startY the start Y area coordinate.
+     * @param w the width of the area. 
+     * @param h the height of the area.
+     * @param rgbArray the result array will be stored to this array.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     * 
+     * @return an array of colors for the specified area.
+     */
+    public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        if (rgbArray == null) {
+            rgbArray = new int[offset + h * scansize];
+        }
+
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                rgbArray[i] = cm.getRGB(raster.getDataElements(x, y, null));
+            }
+        }
+        return rgbArray;
+    }
+
+    /**
+     * Sets RGB values from the specified array to the specified
+     * BufferedImage area. The pixels are in the default RGB color model 
+     * (TYPE_INT_ARGB) and default sRGB color space.
+     * 
+     * @param startX the start X coordinate.
+     * @param startY the start Y coordinate.
+     * @param w the width of the BufferedImage area.
+     * @param h the height of the BufferedImage area.
+     * @param rgbArray the array of RGB values.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     */
+    public void setRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                raster.setDataElements(x, y, 
+                        cm.getDataElements(rgbArray[i], null));
+            }
+        }
+    }
+
+    /**
+     * Sets a the specified RGB value to the specified pixel of
+     * this BufferedImage. The pixel should be in the default 
+     * RGB color model (TYPE_INT_ARGB) and default sRGB color space. 
+     *  
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param rgb the RGB value to be set.
+     */
+    public synchronized void setRGB(int x, int y, int rgb) {
+        raster.setDataElements(x, y, cm.getDataElements(rgb, null));
+    }
+
+    public boolean isTileWritable(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return true;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public void releaseWritableTile(int tileX, int tileY) {
+    }
+
+    /**
+     * Gets a color in the TYPE_INT_ARGB color model and default 
+     * sRGB colorspace of the specified pixel. 
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * 
+     * @return the color of the specified pixel in the TYPE_INT_ARGB 
+     * color model and default sRGB colorspace. 
+     */
+    public int getRGB(int x, int y) {
+        return cm.getRGB(raster.getDataElements(x, y, null));
+    }
+
+    /**
+     * Returnes true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     * 
+     * @return true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     */
+    public boolean isAlphaPremultiplied() {
+        return cm.isAlphaPremultiplied();
+    }
+
+    public boolean hasTileWriters() {
+        return true;
+    }
+
+    @Override
+    public void flush() {
+        imageSurf.dispose();
+    }
+
+    public int getWidth() {
+        return raster.getWidth();
+    }
+
+    /**
+     * Gets the image type.
+     * 
+     * @return the image type.
+     */
+    public int getType() {
+        return imageType;
+    }
+
+    public int getTileWidth() {
+        return raster.getWidth();
+    }
+
+    public int getTileHeight() {
+        return raster.getHeight();
+    }
+
+    public int getTileGridYOffset() {
+        return raster.getSampleModelTranslateY();
+    }
+
+    public int getTileGridXOffset() {
+        return raster.getSampleModelTranslateX();
+    }
+
+    public int getNumYTiles() {
+        return 1;
+    }
+
+    public int getNumXTiles() {
+        return 1;
+    }
+
+    public int getMinY() {
+        return raster.getMinY();
+    }
+
+    public int getMinX() {
+        return raster.getMinX();
+    }
+
+    public int getMinTileY() {
+        return 0;
+    }
+
+    public int getMinTileX() {
+        return 0;
+    }
+
+    public int getHeight() {
+        return raster.getHeight();
+    }
+
+    /**
+     * Creates the image surface.
+     * 
+     * @param type the type
+     * 
+     * @return the image surface
+     */
+    private ImageSurface createImageSurface(int type) {
+        return new ImageSurface(getColorModel(), getRaster(), type);
+    }
+
+    /**
+     * Gets the image surface.
+     * 
+     * @return the image surface
+     */
+    ImageSurface getImageSurface() {
+        return imageSurf;
+    }
+
+    public int getTransparency() {
+        return cm.getTransparency();
+    }
+}
+
diff --git a/awt/java/awt/image/BufferedImageFilter.java b/awt/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 0000000..44b3c2e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,375 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BufferedImageFilter class provides filtering operations to 
+ * the BufferedImage objects using operators which implement
+ * BufferedImageOp interface.
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable {
+    
+    /** The Constant accessor. */
+    private static final AwtImageBackdoorAccessor accessor = AwtImageBackdoorAccessor.getInstance();
+
+    /** The op. */
+    private BufferedImageOp op;
+
+    /** The raster. */
+    private WritableRaster raster;
+
+    /** The i data. */
+    private int iData[];
+    
+    /** The b data. */
+    private byte bData[];
+
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The forced rgb. */
+    private boolean forcedRGB = false;
+    
+    /** The transfer type. */
+    private int transferType = DataBuffer.TYPE_UNDEFINED;
+
+    /**
+     * Instantiates a new BufferedImageFilter with the specified
+     * BufferedImageOp operator.
+     * 
+     * @param op the specified BufferedImageOp operator.
+     * 
+     * @throws NullPointerException if BufferedImageOp is null.
+     */
+    public BufferedImageFilter(BufferedImageOp op) {
+        if (op == null) {
+            throw new NullPointerException(Messages.getString("awt.05")); //$NON-NLS-1$
+        }
+        this.op = op;
+    }
+
+    /**
+     * Gets the BufferedImageOp operator associated with this 
+     * BufferedImageFilter object.
+     * 
+     * @return the BufferedImageOp associated with this 
+     * BufferedImageFilter object.
+     */
+    public BufferedImageOp getBufferedImageOp() {
+        return op;
+    }
+
+    @Override
+    public void setDimensions(int width, int height) {
+        this.width = width;
+        this.height = height;
+        // Stop image consuming if no pixels expected.
+        if (width <= 0 || height <= 0) {
+            consumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            reset();
+        }
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if (this.cm != null && this.cm != model && raster != null) {
+            forceRGB();
+        } else {
+            this.cm = model;
+        }
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y, int
+            w, int h,
+            ColorModel model, byte[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, true);
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, int[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, false);
+    }
+
+    @Override
+    public void imageComplete(int status) {
+        if (status == STATICIMAGEDONE || status == SINGLEFRAMEDONE) {
+            BufferedImage bim = new BufferedImage(cm, raster, cm.isAlphaPremultiplied, null);
+            bim = op.filter(bim, null);
+            DataBuffer dstDb = bim.getRaster().getDataBuffer();
+            ColorModel dstCm = bim.getColorModel();
+            int dstW = bim.getWidth();
+            int dstH = bim.getHeight();
+
+            consumer.setDimensions(dstW, dstH);
+
+            if (dstDb.getDataType() == DataBuffer.TYPE_INT) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataInt(dstDb), 0, dstW);
+            } else if (dstDb.getDataType() == DataBuffer.TYPE_BYTE) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataByte(dstDb), 0, dstW);
+            } else {
+                int dstData[] = bim.getRGB(0, 0, dstW, dstH, null, 0, dstW);
+                dstCm = ColorModel.getRGBdefault();
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, dstData, 0, dstW);
+            }
+        } else if (status == IMAGEERROR || status == IMAGEABORTED) {
+            reset();
+        }
+
+        consumer.imageComplete(status);
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scansize the scansize
+     * @param isByteData the is byte data
+     */
+    private void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, Object pixels,
+            int off, int scansize, boolean isByteData
+    ) {
+        // Check bounds
+        // Need to copy only the pixels that will fit into the destination area
+        if (x < 0) {
+            w -= x;
+            off += x;
+            x = 0;
+        }
+
+        if (y < 0) {
+            h -= y;
+            off += y * scansize;
+            y = 0;
+        }
+
+        if (x + w > width) {
+            w = width - x;
+        }
+
+        if (y + h > height) {
+            h = height - y;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        // Check model
+        if (this.cm == null) {
+            setColorModel(model);
+        } else if (model == null) {
+            model = this.cm;
+        } else if (!model.equals(this.cm)) {
+            forceRGB();
+        }
+
+        boolean canArraycopy;
+        // Process pixels
+        switch(transferType) {
+            case DataBuffer.TYPE_UNDEFINED: {
+                if (isByteData) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                    createRaster(transferType);
+                    //bData = new byte[width*height];
+                    canArraycopy = !forcedRGB;
+                    break;
+                }
+                transferType = DataBuffer.TYPE_INT;
+                createRaster(transferType);
+                //iData = new int[width*height];
+                canArraycopy = !forcedRGB || model.equals(ColorModel.getRGBdefault());
+                break;
+            } // And proceed to copy the pixels
+            case DataBuffer.TYPE_INT: {
+                if (isByteData) { // There are int data already but the new data are bytes
+                    forceRGB();
+                    canArraycopy = false;
+                    break;
+                } else if (!forcedRGB || model.equals(ColorModel.getRGBdefault())) {
+                    canArraycopy = true;
+                    break;
+                } // Else fallback to the RGB conversion
+            }
+            case DataBuffer.TYPE_BYTE: {
+                if (isByteData && !forcedRGB) {
+                    canArraycopy = true;
+                    break;
+                }
+
+                // RGB conversion
+                canArraycopy = false;
+                break;
+            } default: {
+                throw new IllegalStateException(Messages.getString("awt.06")); //$NON-NLS-1$
+            }
+        }
+
+        off += x;
+        int maxOffset = off + h * scansize;
+        int dstOffset = x + y * width;
+
+        if (canArraycopy) {
+            Object dstArray = isByteData ? (Object) bData : (Object) iData;
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                System.arraycopy(pixels, off, dstArray, dstOffset, w);
+            }
+        } else {
+            // RGB conversion
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                int srcPos = off;
+                int dstPos = dstOffset;
+                int maxDstPos = dstOffset + w;
+                for (; dstPos < maxDstPos; dstPos++, srcPos++) {
+                    iData[dstPos] = model.getRGB(
+                            isByteData ?
+                            ((byte[])pixels)[srcPos] :
+                            ((int[])pixels)[srcPos]
+                    );
+                }
+            }
+        }
+    }
+
+    /**
+     * Force rgb.
+     */
+    private void forceRGB() {
+        if (!forcedRGB) {
+            forcedRGB = true;
+            int size = width*height;
+            int rgbData[] = new int[size];
+
+            if (bData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(bData[i]);
+                }
+            } else if (iData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(iData[i]);
+                }
+            }
+
+            cm = ColorModel.getRGBdefault();
+            DataBufferInt db = new DataBufferInt(rgbData, size);
+            int masks[] = new int[] {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};
+            raster = Raster.createPackedRaster(db, width, height, width, masks, null);
+            iData = accessor.getDataInt(db);
+            bData = null;
+            transferType = DataBuffer.TYPE_INT;
+        }
+    }
+
+    /**
+     * Reset.
+     */
+    private void reset() {
+        width = 0;
+        height = 0;
+        forcedRGB = false;
+        cm = null;
+        iData = null;
+        bData = null;
+        transferType = DataBuffer.TYPE_UNDEFINED;
+        raster = null;
+    }
+
+    /**
+     * Creates the raster.
+     * 
+     * @param dataType the data type
+     */
+    private void createRaster(int dataType) {
+        boolean createdValidBuffer = false;
+        try{
+            raster = cm.createCompatibleWritableRaster(width, height);
+            int rasterType = raster.getDataBuffer().getDataType();
+            if (rasterType == dataType) {
+                switch (rasterType) {
+                    case DataBuffer.TYPE_INT: {
+                        iData = accessor.getDataInt(raster.getDataBuffer());
+                        if (iData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    case DataBuffer.TYPE_BYTE: {
+                        bData = accessor.getDataByte(raster.getDataBuffer());
+                        if (bData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    default:
+                        createdValidBuffer = false;
+                }
+
+                if(cm == ColorModel.getRGBdefault()){
+                    forcedRGB = true;
+                }
+            } else {
+                createdValidBuffer = false;
+            }
+        } catch(Exception e) {
+            createdValidBuffer = false;
+        }
+
+        if (createdValidBuffer == false) {
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            iData = accessor.getDataInt(raster.getDataBuffer());
+            bData = null;
+            forcedRGB = true;
+        }
+    }
+}
diff --git a/awt/java/awt/image/BufferedImageOp.java b/awt/java/awt/image/BufferedImageOp.java
new file mode 100644
index 0000000..85b9f4e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageOp.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The BufferedImageOp interface provides methods for performing transformations
+ * from source data to destination data for BufferedImage objects. An object
+ * implementing this interface can be passed into a BufferedImageFilter 
+ * to operate on a BufferedImage.
+ */
+public interface BufferedImageOp {
+    
+    /**
+     * Creates a destination image with the specified BufferedImage and
+     * ColorModel; this destination image is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source BufferedImage.
+     * @param destCM the destination ColorModel.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM);
+
+    /**
+     * Performs a filter operation on the source BufferedImage and stores 
+     * the resulting BufferedImage to the destination BufferedImage. If 
+     * the destination BufferedImage is null, a BufferedImage with an 
+     * appropriate ColorModel is created.
+     * 
+     * @param src the source BufferedImage.
+     * @param dest the destination BufferedImage, where the result is stored.
+     * 
+     * @return the filtered BufferedImage.
+     */
+    public BufferedImage filter(BufferedImage src, BufferedImage dest);
+
+    /**
+     * Gets the bounds of filtered image.
+     * 
+     * @param src the source BufferedImage to be filtered.
+     * 
+     * @return the rectangle bounds of filtered image.
+     */
+    public Rectangle2D getBounds2D(BufferedImage src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source image. 
+     * 
+     * @param srcPt the point of the source image.
+     * @param dstPt the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
+
+    /**
+     * Gets the RenderingHints of the BufferedImageOp.
+     * 
+     * @return the RenderingHints of the BufferedImageOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/ByteLookupTable.java b/awt/java/awt/image/ByteLookupTable.java
new file mode 100644
index 0000000..043b533
--- /dev/null
+++ b/awt/java/awt/image/ByteLookupTable.java
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ByteLookupTable class provides functionality for lookup operations, 
+ * and is defined by an input byte array for bands or components of 
+ * image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an array of unsigned bytes.
+ */
+public class ByteLookupTable extends LookupTable {
+    
+    /** The data. */
+    private byte data[][];
+    
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array which represents the lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes.
+     */
+    public ByteLookupTable(int offset, byte[] data) {
+        super(offset, 1);
+        if (data.length < 1)
+            throw new IllegalArgumentException("Length of data should not be less then one");
+        this.data = new byte[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array of arrays which represents the lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes array for each band.
+     */
+    public ByteLookupTable(int offset, byte[][] data) {
+        super(offset, data.length);
+        this.data = new byte[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ByteLookupTable object. If 
+     * this ByteLookupTable object has one byte array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ByteLookupTable object.
+     */
+    public final byte[][] getTable() {
+        // Returns data by reference
+        return data;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    /**
+     * Returns a byte array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ByteLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the byte array of translated samples of a pixel.
+     */
+    public byte[] lookupPixel(byte[] src, byte[] dst) {
+        if (dst == null) {
+            dst = new byte[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/ColorConvertOp.java b/awt/java/awt/image/ColorConvertOp.java
new file mode 100644
index 0000000..6d503d7
--- /dev/null
+++ b/awt/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,711 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ */  
+package java.awt.image;
+
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorConvertOp class converts the pixels of the data in the
+ * source image with the specified ColorSpace objects or an array 
+ * of ICC_Profile objects. The result pixels are scaled to the precision
+ * of the destination image.
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp {
+    // Unused but required by interfaces
+    /** The rendering hints. */
+    RenderingHints renderingHints;
+        
+    // Sequence consisting of ColorSpace and ICC_Profile elements
+    /** The conversion sequence. */
+    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for null
+    
+    // Not null if ColorConvertOp is constructed from the array of ICC profiles
+    /** The mid profiles. */
+    private ICC_Profile midProfiles[];   
+
+    /** The cc. */
+    private final ColorConverter cc = new ColorConverter();
+    
+    /** The t creator. */
+    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
+    
+    /** The is icc. */
+    private boolean isICC = true;
+    
+    
+    // Cached ICC_Transform
+    /**
+     * The Class ICC_TransfomCreator.
+     */
+    private class ICC_TransfomCreator {
+        
+        /** The transform. */
+        private ICC_Transform transform;
+        
+        /** The max components. */
+        private int maxComponents;
+        
+        /**
+         * For the full ICC case.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * @param convSeq the conv seq
+         * 
+         * @return the transform
+         */
+        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
+            if (transform != null &&
+               src == transform.getSrc() && 
+               dst == transform.getDst()) {
+                return transform;
+            }
+            
+            int length = convSeq.length;
+            int srcFlg = 0, dstFlg = 0;
+            
+            if (length == 0 || src != convSeq[0]) {
+                if (src != null) {
+                    srcFlg = 1; // need src profile
+                }
+            }
+            if (length == 0 || dst != convSeq[length-1]) {
+                if (dst != null) {
+                    dstFlg = 1; // need dst profile
+                }
+            }
+            
+            ICC_Profile profiles[];
+            int nProfiles = length + srcFlg + dstFlg;
+            if (nProfiles == length) {
+                profiles = convSeq;
+            } else {
+                profiles = new ICC_Profile[nProfiles];
+                int pos = 0;
+                if (srcFlg != 0) {
+                    profiles[pos++] = src;
+                }
+                for (int i=0; i<length; i++) {
+                    profiles[pos++] = convSeq[i];
+                }
+                if (dstFlg != 0) {
+                    profiles[pos++] = dst;
+                }
+            }
+            
+            return transform = new ICC_Transform(profiles);
+        }
+        
+        /**
+         * Used only when there are non-ICC color spaces.
+         * Returns sequence of non-ICC color spaces and ICC transforms
+         * made from src, dst and conversionSequence.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * 
+         * @return the sequence
+         */
+        public Object[] getSequence(Object src, Object dst) {
+            ArrayList<Object> profiles = new ArrayList<Object>(10);
+            ArrayList<Object> sequence = new ArrayList<Object>(10);         
+
+            // We need this profile anyway
+            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+
+            Object conversionFirst = null, conversionLast = null;
+            int conversionLength = conversionSequence.length;
+            if (conversionLength > 0) {
+                conversionFirst = conversionSequence[0];
+                conversionLast = conversionSequence[conversionLength-1];
+            }
+
+            boolean iccSequenceStarted = false;
+            
+            if (src != conversionFirst && src != null) {
+                if (src instanceof ICC_Profile) {
+                    profiles.add(src);
+                    iccSequenceStarted = true;
+                } else {
+                    profiles.add(xyzProfile);
+                    sequence.add(src); // Add non-ICC color space to the sequence
+                } 
+            } else {
+                profiles.add(xyzProfile);
+            }
+            
+            for (int i=0; i<conversionLength; i++) {
+                if (conversionSequence[i] instanceof ICC_Profile) {
+                    profiles.add(conversionSequence[i]);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                    
+                    // Eliminate same profiles if there are any
+                    // (e.g. xyzProfile may occur several times)
+                    Object prev = profiles.get(0);
+                    for (int k=1; k<profiles.size(); k++) {                     
+                        if (prev == profiles.get(k)) {
+                            k--;
+                            profiles.remove(k);
+                        }
+                        prev = profiles.get(k);
+                    }
+                    
+                    // If only one profile left we skip the transform -
+                    // it can be only CIEXYZ
+                    if (profiles.size() > 1) {
+                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+
+                        // Add non-ICC color space to the sequence
+                        sequence.add(conversionSequence[i]);
+                    }
+                    
+                    profiles.clear();
+                    profiles.add(xyzProfile);
+                    iccSequenceStarted = false; // Sequence of ICC profiles is processed
+                } else { // Add non-ICC color space to the sequence
+                    sequence.add(conversionSequence[i]); 
+                }               
+            }
+            
+            if (dst != conversionLast && dst != null) { // Add last profile if needed
+                if (dst instanceof ICC_Profile) {
+                    profiles.add(dst);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                } else {
+                    sequence.add(dst); // Add last non-ICC color space to the sequence
+                }
+            }
+            
+            if (iccSequenceStarted) { // Make last transform if needed
+                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+                if (dst != null && !(dst instanceof ICC_Profile)) {
+                    sequence.add(dst); // Add last non-ICC color space to the
+                                        // sequence
+                }
+            }
+
+            // Calculate max number of components
+            // This number will be used for memory allocation
+            maxComponents = 0;
+            Object o;           
+            for (int i=0, size = sequence.size(); i<size; i++) {
+                o = sequence.get(i);
+                if (o instanceof ICC_Transform) {
+                    ICC_Transform t = (ICC_Transform) o; 
+                    maxComponents = 
+                        (maxComponents > t.getNumInputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumInputChannels() + 1;
+                    maxComponents = 
+                        (maxComponents > t.getNumOutputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumOutputChannels() + 1;
+                } else {
+                    ColorSpace cs = (ColorSpace) o;
+                    maxComponents = 
+                        (maxComponents > cs.getNumComponents() + 1) ?
+                            maxComponents : 
+                            cs.getNumComponents() + 1;
+                }               
+            }
+            
+            return sequence.toArray();
+        }
+    }
+    
+    /**
+     * Instantiates a new ColorConvertOp object using two specified
+     * ColorSpace objects.
+     * 
+     * @param srcCS the source ColorSpace.
+     * @param dstCS the destination ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
+        if (srcCS == null || dstCS == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+        
+        boolean srcICC = srcCS instanceof ICC_ColorSpace;
+        boolean dstICC = dstCS instanceof ICC_ColorSpace;
+        
+        if (srcICC && dstICC) {
+            conversionSequence = new ICC_Profile[2];
+        } else {
+            conversionSequence = new Object[2];
+            isICC = false;
+        }
+        
+        if (srcICC) {
+            conversionSequence[0] = ((ICC_ColorSpace) srcCS).getProfile();
+        } else {
+            conversionSequence[0] = srcCS;
+        }
+        
+        if (dstICC) {
+            conversionSequence[1] = ((ICC_ColorSpace) dstCS).getProfile();
+        } else {
+            conversionSequence[1] = dstCS;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object from the specified 
+     * ICC_Profile objects.
+     * 
+     * @param profiles the array of ICC_Profile objects.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
+        if (profiles == null) {
+            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+        
+        // This array is not used in the program logic, so don't need to copy it
+        // Store it only to return back
+        midProfiles = profiles;  
+        
+        conversionSequence = new ICC_Profile[midProfiles.length];
+        
+        // Add profiles to the conversion sequence
+        for (int i=0, length=midProfiles.length; i<length; i++) {
+            conversionSequence[i] = midProfiles[i];
+        }       
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object using the specified
+     * ColorSpace object.
+     * 
+     * @param cs the destination ColorSpace or an intermediate ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
+        if (cs == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+                        
+        if (cs instanceof ICC_ColorSpace) {
+            conversionSequence = new ICC_Profile[1];
+            conversionSequence[0] = ((ICC_ColorSpace) cs).getProfile();
+        } else {
+            conversionSequence = new Object[1];
+            conversionSequence[0] = cs;
+            isICC = false;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object which converts from 
+     * a source color space to a destination color space.
+     * 
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(RenderingHints hints) {
+        renderingHints = hints;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (conversionSequence.length < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
+        }
+
+        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
+        int nSrcColorComps, nDstColorComps;
+        Object first = conversionSequence[0];
+        Object last = conversionSequence[conversionSequence.length - 1];
+        
+        // Get the number of input/output color components
+        if (isICC) {
+            srcPf = (ICC_Profile) first;
+            dstPf = (ICC_Profile) last;
+            nSrcColorComps = srcPf.getNumComponents();
+            nDstColorComps = dstPf.getNumComponents();
+        } else {
+            if (first instanceof ICC_Profile) {
+                srcPf = (ICC_Profile) first;
+                nSrcColorComps = srcPf.getNumComponents();
+            } else {
+                nSrcColorComps = ((ColorSpace) first).getNumComponents();
+            }
+            
+            if (last instanceof ICC_Profile) {
+                dstPf = (ICC_Profile) last;
+                nDstColorComps = dstPf.getNumComponents();
+            } else {
+                nDstColorComps = ((ColorSpace) last).getNumComponents();
+            }
+        }
+
+        // Check that source and destination rasters are compatible with
+        // transforms and with each other
+        if (src.getNumBands() != nSrcColorComps) {
+            // awt.25E=Incorrect number of source raster bands. Should be equal
+            //          to the number of color components of source colorspace.
+            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
+        }
+        
+        if (dst != null) { // Check destination raster
+            if (dst.getNumBands() !=
+                nDstColorComps) {
+                // awt.25F=Incorrect number of destination raster bands. Should
+                //          be equal to the number of color components of destination
+                //          colorspace.
+                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
+            }
+            
+            if (src.getWidth() != dst.getWidth() ||
+               src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
+            }
+            
+        } else {
+          dst = createCompatibleDestRaster(src);
+        }
+        
+        if (isICC) {
+            // Create transform
+            ICC_Transform t = tCreator.getTransform(srcPf, dstPf, 
+                    (ICC_Profile[])conversionSequence); 
+            cc.translateColor(t, src, dst);         
+        } else {
+            Object[] sequence = tCreator.getSequence(null, null);
+            
+            // Get data from the source raster
+            ColorScaler scaler = new ColorScaler();
+            scaler.loadScalingData(src, null);
+            float tmpData[][] = scaler.scaleNormalize(src);
+            
+            // Get source and destination color spaces
+            ColorSpace srcCS = (srcPf == null) ? 
+                    (ColorSpace) first:
+                    new ICC_ColorSpace(srcPf);
+            ColorSpace dstCS = (dstPf == null) ? 
+                    (ColorSpace) last:
+                    new ICC_ColorSpace(dstPf);
+                    
+            applySequence(sequence, tmpData, srcCS, dstCS);
+            
+            scaler.loadScalingData(dst, null);
+            scaler.unscaleNormalized(dst, tmpData);
+        }
+
+        return dst;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        // If destination color model is passed only one line needed
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                    destCM.isAlphaPremultiplied(), 
+                    null);
+        }
+        
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        // Get destination color space
+        Object destination = conversionSequence[nSpaces-1];
+        ColorSpace dstCS = 
+            (destination instanceof ColorSpace) ? 
+                    (ColorSpace) destination : 
+                    new ICC_ColorSpace((ICC_Profile) destination);
+        
+        ColorModel srcCM = src.getColorModel();     
+        ColorModel dstCM = new ComponentColorModel(dstCS, 
+                srcCM.hasAlpha(), 
+                srcCM.isAlphaPremultiplied(),
+                srcCM.getTransparency(),
+                srcCM.getTransferType());
+        
+        return new BufferedImage(dstCM,
+                destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                destCM.isAlphaPremultiplied(), 
+                null);
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (dst == null && conversionSequence.length < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        // First handle index color model
+        if (srcCM instanceof IndexColorModel) {            
+            src = ((IndexColorModel) srcCM).convertToIntDiscrete(src.getRaster(), false);
+        }
+        ColorSpace srcCS = srcCM.getColorSpace();        
+                
+        BufferedImage res;
+        boolean isDstIndex = false;
+        if (dst != null) {
+          
+          if (src.getWidth() != dst.getWidth() ||
+             src.getHeight() != dst.getHeight()) {
+              throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
+          }
+
+            if (dst.getColorModel() instanceof IndexColorModel) {
+                isDstIndex = true;
+                res = createCompatibleDestImage(src, null);
+            } else {                
+                res = dst;
+            }           
+        } else {
+            res = createCompatibleDestImage(src, null);
+        }
+        ColorModel dstCM = res.getColorModel();
+        ColorSpace dstCS = dstCM.getColorSpace();
+        
+        ICC_Profile srcPf = null, dstPf = null;
+        if (srcCS instanceof ICC_ColorSpace) {
+            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
+        }
+        if (dstCS instanceof ICC_ColorSpace) {
+            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
+        }
+        
+        boolean isFullICC = isICC && srcPf != null && dstPf != null;
+        
+        if (isFullICC) {
+            ICC_Transform t =
+                    tCreator.getTransform(srcPf, dstPf, (ICC_Profile[]) conversionSequence);
+            cc.translateColor(t, src, res);
+        } else { // Perform non-ICC transform
+            Object sequence[] = tCreator.getSequence(
+                    srcPf == null ? (Object) srcCS : srcPf,
+                    dstPf == null ? (Object) dstCS : dstPf);            
+            
+            int srcW = src.getWidth();
+            int srcH = src.getHeight();
+            int numPixels = srcW*srcH;
+
+            // Load all pixel data into array tmpData 
+            float tmpData[][] = 
+                new float[numPixels][tCreator.maxComponents];
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    tmpData[dataPos] = 
+                        srcCM.getNormalizedComponents(
+                                src.getRaster().getDataElements(row, col, null), 
+                                tmpData[dataPos], 0);
+                    dataPos++;
+                }
+            }
+
+            // Copy alpha channel if needed
+            float alpha[] = null;
+            int alphaIdx = srcCM.numComponents - 1;
+            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
+                alpha = new float[numPixels];
+                for (int i=0; i<numPixels; i++) {
+                    alpha[i] = tmpData[i][alphaIdx];
+                }
+            }
+            
+            // Translate colors
+            applySequence(sequence, tmpData, srcCS, dstCS);
+
+            // Copy alpha if needed
+            if (dstCM.hasAlpha()) {
+                alphaIdx = dstCM.numComponents - 1;
+                if (alpha != null) {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = alpha[i];
+                    }                   
+                } else {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = 1f;
+                    }                                       
+                }
+            }
+            
+            // Store data back to the image            
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    res.getRaster().setDataElements(row, col, 
+                            dstCM.getDataElements(tmpData[dataPos++], 0 , null));
+                }
+            }
+        }               
+
+        if (isDstIndex) { // Convert image into indexed color
+            Graphics2D g2d = dst.createGraphics();
+            g2d.drawImage(res, 0, 0, null);
+            g2d.dispose();
+            return dst;
+        }
+        
+        return res;
+    }
+
+    /**
+     * Apply sequence.
+     * 
+     * @param sequence the sequence
+     * @param tmpData the tmp data
+     * @param srcCS the src cs
+     * @param dstCS the dst cs
+     */
+    private void applySequence(
+            Object sequence[], 
+            float tmpData[][],
+            ColorSpace srcCS, 
+            ColorSpace dstCS
+            ) {
+        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+        
+        int numPixels = tmpData.length;
+        
+        // First transform...
+        if (sequence[0] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[0];
+            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]); 
+            }
+            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
+        }
+        
+        for (Object element : sequence) {
+            if (element instanceof ICC_Transform) {
+                ICC_Transform t = (ICC_Transform)element;
+                cc.translateColor(t, tmpData, null, null, numPixels);
+            } else {
+                ColorSpace cs = (ColorSpace) element;
+                for (int k=0; k<numPixels; k++) {
+                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
+                    tmpData[k] = cs.toCIEXYZ(tmpData[k]); 
+                }
+            }
+        }
+        
+        // Last transform...
+        if (sequence[sequence.length-1] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[sequence.length-1];
+            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]); 
+            }
+        }
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt != null) {
+            dstPt.setLocation(srcPt);
+            return dstPt;
+        }
+        return new Point2D.Float((float) srcPt.getX(), (float) srcPt.getY());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        int nComps = 0;
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        Object lastCS = conversionSequence[nSpaces-1];
+        if (lastCS instanceof ColorSpace) {
+            nComps = ((ColorSpace) lastCS).getNumComponents();
+        } else {
+            nComps = ((ICC_Profile) lastCS).getNumComponents(); 
+        }
+        
+        // Calculate correct data type
+        int dstDataType = src.getDataBuffer().getDataType();
+        if (dstDataType != DataBuffer.TYPE_BYTE &&
+           dstDataType != DataBuffer.TYPE_SHORT) {
+                dstDataType = DataBuffer.TYPE_SHORT;
+        }
+        
+        return Raster.createInterleavedRaster(
+                dstDataType, 
+                src.getWidth(),
+                src.getHeight(),
+                nComps,
+                new Point(src.getMinX(), src.getMinY())
+            );
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return src.getRaster().getBounds();
+    }
+
+    /**
+     * Gets an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     * 
+     * @return an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     */
+    public final ICC_Profile[] getICC_Profiles() {
+        if (midProfiles != null) {
+            return midProfiles;
+        }
+        return null;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return renderingHints;
+    }    
+}
diff --git a/awt/java/awt/image/ColorModel.java b/awt/java/awt/image/ColorModel.java
new file mode 100644
index 0000000..945c087
--- /dev/null
+++ b/awt/java/awt/image/ColorModel.java
@@ -0,0 +1,911 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ColorModel.
+ */
+public abstract class ColorModel implements Transparency {
+
+    /** The pixel_bits. */
+    protected int pixel_bits;  // Pixel length in bits
+
+    /** The transfer type. */
+    protected int transferType;
+
+    /** The cs. */
+    ColorSpace cs;
+
+    /** The has alpha. */
+    boolean hasAlpha;
+
+    /** The is alpha premultiplied. */
+    boolean isAlphaPremultiplied;
+
+    /** The transparency. */
+    int transparency;
+
+    /** The num color components. */
+    int numColorComponents;
+
+    /** The num components. */
+    int numComponents;
+
+    /** The bits. */
+    int[] bits;             // Array of components masks 
+
+    /** The max values. */
+    int[] maxValues = null; // Max values that may be represent by color
+                            // components
+
+    /** The max bit length. */
+    int maxBitLength;       // Max length color components in bits
+
+    /** The RG bdefault. */
+    private static ColorModel RGBdefault;
+
+    /**
+     * Instantiates a new color model with the specified values.
+     * 
+     * @param pixel_bits the pixel length in bits
+     * @param bits the array of component masks
+     * @param cspace the colorspace
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+
+        if (pixel_bits < 1) {
+            // awt.26B=The number of bits in the pixel values is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.26B")); //$NON-NLS-1$
+        }
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        int sum = 0;
+        for (int element : bits) {
+            if (element < 0) {
+                // awt.26D=The elements in bits is less than 0
+                throw new IllegalArgumentException(Messages.getString("awt.26D")); //$NON-NLS-1$
+            }
+            sum += element;
+        }
+
+        if (sum < 1) {
+            // awt.26E=The sum of the number of bits in bits is less than 1
+            throw new NullPointerException(Messages.getString("awt.26E")); //$NON-NLS-1$
+        }
+
+        if (cspace == null) {
+            // awt.26F=The cspace is null
+            throw new IllegalArgumentException(Messages.getString("awt.26F")); //$NON-NLS-1$
+        }
+
+        if (transparency < Transparency.OPAQUE ||
+               transparency > Transparency.TRANSLUCENT) {
+            // awt.270=The transparency is not a valid value
+            throw new IllegalArgumentException(Messages.getString("awt.270")); //$NON-NLS-1$
+        }
+
+        this.pixel_bits = pixel_bits;
+        this.bits = bits.clone();
+
+        maxValues = new int[bits.length];
+        maxBitLength = 0;
+        for (int i = 0; i < maxValues.length; i++) {
+            maxValues[i] = (1 << bits[i]) - 1;
+            if (bits[i] > maxBitLength) {
+                maxBitLength = bits[i];
+            }
+        }
+
+        cs = cspace;
+        this.hasAlpha = hasAlpha;
+        this.isAlphaPremultiplied = isAlphaPremultiplied;
+        numColorComponents = cs.getNumComponents();
+
+        if (hasAlpha) {
+            numComponents = numColorComponents + 1;
+        } else {
+            numComponents = numColorComponents;
+        }
+
+        this.transparency = transparency;
+        this.transferType = transferType;
+
+    }
+
+    /**
+     * Instantiates a new color model with the specified pixel bit depth.
+     * The transferType is chosen based on the pixel bits, and the other
+     * data fields are given default values.
+     * 
+     * @param bits the array of component masks
+     */
+    public ColorModel(int bits) {
+
+        if (bits < 1) {
+            // awt.271=The number of bits in bits is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.271")); //$NON-NLS-1$
+        }
+
+        pixel_bits = bits;
+        transferType = getTransferType(bits);
+        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        hasAlpha = true;
+        isAlphaPremultiplied = false;
+        transparency = Transparency.TRANSLUCENT;
+
+        numColorComponents = 3;
+        numComponents = 4;
+
+        this.bits = null;
+    }
+
+    /**
+     * Gets the data elements from the specified component array, transforming
+     * them according to rules of the color model.
+     * 
+     * @param components the components
+     * @param offset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int[] components, int offset, Object obj) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the data elements from the specified array of normalized components.
+     * 
+     * @param normComponents the array normalized components
+     * @param normOffset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(float[] normComponents, int normOffset,
+            Object obj) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElements(unnormComponents, 0, obj);
+    }
+
+    /**
+     * Gets the data elements corresponding to the pixel determined by the 
+     * RGB data.
+     * 
+     * @param rgb the rgb int that defines the pixel
+     * @param pixel the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int rgb, Object pixel) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the child raster corresponding to the alpha channel of the 
+     * specified writable raster, or null if alpha is not supported.
+     * 
+     * @param raster the raster
+     * 
+     * @return the alpha raster
+     */
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        return null;
+    }
+
+    /**
+     * Creates a new color model by coercing the data in the writable raster 
+     * in accordance with the alpha strategy of this color model.
+     * 
+     * @param raster the raster
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this 
+     * color model
+     * 
+     * @return the new color model
+     */
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB,
+        // false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+        // System.out.println(cm.toString());
+        return "ColorModel: Color Space = " + cs.toString() + "; has alpha = " //$NON-NLS-1$ //$NON-NLS-2$
+                + hasAlpha + "; is alpha premultipied = " //$NON-NLS-1$
+                + isAlphaPremultiplied + "; transparency = " + transparency //$NON-NLS-1$
+                + "; number color components = " + numColorComponents //$NON-NLS-1$
+                + "; pixel bits = " + pixel_bits + "; transfer type = " //$NON-NLS-1$ //$NON-NLS-2$
+                + transferType;
+    }
+
+    /**
+     * Gets the components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param components the the array where the resulting components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of components
+     */
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the normalized components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of normalized components
+     */
+    public float[] getNormalizedComponents(Object pixel,
+            float[] normComponents, int normOffset) {
+
+        if (pixel == null) {
+            // awt.294=pixel is null
+            throw new NullPointerException(Messages.getString("awt.294")); //$NON-NLS-1$
+        }
+
+        int unnormComponents[] = getComponents(pixel, null, 0);
+        return getNormalizedComponents(unnormComponents, 0, normComponents,
+                normOffset);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ColorModel)) {
+            return false;
+        }
+        ColorModel cm = (ColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+               transferType == cm.getTransferType() &&
+               cs.getType() == cm.getColorSpace().getType() &&
+               hasAlpha == cm.hasAlpha() &&
+               isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+               transparency == cm.getTransparency() &&
+               numColorComponents == cm.getNumColorComponents() &&
+               numComponents == cm.getNumComponents() &&
+               Arrays.equals(bits, cm.getComponentSize()));
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the red
+     */
+    public int getRed(Object inData) {
+        return getRed(constructPixel(inData));
+    }
+
+    /**
+     * Gets the RGB int corresponding to the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the int that gives the pixel's colors in RGB format
+     */
+    public int getRGB(Object inData) {
+        return (getAlpha(inData) << 24 | getRed(inData) << 16 |
+               getGreen(inData) << 8 | getBlue(inData));
+    }
+
+    /**
+     * Gets the green component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the green
+     */
+    public int getGreen(Object inData) {
+        return getGreen(constructPixel(inData));
+    }
+
+    /**
+     * Gets the blue component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the blue
+     */
+    public int getBlue(Object inData) {
+        return getBlue(constructPixel(inData));
+    }
+
+    /**
+     * Gets the alpha component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the alpha
+     */
+    public int getAlpha(Object inData) {
+        return getAlpha(constructPixel(inData));
+    }
+
+    /**
+     * Creates a compatible writable raster.
+     * 
+     * @param w the width of the desired writable raster
+     * @param h the height of the desired writable raster
+     * 
+     * @return the writable raster
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the sample model is compatible with this color model.
+     * 
+     * @param sm the sample model
+     * 
+     * @return true, if the sample model is compatible with this color model
+     */
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates the compatible sample model.
+     * 
+     * @param w the width of the desired sample model
+     * @param h the height of the desired sample model
+     * 
+     * @return the sample model
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the specified raster is compatible with this color model.
+     * 
+     * @param raster the raster to inspect
+     * 
+     * @return true, if the raster is compatible with this color model
+     */
+    public boolean isCompatibleRaster(Raster raster) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the color space of this color model.
+     * 
+     * @return the color space
+     */
+    public final ColorSpace getColorSpace() {
+        return cs;
+    }
+
+    /**
+     * Gets the normalized components corresponding to the specified 
+     * unnormalized components.
+     * 
+     * @param components the array of unnormalized components
+     * @param offset the offset where the components should be read 
+     * from the array of unnormalized components
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the normalized components
+     */
+    public float[] getNormalizedComponents(int[] components, int offset,
+            float normComponents[], int normOffset) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float normAlpha =
+                (float) components[offset + numColorComponents] /
+                    maxValues[numColorComponents];
+            if (normAlpha != 0.0f) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComponents[normOffset + i] =
+                        components[offset + i] /
+                            (normAlpha * maxValues[i]);
+                }
+                normComponents[normOffset + numColorComponents] = normAlpha;
+            } else {
+                for (int i = 0; i < numComponents; i++) {
+                    normComponents[normOffset + i] = 0.0f;
+                }
+            }
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                normComponents[normOffset + i] =
+                    (float) components[offset + i] /
+                        maxValues[i];
+            }
+        }
+
+        return normComponents;
+    }
+
+    /**
+     * Gets the data element corresponding to the unnormalized components.
+     * 
+     * @param components the components
+     * @param offset the offset to start reading the components from the 
+     * array of components
+     * 
+     * @return the data element
+     */
+    public int getDataElement(int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the unnormalized components corresponding to the specified 
+     * normalized components.
+     * 
+     * @param normComponents the array of normalized components
+     * @param normOffset the offset where the components should be read 
+     * from the array of normalized components
+     * @param components the array where the resulting unnormalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the unnormalized components
+     */
+    public int[] getUnnormalizedComponents(float normComponents[],
+            int normOffset, int components[], int offset) {
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.273=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.273")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        } else {
+            if (components.length - offset < numComponents) {
+                // awt.272=The length of components minus offset is less than numComponents
+                throw new IllegalArgumentException(Messages.getString("awt.272")); //$NON-NLS-1$
+            }
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                components[offset + i] = (int) (normComponents[normOffset + i]
+                        * maxValues[i] * alpha + 0.5f);
+            }
+            components[offset + numColorComponents] =
+                (int) (normComponents[normOffset + numColorComponents] *
+                        maxValues[numColorComponents] + 0.5f);
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                components[offset + i] =
+                    (int) (normComponents[normOffset + i] *
+                            maxValues[i] + 0.5f);
+            }
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the data element corresponding to the normalized components.
+     * 
+     * @param normComponents the normalized components
+     * @param normOffset the offset where the normalized components should
+     * be read from the normalized component array
+     * 
+     * @return the data element
+     */
+    public int getDataElement(float normComponents[], int normOffset) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElement(unnormComponents, 0);
+    }
+
+    /**
+     * Takes a pixel whose data is defined by an int, and writes the 
+     * corresponding components into the components array, starting 
+     * from the index offset.
+     * 
+     * @param pixel the pixel data
+     * @param components the data array to write the components to (or
+     * null to have the method create the return array)
+     * @param offset the offset that determines where the results are 
+     * written in the components array
+     * 
+     * @return the array of components corresponding to the pixel
+     */
+    public int[] getComponents(int pixel, int components[], int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the red component of the pixel
+     */
+    public abstract int getRed(int pixel);
+
+    /**
+     * Takes the pixel data and returns the int corresponding 
+     * to the pixel's color in RGB format.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the corresponding RGB int
+     */
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24 | getRed(pixel) << 16
+                | getGreen(pixel) << 8 | getBlue(pixel));
+    }
+
+    /**
+     * Gets the green component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the green component of the pixel
+     */
+    public abstract int getGreen(int pixel);
+
+    /**
+     * Gets the size of the desired component of this color model.
+     * 
+     * @param componentIdx the index that determines which component size to get
+     * 
+     * @return the component size corresponding to the index
+     * 
+     * @throws NullPointerException if this color model doesn't support
+     * an array of separate components.
+     * @throws ArrayIndexOutOfBoundsException if the index is negative or
+     * greater than or equal to the number of components
+     */
+    public int getComponentSize(int componentIdx) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (componentIdx < 0 || componentIdx >= bits.length) {
+            // awt.274=componentIdx is greater than the number of components or less than zero
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.274")); //$NON-NLS-1$
+        }
+
+        return bits[componentIdx];
+    }
+
+    /**
+     * Gets the blue component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the blue component of the pixel
+     */
+    public abstract int getBlue(int pixel);
+
+    /**
+     * Gets the alpha component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the alpha component of the pixel
+     */
+    public abstract int getAlpha(int pixel);
+
+    /**
+     * Gets the array of sizes of the different components.
+     * 
+     * @return the array of sizes of the different components
+     */
+    public int[] getComponentSize() {
+        if (bits != null) {
+            return bits.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the alpha component is premultiplied.
+     * 
+     * @return true, if the alpha component is premultiplied
+     */
+    public final boolean isAlphaPremultiplied() {
+        return isAlphaPremultiplied;
+    }
+
+    /**
+     * Checks whether this color model supports alpha.
+     * 
+     * @return true, if this color model has alpha
+     */
+    public final boolean hasAlpha() {
+        return hasAlpha;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp;
+
+        if (hasAlpha) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+        if (isAlphaPremultiplied) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+
+        tmp = hash >>> 24;
+        hash ^= numColorComponents;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transparency;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= cs.getType();
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= pixel_bits;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transferType;
+        hash <<= 8;
+        hash |= tmp;
+
+        if (bits != null) {
+
+            for (int element : bits) {
+                tmp = hash >>> 24;
+                hash ^= element;
+                hash <<= 8;
+                hash |= tmp;
+            }
+
+        }
+
+        return hash;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @return the transfer type
+     */
+    public final int getTransferType() {
+        return transferType;
+    }
+
+    /**
+     * Gets the pixel size in bits.
+     * 
+     * @return the pixel size
+     */
+    public int getPixelSize() {
+        return pixel_bits;
+    }
+
+    /**
+     * Gets the number of components of this color model.
+     * 
+     * @return the number of components
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Gets the number of color components of this color model.
+     * 
+     * @return the number color components
+     */
+    public int getNumColorComponents() {
+        return numColorComponents;
+    }
+
+    /**
+     * Gets the default RGB color model.
+     * 
+     * @return the default RGB color model
+     */
+    public static ColorModel getRGBdefault() {
+        if (RGBdefault == null) {
+            RGBdefault = new DirectColorModel(32, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0xff000000);
+        }
+        return RGBdefault;
+    }
+
+    /*
+     * Construct INT pixel representation from Object
+     * @param obj
+     *
+     * @return
+     */
+    /**
+     * Construct pixel.
+     * 
+     * @param obj the obj
+     * 
+     * @return the int
+     */
+    private int constructPixel(Object obj) {
+        int pixel = 0;
+
+        switch (getTransferType()) {
+
+        case DataBuffer.TYPE_BYTE:
+            byte[] bPixel = (byte[]) obj;
+            if(bPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = bPixel[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short[] sPixel = (short[]) obj;
+            if(sPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = sPixel[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int[] iPixel = (int[]) obj;
+            if(iPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = iPixel[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+
+        }
+        return pixel;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @param bits the array of component masks
+     * 
+     * @return the transfer type
+     */
+    static int getTransferType(int bits) {
+        if (bits <= 8) {
+            return DataBuffer.TYPE_BYTE;
+        } else if (bits <= 16) {
+            return DataBuffer.TYPE_USHORT;
+        } else if (bits <= 32) {
+            return DataBuffer.TYPE_INT;
+        } else {
+            return DataBuffer.TYPE_UNDEFINED;
+        }
+    }
+
+    @Override
+    public void finalize() {
+        // This method is added for the API compatibility
+        // Don't need to call super since Object's finalize is always empty
+    }
+}
diff --git a/awt/java/awt/image/ComponentColorModel.java b/awt/java/awt/image/ComponentColorModel.java
new file mode 100644
index 0000000..a152f55
--- /dev/null
+++ b/awt/java/awt/image/ComponentColorModel.java
@@ -0,0 +1,1471 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ComponentColorModel represents a color model that is defined 
+ * in terms of its components.
+ */
+public class ComponentColorModel extends ColorModel {
+
+    /** The signed. */
+    private boolean signed;   // Pixel samples are signed.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT - 
+                              // unsigned. Samples with others TransferType - 
+                              // signed.
+
+    /** The integral. */
+    private boolean integral; // Pixel samples are integral.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.Short and 
+                              // DataBuffer.TYPE_INT - integral.
+
+    /** The scale factors. */
+    private float scaleFactors[]; // Array of factors for reduction components 
+                                  // values into the form scaled from 0 to 255
+
+    /** The donot support unnormalized. */
+    private boolean donotSupportUnnormalized; // This Color Model don't support
+                                              // unnormolized form 
+
+    /** The need alpha divide. */
+    private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
+
+    /** The calc value. */
+    private boolean calcValue;       // Value was culculated
+
+    /** The need scale. */
+    private boolean needScale;       // Normalized value need to scale
+
+    /** The min vals. */
+    private float minVals[];         // Array of Min normalized values
+
+    /** The ranges. */
+    private float ranges[];          // Array of range normalized values  
+
+    /** The alpha lut. */
+    private byte alphaLUT[];         // Lookup table for scale alpha value
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];      // Lookup tables for scale color values
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[];  // Lookup table for conversion from
+                                         // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];   // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 8 bit 
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 16 bit 
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;       // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;               // Scale factor
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;             // ColorModel has sRGB ColorSpace  
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;       // Color Model has Linear RGB Color 
+                                         // Space 
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param bits the array of component masks
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+     public ComponentColorModel(ColorSpace colorSpace, int bits[],
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+        super(createPixelBits(colorSpace, hasAlpha, transferType),
+                validateBits(bits, colorSpace, hasAlpha, transferType),
+                colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
+                transferType);
+
+        needScale = false;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            signed = false;
+            integral = true;
+            donotSupportUnnormalized = false;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    donotSupportUnnormalized = true;
+                }
+            }
+            if (hasAlpha) {
+                maxValues[numColorComponents] =
+                    (1 << bits[numColorComponents]) - 1;
+                scaleFactors[numColorComponents] =
+                    1.0f / maxValues[numColorComponents];
+            }
+            break;
+        case DataBuffer.TYPE_SHORT:
+            signed = true;
+            integral = true;
+            donotSupportUnnormalized = true;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numComponents; i++) {
+                maxValues[i] = Short.MAX_VALUE;
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    needScale = true;
+                }
+            }
+            if (needScale) {
+                minVals = new float[numColorComponents];
+                ranges = new float[numColorComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    minVals[i] = cs.getMinValue(i);
+                    ranges[i] = cs.getMaxValue(i) - minVals[i];
+                }
+            }
+            break;
+        case DataBuffer.TYPE_FLOAT:
+        case DataBuffer.TYPE_DOUBLE:
+            signed = true;
+            integral = false;
+            donotSupportUnnormalized = true;
+            break;
+        default:
+            // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+            //          DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+            //          DataBuffer.TYPE_DOUBLE
+            throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
+        }
+
+        needAlphaDivide = hasAlpha && isAlphaPremultiplied;
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+        
+        this(colorSpace, 
+                createPixelBitsArray(colorSpace, hasAlpha, transferType), 
+                hasAlpha, 
+                isAlphaPremultiplied, 
+                transparency,
+                transferType);
+    }
+
+    /**
+     * Validate bits.
+     * 
+     * @param bits the bits
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] validateBits(int bits[], ColorSpace colorSpace,
+            boolean hasAlpha, int transferType) {
+        if (bits != null) {
+            return bits;
+        }
+
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        bits = new int[numComponents];
+
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+
+        for (int i = 0; i < numComponents; i++) {
+            bits[i] = componentLength;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the pixel bits.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha,
+            int transferType) {
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+        return numComponents * componentLength;
+    }
+
+    /**
+     * Creates the pixel bits array.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] createPixelBitsArray(ColorSpace colorSpace, 
+            boolean hasAlpha, int transferType) {
+        
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+
+        int bits[] = new int[numComponents];
+        for(int i = 0; i < numComponents; i++){
+            bits[i] = DataBuffer.getDataTypeSize(transferType);
+        }
+        return bits;
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (offset + numComponents > components.length) {
+            // awt.216=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ba[i] = (byte) components[idx];
+            }
+            return ba;
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                sa[i] = (short) components[idx];
+            }
+            return sa;
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ia[i] = components[idx];
+            }
+            return ia;
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(float normComponents[], int normOffset,
+            Object obj) {
+        if (needScale) {
+            for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                normComponents[idx] =
+                    (normComponents[idx] - minVals[i]) / ranges[i];
+            }
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = normOffset; i < numColorComponents;
+                    i++, idx++) {
+                    ba[i] = (byte) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ba[numColorComponents] =
+                    (byte) (normComponents[normOffset + numColorComponents] *
+                            maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ba[idx] =
+                        (byte) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[];
+            if (obj == null) {
+                usa = new short[numComponents];
+            } else {
+                usa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                usa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return usa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ia[numColorComponents] = (int) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ia;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                sa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return sa;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[];
+            if (obj == null) {
+                fa = new float[numComponents];
+            } else {
+                fa = (float[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    fa[i] = normComponents[idx] * alpha;
+                }
+                fa[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    fa[i] = normComponents[idx];
+                }
+            }
+            return fa;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[];
+            if (obj == null) {
+                da = new double[numComponents];
+            } else {
+                da = (double[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                double alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    da[i] = normComponents[idx] * alpha;
+                }
+                da[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    da[i] = normComponents[idx];
+                }
+            }
+            return da;
+
+        default:
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        float normComp[];
+        float comp[];
+
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = (rgb >> 24) & 0xff;
+
+        comp = new float[3];
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float[] defComp = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = defComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = defComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+        if(hasAlpha && isAlphaPremultiplied){
+            normComp[0] *= normComp[numColorComponents];
+            normComp[1] *= normComp[numColorComponents];
+            normComp[2] *= normComp[numColorComponents];
+        }
+
+        return getDataElements(normComp, 0, pixel);
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int bandList[] = new int[1];
+        bandList[0] = raster.getNumBands() - 1;
+
+        return raster.createWritableChild(x, y, raster.getWidth(),
+                raster.getHeight(), x, y, bandList);
+    }
+
+    @Override
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (alpha * iComponents[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (alpha * sComponents[n] + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (iComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                    sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (sComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        }
+
+        if (!signed) {
+            return new ComponentColorModel(cs, bits, hasAlpha,
+                    isAlphaPremultiplied, transparency, transferType);
+        }
+
+        return new ComponentColorModel(cs, null, hasAlpha,
+                isAlphaPremultiplied, transparency, transferType);
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + numComponents];
+        } else if (offset + numComponents > components.length) {
+            // awt.218=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ba[i] & 0xff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = sa[i] & 0xffff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ia[i];
+            }
+            return components;
+
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public float[] getNormalizedComponents(Object pixel,
+            float normComponents[], int normOffset) {
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (usa[i] & 0xffff)
+                        * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = ia[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = sa[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = fa[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (float) da[i];
+            }
+            break;
+
+        default:
+            // awt.21A=This ComponentColorModel does not support this transferType
+            throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
+        }
+
+        if (needAlphaDivide) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] /= alpha;
+            }
+        }
+
+        if (needScale) {
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] = minVals[i] +
+                    ranges[i] * normComponents[idx];
+            }
+        }
+        return normComponents;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ComponentColorModel)) {
+            return false;
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        return getRGBComponent(inData, 0);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int alpha = getAlpha(inData);
+        if (cs.getType() == ColorSpace.TYPE_GRAY) {
+            int gray = getRed(inData);
+            return (alpha << 24 | gray << 16 | gray << 8 | gray);
+        }
+        return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 |
+                getBlue(inData));
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        return getRGBComponent(inData, 1);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        return getRGBComponent(inData, 2);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int alpha = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte ba[] = (byte[]) inData;
+            alpha = ba[numColorComponents] & 0xff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_USHORT: {
+            short usa[] = (short[]) inData;
+            alpha = usa[numColorComponents] & 0xffff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_INT: {
+            int ia[] = (int[]) inData;
+            alpha = ia[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_SHORT: {
+            short sa[] = (short[]) inData;
+            alpha = sa[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fa[] = (float[]) inData;
+            return (int) (fa[numColorComponents] * 255.0f + 0.5f);
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double da[] = (double[]) inData;
+            return (int) (da[numColorComponents] * 255.0 + 0.5);
+        }
+        default: {
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        }
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        SampleModel sm = createCompatibleSampleModel(w, h);
+        DataBuffer db = sm.createDataBuffer();
+        return Raster.createWritableRaster(sm, db, null);
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+        if (numComponents != sm.getNumBands()) {
+            return false;
+        }
+        if (transferType != sm.getTransferType()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int bandOffsets[] = new int[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            bandOffsets[i] = i;
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+            return new PixelInterleavedSampleModel(transferType, w, h,
+                    numComponents, w * numComponents, bandOffsets);
+
+        default:
+            return new ComponentSampleModel(transferType, w, h, numComponents,
+                    w * numComponents, bandOffsets);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int sampleSizes[] = sm.getSampleSize();
+        for (int i = 0; i < numComponents; i++) {
+            if (bits[i] != sampleSizes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public float[] getNormalizedComponents(int components[], int offset,
+            float normComponents[], int normOffset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        return super.getNormalizedComponents(components, offset,
+                normComponents, normOffset);
+    }
+
+    @Override
+    public int getDataElement(int[] components, int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+        return components[offset];
+    }
+
+    @Override
+    public int[] getUnnormalizedComponents(float[] normComponents,
+            int normOffset, int[] components, int offset) {
+
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.21B=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
+        }
+
+        return super.getUnnormalizedComponents(normComponents, normOffset,
+                components, offset);
+    }
+
+    @Override
+    public int getDataElement(float normComponents[], int normOffset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        Object pixel = getDataElements(normComponents, normOffset, null);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            return ba[0] & 0xff;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            return sa[0] & 0xffff;
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            return ia[0];
+        default:
+            // awt.211=Pixel values for this ColorModel are not conveniently
+            //          representable as a single int
+            throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + 1];
+        }
+
+        components[offset] = pixel & maxValues[0];
+        return components;
+    }
+
+    @Override
+    public int getRed(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[0] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public int getGreen(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[1] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getBlue(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[2] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getAlpha(int pixel) {
+
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        return 255;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (hasAlpha && bits[numColorComponents] != 8 && integral) {
+            alphaLUT = new byte[maxValues[numColorComponents] + 1];
+            for (int i = 0; i <= maxValues[numColorComponents]; i++) {
+                alphaLUT[i] = (byte) (scaleFactors[numColorComponents] * i + 
+                        0.5f);
+            }
+        }
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (!isAlphaPremultiplied && integral) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            colorLUTs[i][j] =
+                                (byte) (scaleFactors[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scaleFactors[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scaleFactors[i] * j * 257.0f +
+                                        0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * To rgb.
+     * 
+     * @param pixel - int representation of pixel
+     * 
+     * @return - array of normalized sRGB components
+     */
+    private float[] toRGB(int pixel) {
+        
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        Object obj = null;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = new byte[1];
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = new short[1];
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = new int[1];
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        }
+
+        return cs.toRGB(getNormalizedComponents(obj, null, 0));
+    }
+
+    /**
+     * Gets the rgb component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - RGB value from 0 to 255 pixel's component
+     */
+    private int getRGBComponent(Object pixel, int idx) {
+        if (is_sRGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == 8) {
+                return comp;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        } else if (is_LINEAR_RGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == LINEAR_RGB_Length) {
+                return from_LINEAR_RGB_LUT[comp] & 0xff;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        }
+
+        float normComp[] = getNormalizedComponents(pixel, null, 0);
+        float rgbComp[] = cs.toRGB(normComp);
+        return (int) (rgbComp[idx] * 255.0f + 0.5f);
+    }
+
+    /**
+     * Gets the def component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - tentative value of the pixel component
+     */
+    private int getDefComponent(Object pixel, int idx) {
+        int comp = 0;
+        calcValue = false;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            comp = ba[idx] & 0xff;
+            if (needAlphaDivide) {
+                int alpha = ba[numColorComponents] & 0xff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            comp = usa[idx] & 0xffff;
+            if (needAlphaDivide) {
+                int alpha = usa[numColorComponents] & 0xffff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            comp = ia[idx];
+            if (needAlphaDivide) {
+                int alpha = ia[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            comp = sa[idx];
+            if (needAlphaDivide) {
+                int alpha = sa[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            if (needAlphaDivide) {
+                float alpha = fa[numColorComponents];
+                if (fa[numColorComponents] == 0.0f) {
+                    comp = 0;
+                } else {
+                    comp = (int) (fa[idx] * fFactor / alpha + 0.5f);
+                }
+            } else {
+                comp = (int) (fa[idx] * fFactor + 0.5f);
+            }
+            calcValue = true;
+            return comp;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            if (needAlphaDivide) {
+                if (da[numColorComponents] == 0.0) {
+                    comp = 0;
+                } else {
+                    comp = (int) (da[idx] * fFactor / da[numColorComponents] + 
+                            0.5);
+                }
+            } else {
+                comp = (int) (da[idx] * fFactor + 0.5);
+            }
+            calcValue = true;
+            return comp;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/ComponentSampleModel.java b/awt/java/awt/image/ComponentSampleModel.java
new file mode 100644
index 0000000..2ff4f1a
--- /dev/null
+++ b/awt/java/awt/image/ComponentSampleModel.java
@@ -0,0 +1,690 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ComponentSampleModel class represents a set of image data whose 
+ * each element - the sample of a pixel - takes one data element of 
+ * the DataBuffer. 
+ * <p>
+ * The Bank indices denote the correspondence between the bank of data 
+ * buffers and a band of image data. The Pixel stride is the number of data 
+ * array elements between two samples for the same band on the same 
+ * scanline. The pixel stride for a BandedSampleModel is one. The Scanline 
+ * stride represents the number of data array elements between a  
+ * specified sample and the corresponding sample in the same column in 
+ * the next scanline. The array of band offsets gives the starting 
+ * offsets within each data banks of the in the DataBuffer. The bank 
+ * indices represents the indices within each bank of the DataBuffer 
+ * corresponding to a band of image data.
+ */
+public class ComponentSampleModel extends SampleModel {
+
+    /** The band offsets array of this ComponentSampleModel. */
+    protected int bandOffsets[];
+
+    /** The bank indices array of this ComponentSampleModel. */
+    protected int bankIndices[];
+
+    /** The number of bands in this ComponentSampleModel. */
+    protected int numBands;
+
+    /** The number banks of this ComponentSampleModel. */
+    protected int numBanks;
+
+    /** The scanline stride of this ComponentSampleModel. */
+    protected int scanlineStride;
+
+    /** The pixel stride of this ComponentSampleModel. */
+    protected int pixelStride;
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the array of the bank indices.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bankIndices[], int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        if (bankIndices.length != bandOffsets.length) {
+            // awt.24D=Bank Indices length must be equal Bank Offsets length
+            throw new IllegalArgumentException(Messages.getString("awt.24D")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.bankIndices = bankIndices.clone();
+        this.numBands = bandOffsets.length;
+
+        int maxBank = 0;
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bankIndices[i] < 0) {
+                // awt.24E=Index of {0} bank must be >= 0
+                throw new IllegalArgumentException(Messages.getString("awt.24E", i)); //$NON-NLS-1$
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+        this.numBanks = maxBank + 1;
+
+    }
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandOffsets the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.numBands = bandOffsets.length;
+        this.numBanks = 1;
+
+        this.bankIndices = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            bankIndices[i] = 0;
+        }
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte barr[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, barr[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sarr[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sarr[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int iarr[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, iarr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float farr[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, farr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double darr[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, darr[i], data);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Compares this ComponentSampleModel with the specified Object.
+     * 
+     * @param o the Object.
+     * 
+     * @return true, if the object is a ComponentSampleModel with 
+     * identical data values to this ComponentSampleModel, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof ComponentSampleModel)) {
+            return false;
+        }
+        ComponentSampleModel model = (ComponentSampleModel) o;
+        return this.width == model.width && this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               Arrays.equals(this.bandOffsets, model.bandOffsets) &&
+               Arrays.equals(this.bankIndices, model.bankIndices) &&
+               this.numBands == model.numBands &&
+               this.numBanks == model.numBanks &&
+               this.scanlineStride == model.scanlineStride &&
+               this.pixelStride == model.pixelStride;
+    }
+
+    /** 
+     * @see java.awt.image.SampleModel#createSubsetSampleModel(int[])
+     */
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new ComponentSampleModel(dataType, width, height, pixelStride,
+                scanlineStride, indices, offsets);
+
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new ComponentSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x > this.width || x + w > this.width
+                || y > this.height || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[] = null;
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x * pixelStride
+                + bandOffsets[b], s);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+        
+        if (data == null) {
+            // awt.295=data is null
+            throw new NullPointerException(Messages.getString("awt.295")); //$NON-NLS-1$
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+
+        int maxOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+        }
+        int size = (height - 1) * scanlineStride +
+        (width - 1) * pixelStride + maxOffset + 1;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    /**
+     * Gets the offset of the specified band of the specified pixel.
+     * 
+     * @param x the X coordinate of the pixel. 
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the offset of the specified band of the specified pixel.
+     */
+    public int getOffset(int x, int y, int b) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[b];
+    }
+
+    /**
+     * Gets the offset of the first band of the specified pixel.
+     * 
+     * @param x the X coordinate of pixel. 
+     * @param y the Y coordinate of pixel.
+     * 
+     * @return the offset of the first band of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[0];
+    }
+
+    @Override
+    public final int getSampleSize(int band) {
+        return DataBuffer.getDataTypeSize(dataType);
+    }
+
+    @Override
+    public final int[] getSampleSize() {
+        int sampleSizes[] = new int[numBands];
+        int size = DataBuffer.getDataTypeSize(dataType);
+
+        for (int i = 0; i < numBands; i++) {
+            sampleSizes[i] = size;
+        }
+        return sampleSizes;
+    }
+
+    /**
+     * Gets an array of bank indices corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of bank indices.
+     */
+    public final int[] getBankIndices() {
+        return bankIndices.clone();
+    }
+
+    /**
+     * Gets an array of the band offsets corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of band offsets.
+     */
+    public final int[] getBandOffsets() {
+        return bandOffsets.clone();
+    }
+
+    /**
+     * Gets a hash code of this ComponentSampleModel object.
+     * 
+     * @return a hash code of this ComponentSampleModel object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bandOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bankIndices) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= pixelStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride of this ComponentSampleModel.
+     * 
+     * @return the scanline stride of this ComponentSampleModel.
+     */
+    public final int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel stride.
+     * 
+     * @return the pixel stride
+     */
+    public final int getPixelStride() {
+        return pixelStride;
+    }
+
+    @Override
+    public final int getNumDataElements() {
+        return numBands;
+    }
+
+}
+
+
+
diff --git a/awt/java/awt/image/ConvolveOp.java b/awt/java/awt/image/ConvolveOp.java
new file mode 100644
index 0000000..bb588bc
--- /dev/null
+++ b/awt/java/awt/image/ConvolveOp.java
@@ -0,0 +1,545 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 29, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ConvolveOp class convolves from the source data
+ * to the destination using a convolution kernel. 
+ * Each output pixel is represented as the result of multiplying 
+ * the kernel and the surround of the input pixel.
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp {
+
+    /** 
+     * The Constant EDGE_ZERO_FILL indicates that pixels at the edge of 
+     * the destination image are set to zero. 
+     */
+    public static final int EDGE_ZERO_FILL = 0;
+
+    /** 
+     * The Constant EDGE_NO_OP indicates that pixels at the edge of 
+     * the source image are converted to the edge pixels in the 
+     * destination without modification.
+     */
+    public static final int EDGE_NO_OP = 1;
+
+    /** The kernel. */
+    private Kernel kernel;
+    
+    /** The edge cond. */
+    private int edgeCond;
+    
+    /** The rhs. */
+    private RenderingHints rhs = null;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and specified edges condition.
+     * 
+     * @param kernel the specified Kernel.
+     * @param edgeCondition the specified edge condition.
+     * @param hints the RenderingHints object, or null.
+     */
+    public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
+        this.kernel = kernel;
+        this.edgeCond = edgeCondition;
+        this.rhs = hints;
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and EDGE_ZERO_FILL edge condition.
+     * 
+     * @param kernel the specified Kernel.
+     */
+    public ConvolveOp(Kernel kernel) {
+        this.kernel = kernel;
+        this.edgeCond = EDGE_ZERO_FILL;
+    }
+
+    /**
+     * Gets the Kernel object of this ConvolveOp.
+     * 
+     * @return the Kernel object of this ConvolveOp.
+     */
+    public final Kernel getKernel() {
+        return (Kernel) kernel.clone();
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return rhs;
+    }
+
+    /**
+     * Gets the edge condition of this ConvolveOp.
+     * 
+     * @return the edge condition: EDGE_NO_OP or EDGE_ZERO_FILL.
+     */
+    public int getEdgeCondition() {
+        return edgeCond;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == null) { // Should throw according to spec
+            // awt.256=Source raster is null
+            throw new NullPointerException(Messages.getString("awt.256")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.257=Source raster is equal to destination
+            throw new IllegalArgumentException(Messages.getString("awt.257")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
+            throw new IllegalArgumentException(
+                Messages.getString("awt.258", src.getNumBands(), dst.getNumBands())); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+            if (slowFilter(src, dst) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        try {
+            SampleModel sm = src.getSampleModel();
+
+            int numBands = src.getNumBands();
+            int srcHeight = src.getHeight();
+            int srcWidth = src.getWidth();
+
+            int xOrigin = kernel.getXOrigin();
+            int yOrigin = kernel.getYOrigin();
+            int kWidth = kernel.getWidth();
+            int kHeight = kernel.getHeight();
+            float[] data = kernel.getKernelData(null);
+
+            int srcMinX = src.getMinX();
+            int srcMinY = src.getMinY();
+            int dstMinX = dst.getMinX();
+            int dstMinY = dst.getMinY();
+
+            int srcConvMaxX = srcWidth - (kWidth - xOrigin - 1);
+            int srcConvMaxY = srcHeight - (kHeight - yOrigin - 1);
+
+            int[] maxValues = new int[numBands];
+            int[] masks = new int[numBands];
+            int[] sampleSizes = sm.getSampleSize();
+
+            for (int i=0; i < numBands; i++){
+                maxValues[i] = (1 << sampleSizes[i]) - 1;
+                masks[i] = ~(maxValues[i]);
+            }
+
+            // Processing bounds
+            float[] pixels = null;
+            pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+            float[] newPixels = new float[pixels.length];
+            int rowLength = srcWidth*numBands;
+            if (this.edgeCond == ConvolveOp.EDGE_NO_OP){
+                // top
+                int start = 0;
+                int length = yOrigin*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // bottom
+                start = (srcHeight - (kHeight - yOrigin - 1))*rowLength;
+                length = (kHeight - yOrigin - 1)*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // middle
+                length = xOrigin*numBands;
+                int length1 = (kWidth - xOrigin - 1)*numBands;
+                start = yOrigin*rowLength;
+                int start1 = (yOrigin+1)*rowLength - length1;
+                for (int i = yOrigin; i < (srcHeight - (kHeight - yOrigin - 1)); i ++) {
+                    System.arraycopy(pixels, start, newPixels, start, length);
+                    System.arraycopy(pixels, start1, newPixels, start1, length1);
+                    start +=rowLength;
+                    start1 +=rowLength;
+                }
+
+            }
+
+            // Cycle over pixels to be calculated
+            for (int i = yOrigin; i < srcConvMaxY; i++){
+                for (int j = xOrigin; j < srcConvMaxX; j++){
+
+                    // Take kernel data in backward direction, convolution
+                    int kernelIdx = data.length - 1;
+
+                    int pixelIndex = i * rowLength + j * numBands;
+                    for (int hIdx = 0, rasterHIdx = i - yOrigin;
+                         hIdx < kHeight;
+                         hIdx++, rasterHIdx++
+                            ){
+                        for (int wIdx = 0, rasterWIdx = j - xOrigin;
+                             wIdx < kWidth;
+                             wIdx++, rasterWIdx++
+                                ){
+                            int curIndex = rasterHIdx * rowLength + rasterWIdx * numBands;
+                            for (int idx=0; idx < numBands; idx++){
+                                newPixels[pixelIndex+idx] += data[kernelIdx] * pixels[curIndex+idx];
+                            }
+                            kernelIdx--;
+                        }
+                    }
+
+                    // Check for overflow now
+                    for (int idx=0; idx < numBands; idx++){
+                        if (((int)newPixels[pixelIndex+idx] & masks[idx]) != 0) {
+                            if (newPixels[pixelIndex+idx] < 0) {
+                                newPixels[pixelIndex+idx] = 0;
+                            } else {
+                                newPixels[pixelIndex+idx] = maxValues[idx];
+                            }
+                        }
+                    }
+                }
+            }
+
+            dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, newPixels);
+        } catch (Exception e) { // Something goes wrong, signal error
+            return 1;
+        }
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == null) {
+            // awt.259=Source image is null
+            throw new NullPointerException(Messages.getString("awt.259")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.25A=Source equals to destination
+            throw new IllegalArgumentException(Messages.getString("awt.25A")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (srcCM instanceof IndexColorModel) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                        !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                           src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                          (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                           dst.getType() == BufferedImage.TYPE_INT_ARGB))
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) { // Cannot skip channel, don't know which is alpha...
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippFilter32f(
+            kernel.data, kernel.getWidth(), kernel.getHeight(),
+            kernel.getXOrigin(), kernel.getYOrigin(), edgeCond,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            channels, skipChannel, offsets
+        );
+    }
+
+    /**
+     * Ipp filter32f.
+     * 
+     * @param kernel the kernel
+     * @param kWidth the k width
+     * @param kHeight the k height
+     * @param anchorX the anchor x
+     * @param anchorY the anchor y
+     * @param borderType the border type
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippFilter32f(
+                float kernel[], int kWidth, int kHeight,
+                int anchorX, int anchorY, int borderType,
+                Object src, int srcWidth, int srcHeight, int srcStride,
+                Object dst, int dstWidth, int dstHeight, int dstStride,
+                int channels, boolean skipChannel, int offsets[]
+            );
+}
+
diff --git a/awt/java/awt/image/CropImageFilter.java b/awt/java/awt/image/CropImageFilter.java
new file mode 100644
index 0000000..e90c44a
--- /dev/null
+++ b/awt/java/awt/image/CropImageFilter.java
@@ -0,0 +1,193 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The CropImageFilter class crops a rectangular region of an source
+ * Image and provides a source for a new image containing the extracted 
+ * region.
+ */
+public class CropImageFilter extends ImageFilter {
+
+    /** The HEIGHT. */
+    private final int X, Y, WIDTH, HEIGHT;
+
+    /**
+     * Instantiates a new CropImageFilter object with the specified
+     * rectangular area.
+     * 
+     * @param x the X coordinate of rectangular area. 
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     */
+    public CropImageFilter(int x, int y, int w, int h) {
+        X = x;
+        Y = y;
+        WIDTH = w;
+        HEIGHT = h;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Crop Filters"; //$NON-NLS-1$
+        String prop = "x=" + X + "; y=" + Y + "; width=" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        WIDTH + "; height=" + HEIGHT; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        consumer.setDimensions(WIDTH, HEIGHT);
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBuffer.java b/awt/java/awt/image/DataBuffer.java
new file mode 100644
index 0000000..6856aee
--- /dev/null
+++ b/awt/java/awt/image/DataBuffer.java
@@ -0,0 +1,442 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBuffer is a wrapper class for a data array
+ * to be used for the situation where a suite of functionality
+ * acts on a set of data in a consistent way even though the 
+ * primitive type of the data may vary from one use to the next. 
+ */
+public abstract class DataBuffer {
+
+    /** The Constant TYPE_BYTE. */
+    public static final int TYPE_BYTE = 0;
+
+    /** The Constant TYPE_USHORT. */
+    public static final int TYPE_USHORT = 1;
+
+    /** The Constant TYPE_SHORT. */
+    public static final int TYPE_SHORT = 2;
+
+    /** The Constant TYPE_INT. */
+    public static final int TYPE_INT = 3;
+
+    /** The Constant TYPE_FLOAT. */
+    public static final int TYPE_FLOAT = 4;
+
+    /** The Constant TYPE_DOUBLE. */
+    public static final int TYPE_DOUBLE = 5;
+
+    /** The Constant TYPE_UNDEFINED. */
+    public static final int TYPE_UNDEFINED = 32;
+
+    /** The data type indicates the primitive type of the 
+     * data in this DataBuffer. */
+    protected int dataType;
+
+    /** The number of data arrays in this DataBuffer. */
+    protected int banks;
+
+    /** The starting index for reading the 
+     * data from the first (or only) internal data array. */
+    protected int offset;
+
+    /** The length (number of elements) of the data arrays. */
+    protected int size;
+
+    /** The starting indices for reading the 
+     * data from the internal data arrays. */
+    protected int offsets[];
+    
+    /** The data changed. */
+    boolean dataChanged = true;
+    
+    /** The data taken. */
+    boolean dataTaken = false;
+    
+    /** The listener. */
+    DataBufferListener listener;
+
+    static {
+        AwtImageBackdoorAccessorImpl.init();
+    }
+
+    /**
+     * Instantiates a new data buffer.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offsets = offsets.clone();
+        this.offset = offsets[0];
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays starting at the same index.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offset the offset to use for all of the data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = offset;
+        this.offsets = new int[numBanks];
+        int i = 0;
+        while (i < numBanks) {
+            offsets[i++] = offset;
+        }
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    protected DataBuffer(int dataType, int size, int numBanks) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = 0;
+        this.offsets = new int[numBanks];
+    }
+
+    /**
+     * Instantiates a new data buffer with one internal data array
+     * read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     */
+    protected DataBuffer(int dataType, int size) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = 1;
+        this.offset = 0;
+        this.offsets = new int[1];
+    }
+
+    /**
+     * Sets the data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public abstract void setElem(int bank, int i, int val);
+
+    /**
+     * Sets the float data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int bank, int i, float val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the double data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int bank, int i, double val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElem(int i, int val) {
+        setElem(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the specified data array at the 
+     * specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public abstract int getElem(int bank, int i);
+
+    /**
+     * Gets the float-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Gets the double-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Sets the float data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int i, float val) {
+        setElemFloat(0, i, val);
+    }
+
+    /**
+     * Sets the double data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int i, double val) {
+        setElemDouble(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as an int.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public int getElem(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a float.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a double.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int i) {
+        return getElem(i);
+    }
+
+    /**
+     * Gets the array giving the offsets corresponding 
+     * to the internal data arrays.
+     * 
+     * @return the array of offsets
+     */
+    public int[] getOffsets() {
+        return offsets;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @return the size in bits of the primitive data type
+
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Gets the offset corresponding to the first internal 
+     * data array.
+     * 
+     * @return the offset
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of data arrays in this DataBuffer.
+     * 
+     * @return the number of data arrays
+     */
+    public int getNumBanks() {
+        return banks;
+    }
+
+    /**
+     * Gets the primitive type of this buffer's data.
+     * 
+     * @return the data type
+     */
+    public int getDataType() {
+        return this.dataType;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @param type the primitive type
+     * 
+     * @return the size in bits of the primitive data type
+     */
+    public static int getDataTypeSize(int type) {
+        switch (type) {
+
+        case TYPE_BYTE:
+            return 8;
+
+        case TYPE_USHORT:
+        case TYPE_SHORT:
+            return 16;
+
+        case TYPE_INT:
+        case TYPE_FLOAT:
+            return 32;
+
+        case TYPE_DOUBLE:
+            return 64;
+
+        default:
+            // awt.22C=Unknown data type {0}
+            throw new IllegalArgumentException(Messages.getString("awt.22C", type)); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has changed.
+     */
+    void notifyChanged(){
+        if(listener != null && !dataChanged){
+            dataChanged = true;
+            listener.dataChanged();
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has been released.
+     */
+    void notifyTaken(){
+        if(listener != null && !dataTaken){
+            dataTaken = true;
+            listener.dataTaken();
+        }
+    }
+    
+    /**
+     * Release the data.
+     */
+    void releaseData(){
+        if(listener != null && dataTaken){
+            dataTaken = false;
+            listener.dataReleased();
+        }
+    }
+    
+    /**
+     * Adds the data buffer listener.
+     * 
+     * @param listener the listener
+     */
+    void addDataBufferListener(DataBufferListener listener){
+        this.listener = listener;
+    }
+    
+    /**
+     * Removes the data buffer listener.
+     */
+    void removeDataBufferListener(){
+        listener = null;
+    }
+    
+    /**
+     * Validate.
+     */
+    void validate(){
+        dataChanged = false;
+    }
+    
+}
+
diff --git a/awt/java/awt/image/DataBufferByte.java b/awt/java/awt/image/DataBufferByte.java
new file mode 100644
index 0000000..4d29c9c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferByte.java
@@ -0,0 +1,171 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferByte is the subclass of DataBuffer
+ * for the case where the underlying data is of type byte.
+ */
+public final class DataBufferByte extends DataBuffer {
+
+    /** The data. */
+    byte data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size, int offsets[]) {
+        super(TYPE_BYTE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size) {
+        super(TYPE_BYTE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferByte(byte dataArray[], int size, int offset) {
+        super(TYPE_BYTE, size, 1, offset);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(byte dataArray[], int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferByte(int size, int numBanks) {
+        super(TYPE_BYTE, size, numBanks);
+        data = new byte[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new byte[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = new byte[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public byte[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public byte[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public byte[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBufferDouble.java b/awt/java/awt/image/DataBufferDouble.java
new file mode 100644
index 0000000..fa3d324
--- /dev/null
+++ b/awt/java/awt/image/DataBufferDouble.java
@@ -0,0 +1,214 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferDouble is the subclass of DataBuffer
+ * for the case where the underlying data is of type double.
+ */
+public final class DataBufferDouble extends DataBuffer {
+
+    /** The data. */
+    double data[][];
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+    */
+    public DataBufferDouble(double dataArrays[][], int size, int offsets[]) {
+        super(TYPE_DOUBLE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferDouble(double dataArrays[][], int size) {
+        super(TYPE_DOUBLE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferDouble(double dataArray[], int size, int offset) {
+        super(TYPE_DOUBLE, size, 1, offset);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(double dataArray[], int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferDouble(int size, int numBanks) {
+        super(TYPE_DOUBLE, size, numBanks);
+        data = new double[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new double[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = new double[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return (float) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public double[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return (float) (data[0][offset + i]);
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public double[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public double[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferFloat.java b/awt/java/awt/image/DataBufferFloat.java
new file mode 100644
index 0000000..e34245c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferFloat.java
@@ -0,0 +1,214 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferFloat is the subclass of DataBuffer
+ * for the case where the underlying data is float.
+ */
+public final class DataBufferFloat extends DataBuffer {
+
+    /** The data. */
+    float data[][];
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size, int offsets[]) {
+        super(TYPE_FLOAT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size) {
+        super(TYPE_FLOAT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferFloat(float dataArray[], int size, int offset) {
+        super(TYPE_FLOAT, size, 1, offset);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(float dataArray[], int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferFloat(int size, int numBanks) {
+        super(TYPE_FLOAT, size, numBanks);
+        data = new float[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new float[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = new float[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = (float) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = (float) val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired array
+     * 
+     * @return the data
+     */
+    public float[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return data[0][offset + i];
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public float[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public float[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferInt.java b/awt/java/awt/image/DataBufferInt.java
new file mode 100644
index 0000000..43dc188
--- /dev/null
+++ b/awt/java/awt/image/DataBufferInt.java
@@ -0,0 +1,170 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferInt is the subclass of DataBuffer
+ * for the case where the underlying data is of type int.
+ */
+public final class DataBufferInt extends DataBuffer {
+
+    /** The data. */
+    int data[][];
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size, int offsets[]) {
+        super(TYPE_INT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size) {
+        super(TYPE_INT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferInt(int dataArray[], int size, int offset) {
+        super(TYPE_INT, size, 1, offset);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int dataArray[], int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferInt(int size, int numBanks) {
+        super(TYPE_INT, size, numBanks);
+        data = new int[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new int[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = new int[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public int[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public int[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public int[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferShort.java b/awt/java/awt/image/DataBufferShort.java
new file mode 100644
index 0000000..819ba4a
--- /dev/null
+++ b/awt/java/awt/image/DataBufferShort.java
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferShort is the subclass of DataBuffer
+ * for the case where the underlying data is short.
+ */
+public final class DataBufferShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_SHORT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size) {
+        super(TYPE_SHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+
+     */
+    public DataBufferShort(short dataArray[], int size, int offset) {
+        super(TYPE_SHORT, size, 1, offset);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+
+     */
+    public DataBufferShort(short dataArray[], int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferShort(int size, int numBanks) {
+        super(TYPE_SHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]);
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]);
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferUShort.java b/awt/java/awt/image/DataBufferUShort.java
new file mode 100644
index 0000000..7982678
--- /dev/null
+++ b/awt/java/awt/image/DataBufferUShort.java
@@ -0,0 +1,182 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBufferUShort is the subclass of DataBuffer
+ * for the case where the underlying data is unsigned short.
+ */
+public final class DataBufferUShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_USHORT, size, dataArrays.length, offsets);
+        for(int i = 0; i < dataArrays.length; i++){
+            if(dataArrays[i].length < offsets[i] + size){
+                // awt.28d=Length of dataArray[{0}] is less than size + offset[{1}]
+                throw new IllegalArgumentException(Messages.getString("awt.28D", i, i));  //$NON-NLS-1$
+            }
+        }
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size) {
+        super(TYPE_USHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferUShort(short dataArray[], int size, int offset) {
+        super(TYPE_USHORT, size, 1, offset);
+        if(dataArray.length < size + offset){
+            // awt.28E=Length of dataArray is less than size + offset
+            throw new IllegalArgumentException(Messages.getString("awt.28E")); //$NON-NLS-1$
+        }
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(short dataArray[], int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferUShort(int size, int numBanks) {
+        super(TYPE_USHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i= 0;
+        while( i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DirectColorModel.java b/awt/java/awt/image/DirectColorModel.java
new file mode 100644
index 0000000..7a287c0
--- /dev/null
+++ b/awt/java/awt/image/DirectColorModel.java
@@ -0,0 +1,862 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+import java.awt.Transparency;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DirectColorModel represents a standard (packed) RGB
+ * color model with additional support for converting between sRGB
+ * color space and 8 or 16 bit linear RGB color space using lookup tables.
+ */
+public class DirectColorModel extends PackedColorModel {
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
+                                        // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];  // Lookup table for conversion from
+                                        // sRGB Color Space into Linear RGB 
+                                        // 8 bit
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[];  // Lookup table for conversion from
+                                          // sRGB Color Space into Linear RGB 
+                                          // 16 bit 
+
+    /** The alpha lut. */
+    private byte alphaLUT[];            // Lookup table for scale alpha value  
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];         // Lookup tables for scale color values 
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;            // ColorModel has sRGB ColorSpace
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;      // Color Model has Linear RGB Color 
+                                        // Space
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;      // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;              // Scale factor
+
+    /**
+     * Instantiates a new direct color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public DirectColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied,
+            int transferType) {
+
+        super(space, bits, rmask, gmask, bmask, amask, isAlphaPremultiplied,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                transferType);
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model, determining the transfer 
+     * type from the bits array, the transparency from the alpha mask, 
+     * and the default color space {@link ColorSpace#CS_sRGB}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask,
+            int amask) {
+
+        super(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask,
+                bmask, amask, false,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                ColorModel.getTransferType(bits));
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model with no alpha channel, 
+     * determining the transfer type from the bits array, 
+     * the default color space {@link ColorSpace#CS_sRGB}, 
+     * and with the transparency set to {@link Transparency#OPAQUE}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
+        this(bits, rmask, gmask, bmask, 0);
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) obj;
+            }
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) obj;
+            }
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) obj;
+            }
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+
+        return obj;
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        if (equals(ColorModel.getRGBdefault())) {
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = rgb;
+            return ia;
+        }
+
+        int alpha = (rgb >> 24) & 0xff;
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+
+        float comp[] = new float[numColorComponents];
+        float normComp[] = null;
+
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float rgbComp[] = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = rgbComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = rgbComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+
+        int pxl = 0;
+        if (hasAlpha) {
+            float normAlpha = normComp[numColorComponents];
+            alpha = (int) (normAlpha * maxValues[numColorComponents] + 0.5f);
+            if (isAlphaPremultiplied) {
+                red = (int) (normComp[0] * normAlpha * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * normAlpha * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * normAlpha * maxValues[2] + 0.5f);
+            } else {
+                red = (int) (normComp[0] * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+            }
+            pxl = (alpha << offsets[3]) & componentMasks[3];
+        } else {
+            red = (int) (normComp[0] * maxValues[0] + 0.5f);
+            green = (int) (normComp[1] * maxValues[1] + 0.5f);
+            blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+        }
+
+        pxl |= ((red << offsets[0]) & componentMasks[0]) |
+               ((green << offsets[1]) & componentMasks[1]) |
+               ((blue << offsets[2]) & componentMasks[2]);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (pixel == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) pixel;
+            }
+            ba[0] = (byte) pxl;
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (pixel == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) pixel;
+            }
+            sa[0] = (short) pxl;
+            return sa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = pxl;
+            return ia;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public final ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        int components[] = null;
+        int transparentComponents[] = new int[numComponents];
+
+        float alphaFactor = maxValues[numColorComponents];
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, transparentComponents);
+                        } else {
+                            float alpha =
+                                components[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] != 0) {
+                            float alpha =
+                                alphaFactor / components[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+
+        }
+
+        return new DirectColorModel(cs, pixel_bits, componentMasks[0],
+                componentMasks[1], componentMasks[2], componentMasks[3],
+                isAlphaPremultiplied, transferType);
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
+               Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[2]) + " amask = " + //$NON-NLS-1$
+               (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public final int[] getComponents(Object pixel, int components[],
+            int offset) {
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+
+        int intPixel = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            intPixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            intPixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            intPixel = ia[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+        }
+
+        return getComponents(intPixel, components, offset);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRed(pixel);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRGB(pixel);
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getGreen(pixel);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getBlue(pixel);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getAlpha(pixel);
+    }
+
+    @Override
+    public final WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        int bandMasks[] = componentMasks.clone();
+
+        if (pixel_bits > 16) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h,
+                    bandMasks, null);
+        } else if (pixel_bits > 8) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w, h,
+                    bandMasks, null);
+        } else {
+            return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    bandMasks, null);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+
+        if (sppsm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int maskBands[] = sppsm.getBitMasks();
+        return Arrays.equals(maskBands, componentMasks);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+        return pixel;
+    }
+
+    @Override
+    public final int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+        for (int i = 0; i < numComponents; i++) {
+            components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
+        }
+        return components;
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 0);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 0);
+        }
+        return getComponentFrom_RGB(pixel, 0);
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 1);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 1);
+        }
+        return getComponentFrom_RGB(pixel, 1);
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 2);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 2);
+        }
+        return getComponentFrom_RGB(pixel, 2);
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int a = (pixel & componentMasks[3]) >>> offsets[3];
+        if (bits[3] == 8) {
+            return a;
+        }
+        return alphaLUT[a] & 0xff;
+    }
+
+    /**
+     * Gets the red mask.
+     * 
+     * @return the red mask
+     */
+    public final int getRedMask() {
+        return componentMasks[0];
+    }
+
+    /**
+     * Gets the green mask.
+     * 
+     * @return the green mask
+     */
+    public final int getGreenMask() {
+        return componentMasks[1];
+    }
+
+    /**
+     * Gets the blue mask.
+     * 
+     * @return the blue mask
+     */
+    public final int getBlueMask() {
+        return componentMasks[2];
+    }
+
+    /**
+     * Gets the alpha mask.
+     * 
+     * @return the alpha mask
+     */
+    public final int getAlphaMask() {
+        if (hasAlpha) {
+            return componentMasks[3];
+        }
+        return 0;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (hasAlpha && bits[3] != 8) {
+            alphaLUT = new byte[maxValues[3] + 1];
+            for (int i = 0; i <= maxValues[3]; i++) {
+                alphaLUT[i] = (byte) (scales[3] * i + 0.5f);
+            }
+
+        }
+
+        if (!isAlphaPremultiplied) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[i]; j++) {
+                            colorLUTs[i][j] = (byte) (scales[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scales[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scales[i] * j * 257.0f + 0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * sRGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_sRGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            int alpha = (pixel & componentMasks[3]) >>> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * 255.0f /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != 8) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * Linear RGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            float factor = ((1 << LINEAR_RGB_Length) - 1);
+            int alpha = (pixel & componentMasks[3]) >> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * factor /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != LINEAR_RGB_Length) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        } else {
+            comp = from_LINEAR_RGB_LUT[comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * arbitrary RGB ColorSapce.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_RGB(int pixel, int idx) {
+        int components[] = getComponents(pixel, null, 0);
+        float[] normComponents = getNormalizedComponents(components, 0, null, 0);
+        float[] sRGBcomponents = cs.toRGB(normComponents);
+        return (int) (sRGBcomponents[idx] * 255.0f + 0.5f);
+    }
+
+}
+
diff --git a/awt/java/awt/image/FilteredImageSource.java b/awt/java/awt/image/FilteredImageSource.java
new file mode 100644
index 0000000..6a41fa7
--- /dev/null
+++ b/awt/java/awt/image/FilteredImageSource.java
@@ -0,0 +1,88 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+
+/**
+ * The FilteredImageSource class is used for producing image data for a new 
+ * filtered version of the original image using the specified filter object. 
+ */
+public class FilteredImageSource implements ImageProducer {
+
+    /** The source. */
+    private final ImageProducer source;
+    
+    /** The filter. */
+    private final ImageFilter filter;
+
+    /** The cons table. */
+    private final Hashtable<ImageConsumer, ImageConsumer> consTable = new Hashtable<ImageConsumer, ImageConsumer>();
+
+    /**
+     * Instantiates a new FilteredImageSource object with 
+     * the specified ImageProducer and the ImageFilter objects.
+     * 
+     * @param orig the specified ImageProducer.
+     * @param imgf the specified ImageFilter.
+     */
+    public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
+        source = orig;
+        filter = imgf;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            return consTable.containsKey(ic);
+        }
+        return false;
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        ImageConsumer fic = consTable.get(ic);
+        source.startProduction(fic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageFilter fic = (ImageFilter) consTable.get(ic);
+            fic.resendTopDownLeftRight(source);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageConsumer fic = consTable.get(ic);
+            source.removeConsumer(fic);
+            consTable.remove(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !isConsumer(ic)){
+            ImageConsumer fic = filter.getFilterInstance(ic);
+            source.addConsumer(fic);
+            consTable.put(ic, fic);
+        }
+    }
+}
diff --git a/awt/java/awt/image/ImageConsumer.java b/awt/java/awt/image/ImageConsumer.java
new file mode 100644
index 0000000..2eba290
--- /dev/null
+++ b/awt/java/awt/image/ImageConsumer.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageConsumer interface provides the data about the image
+ * and about how its data is delivered.  A ImageProducer provides 
+ * all of the information about the image using 
+ * the methods defined in this interface.
+ */
+public interface ImageConsumer {
+
+    /** 
+     * The Constant RANDOMPIXELORDER indicates that the pixels are 
+     * delivered in a random order.
+     */
+    public static final int RANDOMPIXELORDER = 1;
+
+    /** 
+     * The Constant TOPDOWNLEFTRIGHT indicates that the pixels are 
+     * delivered in top-down, left-to-right order. 
+     */
+    public static final int TOPDOWNLEFTRIGHT = 2;
+
+    /** 
+     * The Constant COMPLETESCANLINES indicates that the pixels are
+     * delivered in complete scanline. 
+     */
+    public static final int COMPLETESCANLINES = 4;
+
+    /** 
+     * The Constant SINGLEPASS indicates that pixels are delivered 
+     * in a single pass. 
+     */
+    public static final int SINGLEPASS = 8;
+
+    /** 
+     * The Constant SINGLEFRAME indicates that image consists of
+     * single frame.
+     */
+    public static final int SINGLEFRAME = 16;
+
+    /** 
+     * The Constant IMAGEERROR indicates an image error during image producing.
+     */
+    public static final int IMAGEERROR = 1;
+
+    /** 
+     * The Constant SINGLEFRAMEDONE indicates that only one of the 
+     * image's frames is completed. 
+     */
+    public static final int SINGLEFRAMEDONE = 2;
+
+    /** 
+     * The Constant STATICIMAGEDONE indicates that the image is completed. 
+     */
+    public static final int STATICIMAGEDONE = 3;
+
+    /** 
+     * The Constant IMAGEABORTED indicates that the image producing 
+     * process is aborted. 
+     */
+    public static final int IMAGEABORTED = 4;
+
+    /**
+     * Sets the properties for the image associated with this ImageConsumer.
+     * 
+     * @param props the properties for the image associated with 
+     * this ImageConsumer.
+     */
+    public void setProperties(Hashtable<?, ?> props);
+
+    /**
+     * Sets the ColorModel object.
+     * 
+     * @param model the new ColorModel.
+     */
+    public void setColorModel(ColorModel model);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            int[] pixels, int off, int scansize);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            byte[] pixels, int off, int scansize);
+
+    /**
+     * Sets the dimensions of a source image.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     */
+    public void setDimensions(int width, int height);
+
+    /**
+     * Sets the hint flags of pixels order, which is used by 
+     * the ImageConsumer for obtaining pixels from the ImageProducer
+     * for which this ImageConsumer is added.
+     * 
+     * @param hintflags the mask of hint flags. 
+     */
+    public void setHints(int hintflags);
+
+    /**
+     * THis method is called in the one of the following cases:
+     * <ul>
+     * <li>The ImageProducer (for which this ImageConsumer is added) 
+     * has been delivered all pixels of the source image. </li>
+     * <li>A one frame of an animation has been completed. </li> 
+     * <li> An error while loading or producing of the image has occured.
+     * </ul> 
+     * 
+     * @param status the status of image producing.
+     */
+    public void imageComplete(int status);
+
+}
+
diff --git a/awt/java/awt/image/ImageFilter.java b/awt/java/awt/image/ImageFilter.java
new file mode 100644
index 0000000..e386d65
--- /dev/null
+++ b/awt/java/awt/image/ImageFilter.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageFilter class provides a filter for delivering image data 
+ * from an ImageProducer to an ImageConsumer.
+ */
+public class ImageFilter implements ImageConsumer, Cloneable {
+
+    /** The consumer. */
+    protected ImageConsumer consumer;
+
+    /**
+     * Instantiates a new ImageFilter.
+     */
+    public ImageFilter() {
+        super();
+    }
+
+    /**
+     * Gets an instance of an ImageFilter object which performs
+     * the filtering for the specified ImageConsumer.
+     *  
+     * @param ic the specified ImageConsumer.
+     * 
+     * @return an ImageFilter used to perform the filtering for 
+     * the specified ImageConsumer.
+     */
+    public ImageFilter getFilterInstance(ImageConsumer ic) {
+        ImageFilter filter = (ImageFilter) clone();
+        filter.consumer = ic;
+        return filter;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Filters"; //$NON-NLS-1$
+        String prop = "Null filter"; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String) o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    /**
+     * Returns a copy of this ImageFilter.
+     * 
+     * @return a copy of this ImageFilter.
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Responds to a request for a Top-Down-Left-Right ordered 
+     * resend of the pixel data from an ImageConsumer. 
+     * 
+     * @param ip the ImageProducer that provides this instance of 
+     * the filter.
+     */
+    public void resendTopDownLeftRight(ImageProducer ip) {
+        ip.requestTopDownLeftRightResend(this);
+    }
+
+    public void setColorModel(ColorModel model) {
+        consumer.setColorModel(model);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setDimensions(int width, int height) {
+        consumer.setDimensions(width, height);
+    }
+
+    public void setHints(int hints) {
+        consumer.setHints(hints);
+    }
+
+    public void imageComplete(int status) {
+        consumer.imageComplete(status);
+    }
+
+}
diff --git a/awt/java/awt/image/ImageObserver.java b/awt/java/awt/image/ImageObserver.java
new file mode 100644
index 0000000..418bd07
--- /dev/null
+++ b/awt/java/awt/image/ImageObserver.java
@@ -0,0 +1,99 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+
+/**
+ * the ImageObserver interface is an asynchronous update interface 
+ * for receiving notifications about Image construction status.
+ */
+public interface ImageObserver {
+
+    /** 
+     * The Constant WIDTH indicates that the width of the image is 
+     * available. 
+     */
+    public static final int WIDTH = 1;
+
+    /** 
+     * The Constant HEIGHT indicates that the width of the image is 
+     * available.
+     */
+    public static final int HEIGHT = 2;
+
+    /** 
+     * The Constant PROPERTIES indicates that the properties of the image
+     * are available. 
+     */
+    public static final int PROPERTIES = 4;
+
+    /**
+     *  The Constant SOMEBITS indicates that more bits needed for 
+     *  drawing a scaled variation of the image pixels are available.
+     */
+    public static final int SOMEBITS = 8;
+
+    /** 
+     * The Constant FRAMEBITS indicates that complete frame of 
+     * a image which was previously drawn is now available
+     * for drawing again. 
+     */
+    public static final int FRAMEBITS = 16;
+
+    /** 
+     * The Constant ALLBITS indicates that an image which 
+     * was previously drawn is now complete and can be drawn again. 
+     */
+    public static final int ALLBITS = 32;
+
+    /** 
+     * The Constant ERROR indicates that error occured. 
+     */
+    public static final int ERROR = 64;
+
+    /** 
+     * The Constant ABORT indicates that the image producing is 
+     * aborted.
+     */
+    public static final int ABORT = 128;
+
+    /**
+     * This method is called when information about an Image
+     * interface becomes available. This method returns true 
+     * if further updates are needed, false if not.
+     * 
+     * @param img the image to be observed.
+     * @param infoflags the bitwise OR combination of information flags:
+     * ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, 
+     * WIDTH.
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @return true if further updates are needed, false if not.
+     */
+    public boolean imageUpdate(Image img, int infoflags, int x, int y,
+            int width, int height);
+
+}
+
diff --git a/awt/java/awt/image/ImageProducer.java b/awt/java/awt/image/ImageProducer.java
new file mode 100644
index 0000000..557ae08
--- /dev/null
+++ b/awt/java/awt/image/ImageProducer.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The ImageProducer provides an interface for objects which produce
+ * the image data. ImageProducer is used for reconstructing the 
+ * image. Each image contains an ImageProducer. 
+ */
+public interface ImageProducer {
+
+    /**
+     * Checks if the specified ImageConsumer is registered with this 
+     * ImageProvider or not.
+     * 
+     * @param ic the ImageConsumer to be checked.
+     * 
+     * @return true, if the specified ImageConsumer is registered with this 
+     * ImageProvider, false otherwise.
+     */
+    public boolean isConsumer(ImageConsumer ic);
+
+    /**
+     * Starts a reconstruction of the image data which will 
+     * be delivered to this consumer. This method addes the
+     * specified ImageConsumer before reconstructing the image.  
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void startProduction(ImageConsumer ic);
+
+    /**
+     * Requests the ImageProducer to resend the image data 
+     * in ImageConsumer.TOPDOWNLEFTRIGHT order.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void requestTopDownLeftRightResend(ImageConsumer ic);
+
+    /**
+     * Deregisters the specified ImageConsumer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void removeConsumer(ImageConsumer ic);
+
+    /**
+     * Adds the specified ImageConsumer object to this ImageProducer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void addConsumer(ImageConsumer ic);
+
+}
+
diff --git a/awt/java/awt/image/ImagingOpException.java b/awt/java/awt/image/ImagingOpException.java
new file mode 100644
index 0000000..ebcaba4
--- /dev/null
+++ b/awt/java/awt/image/ImagingOpException.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 5, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ImagingOpException class provides error notification when 
+ * the BufferedImageOp or RasterOp filter methods can not perform
+ * the desired filter operation.
+ */
+public class ImagingOpException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8026288481846276658L;
+
+    /**
+     * Instantiates a new ImagingOpException with a detail message.
+     * 
+     * @param s the detail message.
+     */
+    public ImagingOpException(String s) {
+        super(s);
+    }
+}
diff --git a/awt/java/awt/image/IndexColorModel.java b/awt/java/awt/image/IndexColorModel.java
new file mode 100644
index 0000000..a7043f4
--- /dev/null
+++ b/awt/java/awt/image/IndexColorModel.java
@@ -0,0 +1,1020 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class IndexColorModel represents a color model in which the 
+ * color values of the pixels are read from a palette.
+ */
+public class IndexColorModel extends ColorModel {
+
+    /** The color map. */
+    private int colorMap[];        // Color Map  
+
+    /** The map size. */
+    private int mapSize;           // Color Map size
+
+    /** The transparent index. */
+    private int transparentIndex;  // Index of fully transparent pixel
+
+    /** The gray palette. */
+    private boolean grayPalette;   // Color Model has Color Map with Gray Pallete
+
+    /** The valid bits. */
+    private BigInteger validBits;  // Specify valid Color Map values
+
+    /** The Constant CACHESIZE. */
+    private static final int CACHESIZE = 20; // Cache size. Cache used for 
+                                             // improving performace of selection
+                                             // nearest color in Color Map
+
+    /** The cachetable. */
+    private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table - used for 
+                               // storing RGB values and that appropriate indices 
+                               // in the Color Map 
+                    
+
+    /** The next insert idx. */
+    private int nextInsertIdx = 0;  // Next index for insertion into Cache table
+
+    /** The total inserted. */
+    private int totalInserted = 0;  // Number of inserted values into Cache table
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * @param validBits a list of which bits represent valid colormap 
+     * values, or null if all are valid
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            int transferType, BigInteger validBits) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE, validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        if (validBits != null) {
+            for (int i = 0; i < mapSize; i++) {
+                if (!validBits.testBit(i)) {
+                    this.validBits = validBits;
+                }
+                break;
+            }
+        }
+
+        transparency = Transparency.OPAQUE;
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            colorMap[i] = cmap[start];
+            alpha = cmap[start] & alphaMask;
+
+            if (alpha == alphaMask) {
+                continue;
+            }
+            if (alpha == 0) {
+                if (transparentIndex < 0) {
+                    transparentIndex = i;
+                }
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+            } else if (alpha != alphaMask &&
+                    transparency != Transparency.TRANSLUCENT) {
+                transparency = Transparency.TRANSLUCENT;
+            }
+
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            boolean hasalpha, int trans, int transferType) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+            transparency = Transparency.BITMASK;
+        } else {
+            transparentIndex = -1;
+            transparency = Transparency.OPAQUE;
+        }
+
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            if (transparentIndex == i) {
+                colorMap[i] = cmap[start] & 0x00ffffff;
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start] & alphaMask;
+                colorMap[i] = cmap[start];
+
+                if (alpha == alphaMask) {
+                    continue;
+                }
+                if (alpha == 0) {
+                    if (trans < 0) {
+                        trans = i;
+                    }
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                } else if (alpha != 0
+                        && transparency != Transparency.TRANSLUCENT) {
+                    transparency = Transparency.TRANSLUCENT;
+                }
+            } else {
+                colorMap[i] = alphaMask | cmap[start];
+            }
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, blue, and alpha values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param a the array giving the alpha components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            byte a[]) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, a, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            int trans) {
+
+        super(bits, IndexColorModel.createBits((trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), (trans >= 0), false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, trans);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
+        super(bits, IndexColorModel.createBits(false),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha, int trans) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        transparency = Transparency.OPAQUE;
+        int alpha = 0xff000000;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = (cmap[start++] & 0xff) << 16 |
+                   (cmap[start++] & 0xff) << 8 | (cmap[start++] & 0xff);
+            if (trans == i) {
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+                if(hasalpha) {
+                    start++;
+                }
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start++] & 0xff;
+                if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                        if (trans < 0) {
+                            trans = i;
+                        }
+                    }
+                } else {
+                    if (alpha != 0xff &&
+                           transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+                alpha <<= 24;
+            }
+            colorMap[i] |= alpha;
+        }
+
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha) {
+
+        this(bits, size, cmap, start, hasalpha, -1);
+    }
+
+    @Override
+    public Object getDataElements(int[] components, int offset, Object pixel) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8 |
+               components[offset + 2];
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+        return getDataElements(rgb, pixel);
+    }
+
+    @Override
+    public synchronized Object getDataElements(int rgb, Object pixel) {
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = rgb >>> 24;
+        int pixIdx = 0;
+
+        for (int i = 0; i < totalInserted; i++) {
+            int idx = i * 2;
+            if (rgb == cachetable[idx]) {
+                return createDataObject(cachetable[idx + 1], pixel);
+            }
+        }
+
+        if (!hasAlpha && grayPalette) {
+            int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
+            int minError = 255;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                error = Math.abs((colorMap[i] & 0xff) - grey);
+                if (error < minError) {
+                    pixIdx = i;
+                    if (error == 0) {
+                        break;
+                    }
+                    minError = error;
+                }
+            }
+        } else if (alpha == 0 && transparentIndex > -1) {
+            pixIdx = transparentIndex;
+        } else  {
+            int minAlphaError = 255;
+            int minError = 195075; // 255^2 + 255^2 + 255^2
+            int alphaError;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                int pix = colorMap[i];
+                if (rgb == pix) {
+                    pixIdx = i;
+                    break;
+                }
+                alphaError = Math.abs(alpha - (pix >>> 24));
+                if (alphaError <= minAlphaError) {
+                    minAlphaError = alphaError;
+
+                    int buf = ((pix >> 16) & 0xff) - red;
+                    error = buf * buf;
+
+                    if (error < minError) {
+                        buf = ((pix >> 8) & 0xff) - green;
+                        error += buf * buf;
+
+                        if (error < minError) {
+                            buf = (pix & 0xff) - blue;
+                            error += buf * buf;
+
+                            if (error < minError) {
+                                pixIdx = i;
+                                minError = error;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        cachetable[nextInsertIdx] = rgb;
+        cachetable[nextInsertIdx + 1] = pixIdx;
+
+        nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
+        if (totalInserted < CACHESIZE) {
+            totalInserted++;
+        }
+
+        return createDataObject(pixIdx, pixel);
+    }
+
+    /**
+     * Converts an image from indexed to RGB format.
+     * 
+     * @param raster the raster containing the source image
+     * @param forceARGB whether to use the default RGB color model
+     * 
+     * @return the buffered image
+     * 
+     * @throws IllegalArgumentException if the raster is not compatible with 
+     * this color model
+     */
+    public BufferedImage convertToIntDiscrete(Raster raster,
+            boolean forceARGB) {
+
+        if (!isCompatibleRaster(raster)) {
+            // awt.265=The raster argument is not compatible with this IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
+        }
+
+        ColorModel model;
+        if (forceARGB || transparency == Transparency.TRANSLUCENT) {
+            model = ColorModel.getRGBdefault();
+        } else if (transparency == Transparency.BITMASK) {
+            model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0x01000000);
+        } else {
+            model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
+        }
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        Object obj = null;
+        int pixels[] = null;
+
+        for (int i = 0; i < h; i++, minY++) {
+            obj = raster.getDataElements(minX, minY, w, 1, obj);
+            if (obj instanceof byte[]) {
+                byte ba[] = (byte[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ba.length];
+                }
+                for (int j = 0; j < ba.length; j++) {
+                    pixels[j] = colorMap[ba[j] & 0xff];
+                }
+            } else if (obj instanceof short[]) {
+                short sa[] = (short[]) obj;
+                if (pixels == null) {
+                    pixels = new int[sa.length];
+                }
+                for (int j = 0; j < sa.length; j++) {
+                    pixels[j] = colorMap[sa[j] & 0xffff];
+                }
+            }
+            if (obj instanceof int[]) {
+                int ia[] = (int[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ia.length];
+                }
+                for (int j = 0; j < ia.length; j++) {
+                    pixels[j] = colorMap[ia[j]];
+                }
+            }
+
+            distRaster.setDataElements(0, i, w, 1, pixels);
+        }
+
+        return new BufferedImage(model, distRaster, false, null);
+    }
+
+    /**
+     * Gets the valid pixels.
+     * 
+     * @return the valid pixels
+     */
+    public BigInteger getValidPixels() {
+        return validBits;
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
+               " numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
+               " transparency = "; //$NON-NLS-1$
+
+        if (transparency == Transparency.OPAQUE) {
+            str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
+        } else if (transparency == Transparency.BITMASK) {
+            str = str + "Transparency.BITMASK"; //$NON-NLS-1$
+        } else {
+            str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
+        }
+
+        str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
+               hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int components[], int offset) {
+        int pixIdx = -1;
+        if (pixel instanceof byte[]) {
+            byte ba[] = (byte[]) pixel;
+            pixIdx = ba[0] & 0xff;
+        } else if (pixel instanceof short[]) {
+            short sa[] = (short[]) pixel;
+            pixIdx = sa[0] & 0xffff;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            pixIdx = ia[0];
+        } else {
+            // awt.219=This transferType is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+        }
+
+        return getComponents(pixIdx, components, offset);
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        WritableRaster raster;
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1,
+                    pixel_bits, null);
+        } else if (pixel_bits <= 8) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    1, null);
+        } else if (pixel_bits <= 16) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w,
+                    h, 1, null);
+        } else {
+            // awt.266=The number of bits in a pixel is greater than 16
+            throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
+        }
+
+        return raster;
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+
+        if (!(sm instanceof MultiPixelPackedSampleModel)
+                && !(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getTransferType() != transferType) {
+            return false;
+        }
+        if (sm.getNumBands() != 1) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h,
+                    pixel_bits);
+        }
+        int bandOffsets[] = new int[1];
+        bandOffsets[0] = 0;
+        return new ComponentSampleModel(transferType, w, h, 1, w,
+                bandOffsets);
+
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        int sampleSize = raster.getSampleModel().getSampleSize(0);
+        return (raster.getTransferType() == transferType &&
+               raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
+                | components[offset + 2];
+        
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+ 
+        int pixel;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) getDataElements(rgb, null);
+            pixel = ba[0] & 0xff;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) getDataElements(rgb, null);
+            pixel = sa[0] & 0xffff;
+            break;
+        default:
+            // awt.267=The transferType is invalid
+            throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Gets the color map.
+     * 
+     * @param rgb the destination array where the color map is written
+     */
+    public final void getRGBs(int rgb[]) {
+        System.arraycopy(colorMap, 0, rgb, 0, mapSize);
+    }
+
+    /**
+     * Gets the red component of the color map.
+     * 
+     * @param r the destination array
+     */
+    public final void getReds(byte r[]) {
+        for (int i = 0; i < mapSize; i++) {
+            r[i] = (byte) (colorMap[i] >> 16);
+        }
+    }
+
+    /**
+     * Gets the green component of the color map.
+     * 
+     * @param g the destination array
+     */
+    public final void getGreens(byte g[]) {
+        for (int i = 0; i < mapSize; i++) {
+            g[i] = (byte) (colorMap[i] >> 8);
+        }
+    }
+
+    /**
+     * Gets the blue component of the color map.
+     * 
+     * @param b the destination array
+     */
+    public final void getBlues(byte b[]) {
+        for (int i = 0; i < mapSize; i++) {
+            b[i] = (byte) colorMap[i];
+        }
+    }
+
+    /**
+     * Gets the alpha component of the color map.
+     * 
+     * @param a the destination array
+     */
+    public final void getAlphas(byte a[]) {
+        for (int i = 0; i < mapSize; i++) {
+            a[i] = (byte) (colorMap[i] >> 24);
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[offset + numComponents];
+        }
+
+        components[offset + 0] = getRed(pixel);
+        components[offset + 1] = getGreen(pixel);
+        components[offset + 2] = getBlue(pixel);
+        if (hasAlpha && (components.length - offset) > 3) {
+            components[offset + 3] = getAlpha(pixel);
+        }
+
+        return components;
+    }
+
+    /**
+     * Checks if the specified pixel is valid for this color model.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return true, if the pixel is valid
+     */
+    public boolean isValid(int pixel) {
+        if (validBits == null) {
+            return (pixel >= 0 && pixel < mapSize);
+        }
+        return (pixel < mapSize && validBits.testBit(pixel));
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        return (colorMap[pixel] >> 16) & 0xff;
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return colorMap[pixel];
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        return (colorMap[pixel] >> 8) & 0xff;
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        return colorMap[pixel] & 0xff;
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        return (colorMap[pixel] >> 24) & 0xff;
+    }
+
+    @Override
+    public int[] getComponentSize() {
+        return bits.clone();
+    }
+
+    /**
+     * Checks if this color model validates pixels.
+     * 
+     * @return true, if all pixels are valid, otherwise false
+     */
+    public boolean isValid() {
+        return (validBits == null);
+    }
+
+    @Override
+    public void finalize() {
+        // TODO: implement
+        return;
+    }
+
+    /**
+     * Gets the index that represents the transparent pixel.
+     * 
+     * @return the index that represents the transparent pixel
+     */
+    public final int getTransparentPixel() {
+        return transparentIndex;
+    }
+
+    @Override
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the size of the color map.
+     * 
+     * @return the map size
+     */
+    public final int getMapSize() {
+        return mapSize;
+    }
+
+    /**
+     * Creates the color map.
+     * 
+     * @param size the size
+     * @param r the r
+     * @param g the g
+     * @param b the b
+     * @param a the a
+     * @param trans the trans
+     */
+    private void createColorMap(int size, byte r[], byte g[], byte b[],
+            byte a[], int trans) {
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparency = Transparency.BITMASK;
+            transparentIndex = trans;
+        } else {
+            transparency = Transparency.OPAQUE;
+            transparentIndex = -1;
+        }
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) |
+                   (b[i] & 0xff);
+
+            if (trans == i) {
+                continue;
+            }
+
+            if (a == null) {
+                colorMap[i] |= 0xff000000;
+            } else {
+                alpha = a[i] & 0xff;
+                if (alpha == 0xff) {
+                    colorMap[i] |= 0xff000000;
+                } else if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                    if (transparentIndex < 0) {
+                        transparentIndex = i;
+                    }
+                } else {
+                    colorMap[i] |= (a[i] & 0xff) << 24;
+                    if (transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * This method checking, if Color Map has Gray Palette.
+     */
+    private void checkPalette() {
+        grayPalette = false;
+        if (transparency > Transparency.OPAQUE) {
+            return;
+        }
+        int rgb = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            rgb = colorMap[i];
+            if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) ||
+                   ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
+                return;
+            }
+        }
+        grayPalette = true;
+    }
+
+    /**
+     * Construction an array pixel representation.
+     * 
+     * @param colorMapIdx - index into Color Map
+     * @param pixel - pixel
+     * 
+     * @return - an array pixel representation
+     */
+    private Object createDataObject(int colorMapIdx, Object pixel) {
+        if (pixel == null) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte[] ba = new byte[1];
+                ba[0] = (byte) colorMapIdx;
+                pixel = ba;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short[] sa = new short[1];
+                sa[0] = (short) colorMapIdx;
+                pixel = sa;
+                break;
+            default:
+                // awt.267=The transferType is invalid
+                throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+            }
+        } else if (pixel instanceof byte[]
+                && transferType == DataBuffer.TYPE_BYTE) {
+            byte ba[] = (byte[]) pixel;
+            ba[0] = (byte) colorMapIdx;
+            pixel = ba;
+        } else if (pixel instanceof short[]&&
+                transferType == DataBuffer.TYPE_USHORT) {
+            short[] sa = (short[]) pixel;
+            sa[0] = (short) colorMapIdx;
+            pixel = sa;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            ia[0] = colorMapIdx;
+            pixel = ia;
+        } else {
+            // awt.268=The pixel is not a primitive array of type transferType
+            throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
+        }
+        return pixel;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param hasAlpha the has alpha
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(boolean hasAlpha) {
+
+        int numChannels;
+        if (hasAlpha) {
+            numChannels = 4;
+        } else {
+            numChannels = 3;
+        }
+
+        int bits[] = new int[numChannels];
+        for (int i = 0; i < numChannels; i++) {
+            bits[i] = 8;
+        }
+
+        return bits;
+
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+               transferType != DataBuffer.TYPE_USHORT) {
+            // awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+            throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
+        }
+        return transferType;
+    }
+
+    /**
+     * Checks if is gray pallete.
+     * 
+     * @return true, if is gray pallete
+     */
+    boolean isGrayPallete(){
+        return grayPalette;
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
new file mode 100644
index 0000000..c6f00e2
--- /dev/null
+++ b/awt/java/awt/image/Kernel.java
@@ -0,0 +1,138 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 28, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Kernel class provides a matrix. This matrix is stored as a float array
+ * which describes how a specified pixel affects the value calculated for 
+ * the pixel's position in the output image of a filtering operation. 
+ * The X, Y origins indicate the kernel matrix element which corresponds to 
+ * the pixel position for which an output value is being calculated.
+ */
+public class Kernel implements Cloneable {
+    
+    /** The x origin. */
+    private final int xOrigin;
+    
+    /** The y origin. */
+    private final int yOrigin;
+    
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+    
+    /** The data. */
+    float data[];
+
+    /**
+     * Instantiates a new Kernel with the specified float array.
+     * The width*height elements of the data array are copied. 
+     * 
+     * @param width the width of the Kernel.
+     * @param height the height of the Kernel.
+     * @param data the data of Kernel.
+     */
+    public Kernel(int width, int height, float[] data) {
+        int dataLength = width*height;
+        if (data.length < dataLength) {
+            // awt.22B=Length of data should not be less than width*height
+            throw new IllegalArgumentException(Messages.getString("awt.22B")); //$NON-NLS-1$
+        }
+
+        this.width = width;
+        this.height = height;
+
+        this.data = new float[dataLength];
+        System.arraycopy(data, 0, this.data, 0, dataLength);
+
+        xOrigin = (width-1)/2;
+        yOrigin = (height-1)/2;
+    }
+
+    /**
+     * Gets the width of this Kernel.
+     * 
+     * @return the width of this Kernel.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the height of this Kernel.
+     * 
+     * @return the height of this Kernel.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the float data array of this Kernel.
+     * 
+     * @param data the float array where the resulted data will be stored.
+     * 
+     * @return the float data array of this Kernel.
+     */
+    public final float[] getKernelData(float[] data) {
+        if (data == null) {
+            data = new float[this.data.length];
+        }
+        System.arraycopy(this.data, 0, data, 0, this.data.length);
+
+        return data;
+    }
+
+    /**
+     * Gets the X origin of this Kernel.
+     * 
+     * @return the X origin of this Kernel.
+     */
+    public final int getXOrigin() {
+        return xOrigin;
+    }
+
+    /**
+     * Gets the Y origin of this Kernel.
+     * 
+     * @return the Y origin of this Kernel.
+     */
+    public final int getYOrigin() {
+        return yOrigin;
+    }
+
+    /**
+     * Returns a copy of this Kernel object.
+     * 
+     * @return the copy of this Kernel object.
+     */
+    @Override
+    public Object clone() {
+        return new Kernel(width, height, data);
+    }
+}
diff --git a/awt/java/awt/image/LookupOp.java b/awt/java/awt/image/LookupOp.java
new file mode 100644
index 0000000..f9bd2c7
--- /dev/null
+++ b/awt/java/awt/image/LookupOp.java
@@ -0,0 +1,647 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The LookupOp class perfoms a lookup operation which transforms a 
+ * source image by filtering each band using a table of data. 
+ * The table may contain a single array or it may contain a 
+ * different data array for each band of the image.
+ */
+public class LookupOp implements BufferedImageOp, RasterOp {
+    
+    /** The lut. */
+    private final LookupTable lut;
+    
+    /** The hints. */
+    private RenderingHints hints;
+    
+    // TODO remove when this field is used
+    /** The can use ipp. */
+    @SuppressWarnings("unused")
+    private final boolean canUseIpp;
+
+    // We don't create levels/values when it is possible to reuse old
+    /** The cached levels. */
+    private int cachedLevels[];
+    
+    /** The cached values. */
+    private int cachedValues[];
+    // Number of channels for which cache is valid.
+    // If negative number of channels is same as positive but skipAlpha was specified
+    /** The valid for channels. */
+    private int validForChannels;
+
+    /** The level initializer. */
+    static int levelInitializer[] = new int[0x10000];
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+
+        for (int i=1; i<=0x10000; i++) {
+            levelInitializer[i-1] = i;
+        }
+    }
+
+    /**
+     * Instantiates a new LookupOp object from the specified 
+     * LookupTable object and a RenderingHints object.
+     * 
+     * @param lookup the specified LookupTable object. 
+     * @param hints the RenderingHints object or null.
+     */
+    public LookupOp(LookupTable lookup, RenderingHints hints) {
+        if (lookup == null){
+            throw new NullPointerException(Messages.getString("awt.01", "lookup")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        lut = lookup;
+        this.hints = hints;
+        canUseIpp = lut instanceof ByteLookupTable || lut instanceof ShortLookupTable;
+    }
+
+    /**
+     * Gets the LookupTable of the specified Object.
+     * 
+     * @return the LookupTable of the specified Object.
+     */
+    public final LookupTable getTable() {
+        return lut;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+
+            // Sync transfer type with LUT for component color model
+            if (dstCM instanceof ComponentColorModel) {
+                int transferType = dstCM.getTransferType();
+                if (lut instanceof ByteLookupTable) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                } else if (lut instanceof ShortLookupTable) {
+                    transferType = DataBuffer.TYPE_SHORT;
+                }
+
+                dstCM = new ComponentColorModel(
+                        dstCM.cs,
+                        dstCM.hasAlpha(),
+                        dstCM.isAlphaPremultiplied,
+                        dstCM.transparency,
+                        transferType
+                );
+            }
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                throw new IllegalArgumentException(Messages.getString("awt.237")); //$NON-NLS-1$            }
+            }
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.28F")); //$NON-NLS-1$            }
+            }
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.290")); //$NON-NLS-1$            }
+            }
+        }
+
+        if (lut.getNumComponents() != 1 && lut.getNumComponents() != src.getNumBands()) {
+            // awt.238=The number of arrays in the LookupTable does not meet the restrictions
+            throw new IllegalArgumentException(Messages.getString("awt.238")); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (!canUseIpp || ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        int nLUTComponents = lut.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (nLUTComponents == 1 || nLUTComponents == nComponents-1) {
+                skipAlpha = true;
+            } else if (nLUTComponents == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.229=Number of components in the LUT does not match the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+            }
+        } else if (nLUTComponents == 1 || nLUTComponents == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.229=Number of components in the LUT does not match the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, null);
+        } else {
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.291")); //$NON-NLS-1$
+            }
+
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.292")); //$NON-NLS-1$
+            }
+
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src
+                        .getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst
+                        .getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, null);
+                }
+            }
+        }
+
+        // TODO
+        //if (!canUseIpp || ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        int minSrcX = src.getMinX();
+        int minDstX = dst.getMinX();
+        int minSrcY = src.getMinY();
+        int minDstY = dst.getMinY();
+
+        int skippingChannels = skipAlpha ? 1 : 0;
+        int numBands2Process = src.getNumBands() - skippingChannels;
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int[] pixels = null;
+        int offset = lut.getOffset();
+
+        if (lut instanceof ByteLookupTable){
+            byte[][] byteData = ((ByteLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[b][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[0][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else if (lut instanceof ShortLookupTable){
+            short[][] shortData  = ((ShortLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[b][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[0][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else {
+            int pixel[] = new int[src.getNumBands()];
+            int maxY = minSrcY + srcHeight;
+            int maxX = minSrcX + srcWidth;
+            for (int srcY=minSrcY, dstY = minDstY; srcY < maxY; srcY++, dstY++){
+                for (int srcX=minSrcX, dstX = minDstX; srcX < maxX; srcX++, dstX++){
+                    src.getPixel(srcX, srcY, pixel);
+                    lut.lookupPixel(pixel, pixel);
+                    dst.setPixel(dstX, dstY, pixel);
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Creates the byte levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createByteLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        byte data[][] = ((ByteLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+            int channelBase = nLevels * channelOffset;
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFF;
+            }
+        }
+    }
+
+    /**
+     * Creates the short levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createShortLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        short data[][] = ((ShortLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            int channelBase = nLevels * channelOffset;
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFFFF;
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Have IPP functions for 1, 3 and 4 channels
+                    channels = srcSM.getNumBands();
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 =
+                            (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 =
+                            (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = null, values[] = null;
+        int channelMultiplier = skipAlpha ? -1 : 1;
+        if (channelMultiplier*channels == validForChannels) { // use existing levels/values
+            levels = cachedLevels;
+            values = cachedValues;
+        } else { // create new levels/values
+            if (lut instanceof ByteLookupTable) {
+                byte data[][] = ((ByteLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
+            } else if (lut instanceof ShortLookupTable) {
+                short data[][] = ((ShortLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
+            }
+
+            // cache levels/values
+            validForChannels = channelMultiplier*channels;
+            cachedLevels = levels;
+            cachedValues = values;
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            false
+        );
+
+        return res;
+    }
+
+    /**
+     * Ipp lut.
+     * 
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param levels the levels
+     * @param values the values
+     * @param channels the channels
+     * @param offsets the offsets
+     * @param linear the linear
+     * 
+     * @return the int
+     */
+    final static native int ippLUT(
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int levels[], int values[],
+            int channels, int offsets[],
+            boolean linear
+    );
+}
diff --git a/awt/java/awt/image/LookupTable.java b/awt/java/awt/image/LookupTable.java
new file mode 100644
index 0000000..d15f23c
--- /dev/null
+++ b/awt/java/awt/image/LookupTable.java
@@ -0,0 +1,93 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This abstract LookupTable class represents lookup table which
+ * is defined with the number of components and offset value.
+ * ByteLookupTable and ShortLookupTable classes are subclasses of
+ * LookupTable which contains byte and short data tables as
+ * an input arrays for bands or components of image.
+ */
+public abstract class LookupTable {
+    
+    /** The offset. */
+    private int offset;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a new LookupTable with the specified offset value
+     * and number of components.
+     * 
+     * @param offset the offset value.
+     * @param numComponents the number of components.
+     */
+    protected LookupTable(int offset, int numComponents) {
+        if (offset < 0) {
+            // awt.232=Offset should be not less than zero
+            throw new IllegalArgumentException(Messages.getString("awt.232")); //$NON-NLS-1$
+        }
+        if (numComponents < 1) {
+            // awt.233=Number of components should be positive
+            throw new IllegalArgumentException(Messages.getString("awt.233")); //$NON-NLS-1$
+        }
+
+        this.offset = offset;
+        this.numComponents = numComponents;
+    }
+
+    /**
+     * Gets the offset value of this Lookup table.
+     * 
+     * @return the offset value of this Lookup table.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of components of this Lookup table.
+     * 
+     * @return the number components of this Lookup table.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Returns a int array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * LookupTable. The resulted array is stored to the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the int array of translated samples of a pixel.
+     */
+    public abstract int[] lookupPixel(int[] src, int[] dst);
+}
diff --git a/awt/java/awt/image/MemoryImageSource.java b/awt/java/awt/image/MemoryImageSource.java
new file mode 100644
index 0000000..983f19e
--- /dev/null
+++ b/awt/java/awt/image/MemoryImageSource.java
@@ -0,0 +1,512 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MemoryImageSource class is used to produces pixels of an image from
+ * an array. This class can manage a memory image which 
+ * contains an animation or custom rendering.
+ */
+public class MemoryImageSource implements ImageProducer {
+
+    /** The width. */
+    int width;
+    
+    /** The height. */
+    int height;
+    
+    /** The cm. */
+    ColorModel cm;
+    
+    /** The b data. */
+    byte bData[];
+    
+    /** The i data. */
+    int iData[];
+    
+    /** The offset. */
+    int offset;
+    
+    /** The scanline. */
+    int scanline;
+    
+    /** The properties. */
+    Hashtable<?, ?> properties;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers;
+    
+    /** The animated. */
+    boolean animated;
+    
+    /** The fullbuffers. */
+    boolean fullbuffers;
+    
+    /** The data type. */
+    int dataType;
+
+    /** The Constant DATA_TYPE_BYTE. */
+    static final int DATA_TYPE_BYTE = 0;
+    
+    /** The Constant DATA_TYPE_INT. */
+    static final int DATA_TYPE_INT = 1;
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan,
+            Hashtable<?, ?> props) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixels array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        if(!isConsumer(ic) && ic != null) {
+            consumers.addElement(ic);
+        }
+        try{
+            setHeader(ic);
+            setPixels(ic, 0, 0, width, height);
+            if(animated){
+                ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+            }else{
+                ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+                if(isConsumer(ic)) {
+                    removeConsumer(ic);
+                }
+            }
+        }catch(Exception e){
+            if(isConsumer(ic)) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+            if(isConsumer(ic)) {
+                removeConsumer(ic);
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        consumers.removeElement(ic);
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic == null || consumers.contains(ic)) {
+            return;
+        }
+        consumers.addElement(ic);
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(int newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_INT;
+        this.iData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(byte newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_BYTE;
+        this.bData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Sets the full buffer updates flag to true. If this is an 
+     * animated image, the image consumers hints are updated
+     * accordingly.
+     * 
+     * @param fullbuffers the true if the pixel buffer should be sent always.
+     */
+    public synchronized void setFullBufferUpdates(boolean fullbuffers) {
+        if(this.fullbuffers == fullbuffers) {
+            return;
+        }
+        this.fullbuffers = fullbuffers;
+        if(animated){
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(fullbuffers){
+                        con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                                ImageConsumer.COMPLETESCANLINES);
+                    }else{
+                        con.setHints(ImageConsumer.RANDOMPIXELORDER);
+                    }
+                }catch(Exception e){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the flag that tells whether this memory image has more 
+     * than one frame (for animation): true for multiple frames,
+     * false if this class represents a single frame image.
+     *  
+     * @param animated whether this image represents an animation.
+     */
+    public synchronized void setAnimated(boolean animated) {
+        if(this.animated == animated) {
+            return;
+        }
+        Object consAr[] = consumers.toArray();
+        for (Object element : consAr) {
+            ImageConsumer con = (ImageConsumer)element;
+            try{
+                con.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            }catch(Exception e){
+                if(isConsumer(con)) {
+                    con.imageComplete(ImageConsumer.IMAGEERROR);
+                }
+            }
+            if(isConsumer(con)){
+                removeConsumer(con);
+            }
+        }
+        this.animated = animated;
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * ImageConsumers and notifies them that an animation frame 
+     * is completed only if framenotify parameter is true.
+     * That works only if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of rthe ectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     * @param framenotify true if a SINGLEFRAMEDONE notification
+     * should be sent to the registered consumers, false otherwise. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h,
+            boolean framenotify) {
+        if(animated){
+            if(fullbuffers){
+                x = 0;
+                y = 0;
+                w = width;
+                h = height;
+            }else{
+                if(x < 0){
+                    w += x;
+                    x = 0;
+                }
+                if(w > width) {
+                    w = width - x;
+                }
+                if(y < 0){
+                    h += y;
+                    y = 0;
+                }
+            }
+            if(h > height) {
+                h = height - y;
+            }
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(w > 0 && h > 0) {
+                        setPixels(con, x, y, w, h);
+                    }
+                    if(framenotify) {
+                        con.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+                    }
+                }catch(Exception ex){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * the ImageConsumers and notifies them that an animation frame 
+     * is completed if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of the rectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h) {
+        newPixels(x, y, w, h, true);
+    }
+
+    /**
+     * Sends a new buffer of pixels to the ImageConsumers 
+     * and notifies them that an animation frame is completed if
+     * the animated flag has been set to true by the setAnimated() method. 
+     */
+    public void newPixels() {
+        newPixels(0, 0, width, height, true);
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, byte pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.bData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_BYTE;
+        this.consumers = new Vector<ImageConsumer>();
+
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, int pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.iData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_INT;
+        this.consumers = new Vector<ImageConsumer>();
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param con the con
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     */
+    private void setPixels(ImageConsumer con, int x, int y, int w, int h){
+        int pixelOff = scanline * y + offset + x;
+
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
+            break;
+        case DATA_TYPE_INT:
+            con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
+            break;
+        default:
+            // awt.22A=Wrong type of pixels array
+            throw new IllegalArgumentException(Messages.getString("awt.22A")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Sets the header.
+     * 
+     * @param con the new header
+     */
+    private synchronized void setHeader(ImageConsumer con){
+        con.setDimensions(width, height);
+        con.setProperties(properties);
+        con.setColorModel(cm);
+        con.setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT |
+                ImageConsumer.COMPLETESCANLINES) : ImageConsumer.RANDOMPIXELORDER) :
+                (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
+                 ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
+    }
+
+}
+
diff --git a/awt/java/awt/image/MultiPixelPackedSampleModel.java b/awt/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 0000000..dd44b49
--- /dev/null
+++ b/awt/java/awt/image/MultiPixelPackedSampleModel.java
@@ -0,0 +1,454 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MultiPixelPackedSampleModel class represents image data with one
+ * band. This class packs multiple pixels with one sample in one data 
+ * element and supports the following data types: DataBuffer.TYPE_BYTE, 
+ * DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT. 
+ */
+public class MultiPixelPackedSampleModel extends SampleModel {
+
+    /** The pixel bit stride. */
+    private int pixelBitStride;
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The data bit offset. */
+    private int dataBitOffset;
+
+    /** The bit mask. */
+    private int bitMask;
+
+    /** The data element size. */
+    private int dataElementSize;
+
+    /** The pixels per data element. */
+    private int pixelsPerDataElement;
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param dataBitOffset the array of the band offsets.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits, int scanlineStride, int dataBitOffset) {
+
+        super(dataType, w, h, 1);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+               dataType != DataBuffer.TYPE_USHORT &&
+               dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        if(numberOfBits == 0) {
+            // awt.20C=Number of Bits equals to zero
+            throw new RasterFormatException(Messages.getString("awt.20C")); //$NON-NLS-1$
+        }
+        this.pixelBitStride = numberOfBits;
+        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
+        if(dataElementSize % pixelBitStride != 0) {
+            // awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
+            throw new RasterFormatException(Messages.getString("awt.20D")); //$NON-NLS-1$
+        }
+
+        if(dataBitOffset % numberOfBits != 0) {
+            // awt.20E=Data Bit offset is not a multiple of pixel bit stride
+            throw new RasterFormatException(Messages.getString("awt.20E")); //$NON-NLS-1$
+        }
+        this.dataBitOffset = dataBitOffset;
+
+        this.pixelsPerDataElement = dataElementSize / pixelBitStride;
+        this.bitMask = (1 << numberOfBits) - 1;
+    }
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits) {
+
+        this(dataType, w, h, numberOfBits, (numberOfBits * w +
+               DataBuffer.getDataTypeSize(dataType) - 1) /
+               DataBuffer.getDataTypeSize(dataType), 0);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+            bdata[0] = (byte) getSample(x, y, 0, data);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+            sdata[0] = (short) getSample(x, y, 0, data);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+            idata[0] = getSample(x, y, 0, data);
+            obj = idata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        setSample(x, y, obj, data, 1, 0);
+    }
+
+    /**
+     * Compares this MultiPixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is a MultiPixelPackedSampleModel 
+     * with the same data parameter values as this MultiPixelPackedSampleModel,
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
+            return false;
+        }
+
+        MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel) o;
+        return this.width == model.width &&
+               this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               this.pixelBitStride == model.pixelBitStride &&
+               this.bitMask == model.bitMask &&
+               this.pixelsPerDataElement == model.pixelsPerDataElement &&
+               this.dataElementSize == model.dataElementSize &&
+               this.dataBitOffset == model.dataBitOffset &&
+               this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands != null && bands.length != 1) {
+            // awt.20F=Number of bands must be only 1
+            throw new RasterFormatException(Messages.getString("awt.20F")); //$NON-NLS-1$
+        }
+        return createCompatibleSampleModel(width, height);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        pixel[0] = getSample(x, y, 0, data);
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        setSample(x, y, iArray, data, 2, 0);
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height || b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int elem = data.getElem(y * scanlineStride + bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize - 1)) -
+                pixelBitStride;
+
+        return (elem >> shift) & bitMask;
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        setSample(x, y, null, data, 3, s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
+            break;
+        }
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + (x * pixelBitStride + dataBitOffset) /
+               dataElementSize;
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return pixelBitStride;
+    }
+
+    /**
+     * Gets the bit offset in the data element which 
+     * is stored for the specified pixel of a scanline.
+     * 
+     * @param x the pixel.
+     * 
+     * @return the bit offset of the pixel in the data element.
+     */
+    public int getBitOffset(int x) {
+        return (x * pixelBitStride + dataBitOffset) % dataElementSize;
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        int sampleSizes[] = { pixelBitStride };
+        return sampleSizes;
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= scanlineStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelBitStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataBitOffset;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= bitMask;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataElementSize;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelsPerDataElement;
+        return hash;
+    }
+
+    @Override
+    public int getTransferType() {
+        if (pixelBitStride > 16) {
+            return DataBuffer.TYPE_INT;
+        } else if (pixelBitStride > 8) {
+            return DataBuffer.TYPE_USHORT;
+        } else {
+            return DataBuffer.TYPE_BYTE;
+        }
+    }
+
+    /**
+     * Gets the scanline stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the scanline stride of this MultiPixelPackedSampleModel.
+     */
+    public int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel bit stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the pixel bit stride of this MultiPixelPackedSampleModel.
+     */
+    public int getPixelBitStride() {
+        return pixelBitStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Gets the data bit offset.
+     * 
+     * @return the data bit offset.
+     */
+    public int getDataBitOffset() {
+        return dataBitOffset;
+    }
+
+    /**
+     * This method is used by other methods of this class. The behaviour of
+     * this method depends on the method which has been invoke this one. The
+     * argument methodId is used to choose valid behaviour in a particular case.
+     * If methodId is equal to 1 it means that this method has been invoked by
+     * the setDataElements() method, 2 - means setPixel(), and setSample() in
+     * any other cases.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param obj the obj
+     * @param data the data
+     * @param methodId the method id
+     * @param s the s
+     */
+    private void setSample(final int x, final int y, final Object obj,
+            final DataBuffer data, final int methodId, int s) {
+        if ((x < 0) || (y < 0) || (x >= this.width) || (y >= this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        final int bitnum = dataBitOffset + x * pixelBitStride;
+        final int idx = y * scanlineStride + bitnum / dataElementSize;
+        final int shift = dataElementSize - (bitnum & (dataElementSize - 1))
+                - pixelBitStride;
+        final int mask = ~(bitMask << shift);
+        int elem = data.getElem(idx);
+
+        switch (methodId) {
+        case 1: {                        // Invoked from setDataElements()
+            switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                s = ((byte[]) obj)[0] & 0xff;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                s = ((short[]) obj)[0] & 0xffff;
+                break;
+            case DataBuffer.TYPE_INT:
+                s = ((int[]) obj)[0];
+                break;
+            }
+            break;
+        }
+        case 2: {                        // Invoked from setPixel()
+            s = ((int[]) obj)[0];
+            break;
+        }
+        }
+
+        elem &= mask;
+        elem |= (s & bitMask) << shift;
+        data.setElem(idx, elem);
+    }
+}
+
diff --git a/awt/java/awt/image/PackedColorModel.java b/awt/java/awt/image/PackedColorModel.java
new file mode 100644
index 0000000..7aaefbf
--- /dev/null
+++ b/awt/java/awt/image/PackedColorModel.java
@@ -0,0 +1,383 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class PackedColorModel represents a color model where the 
+ * components are just the red, green, and blue bands, plus an alpha
+ * band if alpha is supported.
+ */
+public abstract class PackedColorModel extends ColorModel {
+
+    /** The component masks. */
+    int componentMasks[];
+
+    /** The offsets. */
+    int offsets[];
+
+    /** The scales. */
+    float scales[];
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param colorMaskArray the array that gives the bitmask corresponding
+     * to each color band (red, green, and blue)
+     * @param alphaMask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int colorMaskArray[],
+            int alphaMask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(colorMaskArray, alphaMask), space,
+                (alphaMask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        componentMasks = new int[numComponents];
+        for (int i = 0; i < numColorComponents; i++) {
+            componentMasks[i] = colorMaskArray[i];
+        }
+
+        if (hasAlpha) {
+            componentMasks[numColorComponents] = alphaMask;
+            if (this.bits[numColorComponents] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(rmask, gmask, bmask, amask), space,
+                (amask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        if (cs.getType() != ColorSpace.TYPE_RGB) {
+            // awt.239=The space is not a TYPE_RGB space
+            throw new IllegalArgumentException(Messages.getString("awt.239")); //$NON-NLS-1$
+        }
+
+        for (int i = 0; i < numColorComponents; i++) {
+            if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                // awt.23A=The min/max normalized component values are not 0.0/1.0
+                throw new IllegalArgumentException(Messages.getString("awt.23A")); //$NON-NLS-1$
+            }
+        }
+        componentMasks = new int[numComponents];
+        componentMasks[0] = rmask;
+        componentMasks[1] = gmask;
+        componentMasks[2] = bmask;
+
+        if (hasAlpha) {
+            componentMasks[3] = amask;
+            if (this.bits[3] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int band[] = new int[1];
+        band[0] = raster.getNumBands() - 1;
+        return raster.createWritableChild(x, y, w, h, x, y, band);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof PackedColorModel)) {
+            return false;
+        }
+        PackedColorModel cm = (PackedColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+                transferType == cm.getTransferType() &&
+                cs.getType() == cm.getColorSpace().getType() &&
+                hasAlpha == cm.hasAlpha() &&
+                isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+                transparency == cm.getTransparency() &&
+                numColorComponents == cm.getNumColorComponents()&&
+                numComponents == cm.getNumComponents() &&
+                Arrays.equals(bits, cm.getComponentSize()) &&
+                Arrays.equals(componentMasks, cm.getMasks()));
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+        SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel) sm;
+
+        return ((esm.getNumBands() == numComponents) &&
+                (esm.getTransferType() == transferType) &&
+                Arrays.equals(esm.getBitMasks(), componentMasks));
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(transferType, w, h,
+                componentMasks);
+    }
+
+    /**
+     * Gets the bitmask corresponding to the specified color component.
+     * 
+     * @param index the index of the desired color
+     * 
+     * @return the mask
+     */
+    public final int getMask(int index) {
+        return componentMasks[index];
+    }
+
+    /**
+     * Gets the bitmasks of the components.
+     * 
+     * @return the masks
+     */
+    public final int[] getMasks() {
+        return (componentMasks.clone());
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param colorMaskArray the color mask array
+     * @param alphaMask the alpha mask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int colorMaskArray[], int alphaMask) {
+        int bits[];
+        int numComp;
+        if (alphaMask == 0) {
+            numComp = colorMaskArray.length;
+        } else {
+            numComp = colorMaskArray.length + 1;
+        }
+
+        bits = new int[numComp];
+        int i = 0;
+        for (; i < colorMaskArray.length; i++) {
+            bits[i] = countCompBits(colorMaskArray[i]);
+            if (bits[i] < 0) {
+                // awt.23B=The mask of the {0} component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23B", i)); //$NON-NLS-1$
+            }
+        }
+
+        if (i < numComp) {
+            bits[i] = countCompBits(alphaMask);
+
+            if (bits[i] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param rmask the rmask
+     * @param gmask the gmask
+     * @param bmask the bmask
+     * @param amask the amask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int rmask, int gmask, int bmask,
+            int amask) {
+
+        int numComp;
+        if (amask == 0) {
+            numComp = 3;
+        } else {
+            numComp = 4;
+        }
+        int bits[] = new int[numComp];
+
+        bits[0] = countCompBits(rmask);
+        if (bits[0] < 0) {
+            // awt.23D=The mask of the red component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23D")); //$NON-NLS-1$
+        }
+
+        bits[1] = countCompBits(gmask);
+        if (bits[1] < 0) {
+            // awt.23E=The mask of the green component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23E")); //$NON-NLS-1$
+        }
+
+        bits[2] = countCompBits(bmask);
+        if (bits[2] < 0) {
+            // awt.23F=The mask of the blue component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23F")); //$NON-NLS-1$
+        }
+
+        if (amask != 0) {
+            bits[3] = countCompBits(amask);
+            if (bits[3] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Count comp bits.
+     * 
+     * @param compMask the comp mask
+     * 
+     * @return the int
+     */
+    private static int countCompBits(int compMask) {
+        int bits = 0;
+        if (compMask != 0) {
+            // Deleting final zeros
+            while ((compMask & 1) == 0) {
+                compMask >>>= 1;
+            }
+            // Counting component bits
+            while ((compMask & 1) == 1) {
+                compMask >>>= 1;
+                bits++;
+            }
+        }
+
+        if (compMask != 0) {
+            return -1;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+                transferType != DataBuffer.TYPE_USHORT &&
+                transferType != DataBuffer.TYPE_INT) {
+            // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+            throw new IllegalArgumentException(Messages.getString("awt.240")); //$NON-NLS-1$
+        }
+        return transferType;
+}
+
+    /**
+     * Parses the components.
+     */
+    private void parseComponents() {
+        offsets = new int[numComponents];
+        scales = new float[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            int off = 0;
+            int mask = componentMasks[i];
+            while ((mask & 1) == 0) {
+                mask >>>= 1;
+                off++;
+            }
+            offsets[i] = off;
+            if (bits[i] == 0) {
+                scales[i] = 256.0f; // May be any value different from zero,
+                // because will dividing by zero
+            } else {
+                scales[i] = 255.0f / maxValues[i];
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
new file mode 100644
index 0000000..cecd5c8
--- /dev/null
+++ b/awt/java/awt/image/PixelGrabber.java
@@ -0,0 +1,408 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PixelGrabber implements ImageConsumer {
+
+    int width;
+    int height;
+    int X;
+    int Y;
+    int offset;
+    int scanline;
+    ImageProducer producer;
+
+    byte bData[];
+    int iData[];
+    ColorModel cm;
+
+    private int grabberStatus;
+    private int dataType;
+    private boolean isGrabbing;
+    private boolean isRGB;
+
+
+    private static final int DATA_TYPE_BYTE = 0;
+    private static final int DATA_TYPE_INT = 1;
+    private static final int DATA_TYPE_UNDEFINED = 2;
+
+    private static final int ALL_BITS = (ImageObserver.FRAMEBITS |
+            ImageObserver.ALLBITS);
+
+    private static final int GRABBING_STOP = ALL_BITS | ImageObserver.ERROR;
+
+
+
+    public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(ip, x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(img.getSource(), x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) {
+        initialize(img.getSource(), x, y, w, h, null, 0, 0, forceRGB);
+    }
+
+    public void setProperties(Hashtable<?, ?> props) {
+        return;
+    }
+
+    public synchronized Object getPixels() {
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            return bData;
+        case DATA_TYPE_INT:
+            return iData;
+        default:
+            return null;
+        }
+    }
+
+    public void setColorModel(ColorModel model) {
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, byte[] pixels, int srcOff, int srcScan) {
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            if(model != ColorModel.getRGBdefault()){
+                bData = new byte[width * height];
+                isRGB = false;
+                dataType = DATA_TYPE_BYTE;
+            }else{
+                iData = new int[width * height];
+                isRGB = true;
+                dataType = DATA_TYPE_INT;
+            }
+        case DATA_TYPE_BYTE:
+            if(!isRGB && cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, bData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            forceToRGB();
+        case DATA_TYPE_INT:
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff + x] = cm.getRGB(pixels[srcOff + x] & 0xff);                    
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, int[] pixels, int srcOff, int srcScan) {
+
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+
+        int mask = 0xFF;
+
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            isRGB = (cm == ColorModel.getRGBdefault());
+
+        case DATA_TYPE_INT:
+            if(cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, iData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            mask = 0xFFFFFFFF;
+
+        case DATA_TYPE_BYTE:
+            forceToRGB();
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff+x] = cm.getRGB(pixels[srcOff+x] & mask);
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+    }
+
+    public synchronized ColorModel getColorModel() {
+        return cm;
+    }
+
+    public synchronized boolean grabPixels(long ms) 
+    throws InterruptedException {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return ((grabberStatus & ALL_BITS) != 0);
+        }
+
+        long start = System.currentTimeMillis();
+
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+        while((grabberStatus & GRABBING_STOP) == 0){
+            if(ms != 0){
+                ms = start + ms - System.currentTimeMillis();
+                if(ms <= 0) {
+                    break;
+                }
+            }
+            wait(ms);
+        }
+
+        return ((grabberStatus & ALL_BITS) != 0);
+    }
+
+    public void setDimensions(int w, int h) {
+        if(width < 0) {
+            width = w - X;
+        }
+        if(height < 0) {
+            height = h - Y;
+        }
+
+        grabberStatus |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
+
+        if(width <=0 || height <=0){
+            imageComplete(STATICIMAGEDONE);
+            return;
+        }
+
+        if(isRGB && dataType == DATA_TYPE_UNDEFINED){
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            scanline = width;
+        }
+    }
+
+    public void setHints(int hints) {
+        return;
+    }
+
+    public synchronized void imageComplete(int status) {
+        switch(status){
+        case IMAGEABORTED:
+            grabberStatus |= ImageObserver.ABORT;
+            break;
+        case IMAGEERROR:
+            grabberStatus |= ImageObserver.ERROR | ImageObserver.ABORT;
+            break;
+        case SINGLEFRAMEDONE:
+            grabberStatus |= ImageObserver.FRAMEBITS;
+            break;
+        case STATICIMAGEDONE:
+            grabberStatus |= ImageObserver.ALLBITS;
+            break;
+        default:
+            // awt.26A=Incorrect ImageConsumer completion status
+            throw new IllegalArgumentException(Messages.getString("awt.26A")); //$NON-NLS-1$
+        }
+        isGrabbing = false;
+        producer.removeConsumer(this);
+        notifyAll();
+    }
+
+    public boolean grabPixels() throws InterruptedException {
+        return grabPixels(0);
+    }
+
+    public synchronized void startGrabbing() {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return;
+        }
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+    }
+
+    public synchronized void abortGrabbing() {
+        imageComplete(IMAGEABORTED);
+    }
+
+    public synchronized int status() {
+        return grabberStatus;
+    }
+
+    public synchronized int getWidth() {
+        if(width < 0) {
+            return -1;
+        }
+        return width;
+    }
+
+    public synchronized int getStatus() {
+        return grabberStatus;
+    }
+
+    public synchronized int getHeight() {
+        if(height < 0) {
+            return -1;
+        }
+        return height;
+    }
+
+    private void initialize(ImageProducer ip, int x, int y, int w, int h,
+            int pixels[], int off, int scansize, boolean forceRGB){
+
+        producer = ip;
+        X = x;
+        Y = y;
+        width = w;
+        height = h;
+        iData = pixels;
+        dataType = (pixels == null) ? DATA_TYPE_UNDEFINED : DATA_TYPE_INT;
+        offset = off;
+        scanline = scansize;
+        if(forceRGB){
+            cm = ColorModel.getRGBdefault();
+            isRGB = true;
+        }
+    }
+
+    /**
+     * Force pixels to INT RGB mode
+     */
+    private void forceToRGB(){
+        if (isRGB)
+            return;
+    
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            iData = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                iData[i] = cm.getRGB(bData[i] & 0xff);
+            }
+            dataType = DATA_TYPE_INT;
+            bData = null;
+            break;
+
+        case DATA_TYPE_INT:
+            int buff[] = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                buff[i] = cm.getRGB(iData[i]);
+            }
+            iData = buff;
+            break;
+        }
+        offset = 0;
+        scanline = width;
+        cm = ColorModel.getRGBdefault();
+        isRGB = true;
+    }
+
+}
diff --git a/awt/java/awt/image/PixelInterleavedSampleModel.java b/awt/java/awt/image/PixelInterleavedSampleModel.java
new file mode 100644
index 0000000..e41473e
--- /dev/null
+++ b/awt/java/awt/image/PixelInterleavedSampleModel.java
@@ -0,0 +1,124 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The PixelInterleavedSampleModel class represents image data 
+ * as represented as interleaved pixels and for which each sample of 
+ * a pixel takes one data element of the DataBuffer.
+ */
+public class PixelInterleavedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Instantiates a new PixelInterleavedSampleModel with the 
+     * specified parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public PixelInterleavedSampleModel(int dataType, int w, int h,
+            int pixelStride, int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
+
+        int maxOffset = bandOffsets[0];
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        maxOffset -= minOffset;
+
+        if (maxOffset > scanlineStride) {
+            // awt.241=Any offset between bands is greater than the Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.241")); //$NON-NLS-1$
+        }
+
+        if (maxOffset > pixelStride) {
+            // awt.242=Pixel stride is less than any offset between bands
+            throw new IllegalArgumentException(Messages.getString("awt.242")); //$NON-NLS-1$
+        }
+
+        if (pixelStride * w > scanlineStride) {
+            // awt.243=Product of Pixel stride and w is greater than Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.243")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        int newOffsets[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            newOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new PixelInterleavedSampleModel(dataType, width, height,
+                pixelStride, scanlineStride, newOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int newOffsets[];
+        int minOffset = bandOffsets[0];
+
+        for (int i = 1; i < numBands; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        if (minOffset > 0) {
+            newOffsets = new int[numBands];
+            for (int i = 0; i < numBands; i++) {
+                newOffsets[i] = bandOffsets[i] - minOffset;
+            }
+        } else {
+            newOffsets = bandOffsets;
+        }
+
+        return new PixelInterleavedSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, newOffsets);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x66;
+    }
+
+}
+
diff --git a/awt/java/awt/image/RGBImageFilter.java b/awt/java/awt/image/RGBImageFilter.java
new file mode 100644
index 0000000..9a76997
--- /dev/null
+++ b/awt/java/awt/image/RGBImageFilter.java
@@ -0,0 +1,190 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RGBImageFilter class represents a filter which modifies
+ * pixels of an image in the default RGB ColorModel. 
+ */
+public abstract class RGBImageFilter extends ImageFilter {
+
+    /** 
+     * The origmodel is the ColorModel to be replaced by newmodel 
+     * when substituteColorModel is called.
+     */
+    protected ColorModel origmodel;
+
+    /** 
+     * The newmodel is the ColorModel with which to replace origmodel 
+     * when substituteColorModel is called. 
+     */
+    protected ColorModel newmodel;
+
+    /** 
+     * The canFilterIndexColorModel indicates if it is 
+     * acceptable to apply the color filtering of the filterRGB 
+     * method to the color table entries of an IndexColorModel 
+     * object.
+     * */
+    protected boolean canFilterIndexColorModel;
+
+    /**
+     * Instantiates a new RGBImageFilter.
+     */
+    public RGBImageFilter() {}
+
+    /**
+     * Filters an IndexColorModel object by calling filterRGB function for
+     * each entry of IndexColorModel.
+     * 
+     * @param icm the IndexColorModel to be filtered.
+     * 
+     * @return the IndexColorModel.
+     */
+    public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
+        int transferType = icm.getTransferType();
+        int bits = icm.getPixelSize();
+        int mapSize = icm.getMapSize();
+        int colorMap[] = new int[mapSize];
+        int filteredColorMap[] = new int[mapSize];
+        icm.getRGBs(colorMap);
+        int trans = -1;
+        boolean hasAlpha = false;
+        for(int i = 0; i < mapSize; i++){
+            filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]);
+            int alpha = filteredColorMap[i] >>> 24;
+            if(alpha != 0xff){
+                if(!hasAlpha) {
+                    hasAlpha = true;
+                }
+                if(alpha == 0 && trans < 0) {
+                    trans = i;
+                }
+            }
+        }
+
+        return new IndexColorModel(bits, mapSize, filteredColorMap, 0,
+                hasAlpha, trans, transferType);
+    }
+
+    /**
+     * Replaces the original color model and the new one.
+     * 
+     * @param oldcm the old ColorModel.
+     * @param newcm the new ColorModel.
+     */
+    public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
+        origmodel = oldcm;
+        newmodel = newcm;
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if(model instanceof IndexColorModel &&
+                canFilterIndexColorModel){
+            IndexColorModel icm = (IndexColorModel) model;
+            ColorModel filteredModel = filterIndexColorModel(icm);
+            substituteColorModel(model, filteredModel);
+            consumer.setColorModel(filteredModel);
+        }else{
+            consumer.setColorModel(ColorModel.getRGBdefault());
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            int[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            byte[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = 
+                        model.getRGB(pixels[pixelsOff + idx] & 0xff);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    /**
+     * Filters a region of pixels in the default RGB ColorModel 
+     * by calling the filterRGB method for them.
+     * 
+     * @param x the X coordinate of region.
+     * @param y the Y coordinate of region.
+     * @param w the width ofregion.
+     * @param h the height of region.
+     * @param pixels the pixels array.
+     * @param off the offset of array.
+     * @param scansize the distance between rows of pixels in the array.
+     */
+    public void filterRGBPixels(int x, int y, int w, int h, 
+            int[] pixels, int off, int scansize) {
+        
+        for(int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize){
+            for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                pixels[lineOff + idx] = 
+                    filterRGB(sx, sy, pixels[lineOff + idx]);
+            }
+        }
+        consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), 
+                pixels, off, scansize);
+    }
+
+    /**
+     * Coverts a single input pixel in the default RGB ColorModel 
+     * to a single output pixel.
+     * 
+     * @param x the X pixel's coordinate.
+     * @param y the Y pixel's coordinate.
+     * @param rgb a pixel in the default RGB color model.
+     * 
+     * @return a filtered pixel in the default RGB color model.
+     */
+    public abstract int filterRGB(int x, int y, int rgb);
+
+}
+
diff --git a/awt/java/awt/image/Raster.java b/awt/java/awt/image/Raster.java
new file mode 100644
index 0000000..4b2426e
--- /dev/null
+++ b/awt/java/awt/image/Raster.java
@@ -0,0 +1,1412 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.image.OrdinaryWritableRaster;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Raster class represents a rectangular area of pixels.
+ * This class is defined by DataBuffer and SampleModel objects. 
+ * The DataBuffer object stores sample values and DSampleModel defines 
+ * the location of sample in this DataBuffer. 
+ */
+public class Raster {
+
+    /** The DataBuffer of this Raster. */
+    protected DataBuffer dataBuffer;
+
+    /** The height of this Raster. */
+    protected int height;
+
+    /** The X coordinate of the upper left pixel in this Raster. */
+    protected int minX;
+
+    /** The Y coordinate of the upper left pixel in this Raster. */
+    protected int minY;
+
+    /** The number of bands in this Raster. */
+    protected int numBands;
+
+    /** The number of data elements. */
+    protected int numDataElements;
+
+    /** The parent of this Raster. */
+    protected Raster parent;
+
+    /** The SampleModel of this Raster. */
+    protected SampleModel sampleModel;
+
+    /** 
+     * The X translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateX;
+
+    /** 
+     * The Y translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateY;
+
+    /** The width of this Raster. */
+    protected int width;
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified 
+     * DataBuffer. The number of bands is defined by the length of bandOffsets
+     * or bankIndices arrays.
+     * 
+     * @param dataBuffer the specified DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bankIndices[],
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        BandedSampleModel sampleModel = new BandedSampleModel(dataType, w, h,
+                scanlineStride, bankIndices, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int scanlineStride, int bankIndices[], int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int maxOffset = bandOffsets[0];
+        int maxBank = bankIndices[0];
+
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+
+        int numBanks = maxBank + 1;
+        int dataSize = scanlineStride * (h - 1) + w + maxOffset;
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(dataSize, numBanks);
+            break;
+        }
+        return createBandedRaster(data, w, h, scanlineStride, bankIndices,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1) {
+            // awt.279=bands is less than 1
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.279")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        int bankIndices[] = new int[bands];
+
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = 0;
+            bankIndices[i] = i;
+        }
+        return createBandedRaster(dataType, w, h, w, bankIndices, bandOffsets,
+                location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int pixelStride,
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        PixelInterleavedSampleModel sampleModel = 
+            new PixelInterleavedSampleModel(dataType, w, h, 
+                    pixelStride, scanlineStride, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int scanlineStride, int pixelStride, int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+        int size = (h - 1) * scanlineStride + w * pixelStride + minOffset;
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        }
+
+        return createInterleavedRaster(data, w, h, scanlineStride, pixelStride,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = i;
+        }
+
+        return createInterleavedRaster(dataType, w, h, w * bands, bands,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel  
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bandMasks[], Point location) {
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new RasterFormatException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        SinglePixelPackedSampleModel sampleModel = 
+            new SinglePixelPackedSampleModel(dataType, w, h, 
+                    scanlineStride, bandMasks);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitsPerPixel the number of bits per pixel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int bitsPerPixel, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        MultiPixelPackedSampleModel sampleModel = 
+            new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bands the number of bands.
+     * @param bitsPerBand the number of bits per band.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bands, int bitsPerBand, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1 || bitsPerBand < 1) {
+            // awt.27D=bitsPerBand or bands is not greater than zero
+            throw new IllegalArgumentException(Messages.getString("awt.27D")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bitsPerBand * bands > DataBuffer.getDataTypeSize(dataType)) {
+            // awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
+            throw new IllegalArgumentException(Messages.getString("awt.27E")); //$NON-NLS-1$
+        }
+
+        if (bands > 1) {
+
+            int bandMasks[] = new int[bands];
+            int mask = (1 << bitsPerBand) - 1;
+
+            for (int i = 0; i < bands; i++) {
+                bandMasks[i] = mask << (bitsPerBand * (bands - 1 - i));
+            }
+
+            return createPackedRaster(dataType, w, h, bandMasks, location);
+        }
+        DataBuffer data = null;
+        int size = ((bitsPerBand * w + 
+                DataBuffer.getDataTypeSize(dataType) - 1) / 
+                DataBuffer.getDataTypeSize(dataType)) * h;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return createPackedRaster(data, w, h, bitsPerBand, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel    
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bandMasks[], Point location) {
+        
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new NullPointerException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(w * h);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(w * h);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(w * h);
+            break;
+        }
+
+        return createPackedRaster(data, w, h, w, bandMasks, location);
+    }
+
+    /**
+     * Creates a Raster object with the specified DataBuffer and SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the Raster.
+     */
+    public static Raster createRaster(SampleModel sm, DataBuffer db,
+            Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new Raster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel and DataBuffer.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            DataBuffer db, Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new OrdinaryWritableRaster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            Point location) {
+
+        if (sm == null) {
+            // awt.280=SampleModel is null
+            throw new NullPointerException(Messages.getString("awt.280")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return createWritableRaster(sm, sm.createDataBuffer(), location);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel and
+     * DataBuffer.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified  DataBuffer.
+     * @param origin the specified origin.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel,
+     * DataBuffer, rectangular region and parent Raster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the a rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel coordinates to the new Raster coordinates.
+     * @param parent the parent of this Raster.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate, Raster parent) {
+
+        if (sampleModel == null || dataBuffer == null || aRegion == null
+                || sampleModelTranslate == null) {
+            // awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
+            throw new NullPointerException(Messages.getString("awt.281")); //$NON-NLS-1$
+        }
+
+        if (aRegion.width <= 0 || aRegion.height <= 0) {
+            // awt.282=aRegion has width or height less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.282")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.x + (long) aRegion.width > Integer.MAX_VALUE) {
+            // awt.283=Overflow X coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.283")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.y + (long) aRegion.height > Integer.MAX_VALUE) {
+            // awt.284=Overflow Y coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
+        }
+        
+        if (sampleModel instanceof ComponentSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((ComponentSampleModel) sampleModel).getScanlineStride());
+        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((MultiPixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((SinglePixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        }
+
+        this.sampleModel = sampleModel;
+        this.dataBuffer = dataBuffer;
+        this.minX = aRegion.x;
+        this.minY = aRegion.y;
+        this.width = aRegion.width;
+        this.height = aRegion.height;
+        this.sampleModelTranslateX = sampleModelTranslate.x;
+        this.sampleModelTranslateY = sampleModelTranslate.y;
+        this.parent = parent;
+        this.numBands = sampleModel.getNumBands();
+        this.numDataElements = sampleModel.getNumDataElements();
+
+    }
+
+    /**
+     * Instantiates a new Raster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected Raster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.getWidth(), sampleModel
+                        .getHeight()), origin, null);
+    }
+
+    /**
+     * Creates the child of this Raster by sharing the specified rectangular
+     * area in this Raste. The parentX, parentY, width 
+     * and height parameters specify the rectangular area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of this Raster. 
+     * @param parentY the Y coordinate of the upper left corner of this Raster.
+     * @param width the width of the child area.
+     * @param height the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the Raster.
+     */
+    public Raster createChild(int parentX, int parentY, int width, int height,
+            int childMinX, int childMinY, int bandList[]) {
+        if (width <= 0 || height <= 0) {
+            // awt.285=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.285")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + width > this.minX + this.width) {
+            // awt.286=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.286")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + height > this.minY + this.height) {
+            // awt.287=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.287")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + width > Integer.MAX_VALUE) {
+            // awt.288=parentX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.288")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + height > Integer.MAX_VALUE) {
+            // awt.289=parentY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.289")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + width > Integer.MAX_VALUE) {
+            // awt.28A=childMinX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28A")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + height > Integer.MAX_VALUE) {
+            // awt.28B=childMinY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28B")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new Raster(childModel, dataBuffer, new Rectangle(childMinX,
+                childMinY, width, height), new Point(childTranslateX
+                + sampleModelTranslateX, childTranslateY
+                + sampleModelTranslateY), this);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster() {
+        return new OrdinaryWritableRaster(sampleModel, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size.
+     * 
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
+
+        return new OrdinaryWritableRaster(sm, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size and location.
+     * 
+     * @param x the X coordinate of the new WritableRaster.
+     * @param y the Y coordinate of the new WritableRaster.
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int x, int y, int w,
+            int h) {
+
+        WritableRaster raster = createCompatibleWritableRaster(w, h);
+
+        return raster.createWritableChild(0, 0, w, h, x, y, null);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified rectangle which determines
+     * new WritableRaster's location and size.
+     * 
+     * @param rect the specified Rectangle.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
+        if (rect == null) {
+            // awt.28C=Rect is null
+            throw new NullPointerException(Messages.getString("awt.28C")); //$NON-NLS-1$
+        }
+
+        return createCompatibleWritableRaster(rect.x, rect.y, rect.width,
+                rect.height);
+    }
+
+    /**
+     * Creates the translated child of this Raster. The New Raster
+     * object is a reference to the this Raster with a 
+     * different location. 
+     *  
+     * @param childMinX the X coordinate of the new Raster.
+     * @param childMinY the Y coordinate of the new Raster.
+     * 
+     * @return the Raster.
+     */
+    public Raster createTranslatedChild(int childMinX, int childMinY) {
+        return createChild(minX, minY, width, height, childMinX, childMinY,
+                null);
+    }
+
+    /**
+     * Gets the bounds of this Raster as a rectangle.
+     * 
+     * @return the bounds of this Raster.
+     */
+    public Rectangle getBounds() {
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the DataBuffer associated with this Raster.
+     * 
+     * @return the DataBuffer associated with this Raster.
+     */
+    public DataBuffer getDataBuffer() {
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the data elements which represent the pixel data of the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param outData the resulting array.
+     * 
+     * @return the data elements of the specified area of this Raster.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the data elements which represent the specified pixel of 
+     * this Raster as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param outData the resulting data.
+     * 
+     * @return the data elements of the specified pixel of this Raster.
+     */
+    public Object getDataElements(int x, int y, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the height of this Raster.
+     * 
+     * @return the height of this Raster.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the minimum X coordinate of this Raster.
+     * 
+     * @return the minimum X coordinate of this Raster.
+     */
+    public final int getMinX() {
+        return minX;
+    }
+
+    /**
+     * Gets the minimum Y coordinate of this Raster.
+     * 
+     * @return the minimum Y coordinate of this Raster.
+     */
+    public final int getMinY() {
+        return minY;
+    }
+
+    /**
+     * Gets the number of bands in this Raster.
+     * 
+     * @return the number of bands in this Raster.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the number of data elements for one pixel.
+     * 
+     * @return the number of data elements for one pixel.
+     */
+    public final int getNumDataElements() {
+        return numDataElements;
+    }
+
+    /**
+     * Gets the parent Raster for this Raster object. 
+     * 
+     * @return the parent Raster for this Raster object.
+     */
+    public Raster getParent() {
+        return parent;
+    }
+
+    /**
+     * Gets a double array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array where result array will be stored.
+     * 
+     * @return the double array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public double[] getPixel(int x, int y, double dArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets a float array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array where the result array will be stored.
+     * 
+     * @return the float array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public float[] getPixel(int x, int y, float fArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array where the result array will be stored.
+     * 
+     * @return the int array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public int[] getPixel(int x, int y, int iArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets an double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param dArray the resulting array.
+     * 
+     * @return the double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets an float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param fArray the resulting array.
+     * 
+     * @return the float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of pixel's the area of pixels.
+     * @param h the height of pixel's the area of pixels.
+     * @param iArray the resulting array.
+     * 
+     * @return the int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as an int.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as an int.
+     */
+    public int getSample(int x, int y, int b) {
+        return sampleModel.getSample(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a double.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a double.
+     */
+    public double getSampleDouble(int x, int y, int b) {
+        return sampleModel.getSampleDouble(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a float.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a float.
+     */
+    public float getSampleFloat(int x, int y, int b) {
+        return sampleModel.getSampleFloat(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the SampleModel associated with this Raster.
+     * 
+     * @return the SampleModel associated with this Raster.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets the translation of the X coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the X coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+     */
+    public final int getSampleModelTranslateX() {
+        return sampleModelTranslateX;
+    }
+
+    /**
+     * Gets the translation of the Y coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the Y coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+
+     */
+    public final int getSampleModelTranslateY() {
+        return sampleModelTranslateY;
+    }
+
+    /**
+     * Gets the double array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param dArray the resulting double array.
+     * 
+     * @return the double array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets the float array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param fArray the resulting float array.
+     * 
+     * @return the float array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets the int array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param iArray the resulting int array.
+     * 
+     * @return the int array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the transfer type for pixels of this Raster.
+     * @see SampleModel#getTransferType()
+     * 
+     * @return the transfer type for pixels of this Raster.
+     */
+    public final int getTransferType() {
+        return sampleModel.getTransferType();
+    }
+
+    /**
+     * Gets the width of this Raster.
+     * 
+     * @return the width of this Raster.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Validate data buffer.
+     * 
+     * @param dataBuffer the data buffer
+     * @param w the w
+     * @param h the h
+     * @param scanlineStride the scanline stride
+     */
+    private static void validateDataBuffer(final DataBuffer dataBuffer, final int w,
+            final int h, final int scanlineStride) {
+        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
+            // awt.298=dataBuffer is too small
+            throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
+        }
+    }
+}
+
+
diff --git a/awt/java/awt/image/RasterFormatException.java b/awt/java/awt/image/RasterFormatException.java
new file mode 100644
index 0000000..8577dad
--- /dev/null
+++ b/awt/java/awt/image/RasterFormatException.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RasterFormatException class represents the exception 
+ * that is thrown when there's an invalid layout
+ * in the Raster.
+ */
+public class RasterFormatException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 96598996116164315L;
+
+    /**
+     * Instantiates a new RasterFormatException with the 
+     * specified detail message.
+     * 
+     * @param s the detail message.
+     */
+    public RasterFormatException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/image/RasterOp.java b/awt/java/awt/image/RasterOp.java
new file mode 100644
index 0000000..e8933ee
--- /dev/null
+++ b/awt/java/awt/image/RasterOp.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The RasterOp interface provides methods for performing transformations
+ * from source data to destination data for Raster objects. The source and 
+ * destination objects should contain the appropriate number of bands for 
+ * the particular classes which implement this interface.
+ */
+public interface RasterOp {
+    
+    /**
+     * Creates a destination WritableRaster with the specified Raster;
+     * this destination image data is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleDestRaster(Raster src);
+
+    /**
+     * Performs a filter operation on the source Raster and stores the resulting
+     * image data to the destination WritableRaster.
+     * 
+     * @param src the source Raster.
+     * @param dst the destination WritableRaster, where the result is stored.
+     * 
+     * @return the filtered WritableRaster.
+     */
+    public WritableRaster filter(Raster src, WritableRaster dst);
+
+    /**
+     * Gets the bounds of the filtered Raster.
+     * 
+     * @param src the source Raster to be filtered.
+     * 
+     * @return the rectangle bounds of the filtered Raster.
+     */
+    public Rectangle2D getBounds2D(Raster src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source raster.
+     * 
+     * @param srcPoint the point of the source raster.
+     * @param dstPoint the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint);
+
+    /**
+     * Gets the RenderingHints of the RasterOp.
+     * 
+     * @return the RenderingHints of the RasterOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/RenderedImage.java b/awt/java/awt/image/RenderedImage.java
new file mode 100644
index 0000000..db3a4c8
--- /dev/null
+++ b/awt/java/awt/image/RenderedImage.java
@@ -0,0 +1,198 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Rectangle;
+import java.util.Vector;
+
+/**
+ * The RenderedImage interface should be implemented by all objects which 
+ * contains image data. The image data is represented as a single tile or 
+ * an array of tiles.
+ */
+public interface RenderedImage {
+
+    /**
+     * Gets the property with the specified name from the property set 
+     * of this RenderedImage.
+     * 
+     * @param name the property's name.
+     * 
+     * @return the property value corresponded to this property's name.
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Copies the region of this RenderedImage to the specified 
+     * WritableRaster. The bounds of the region are the bounds of the 
+     * WritableRaster.
+     * 
+     * @param raster the WritableRaster.
+     * 
+     * @return the created WritableRaster.
+     */
+    public WritableRaster copyData(WritableRaster raster);
+
+    /**
+     * Gets the image data of the image's region as one tile.
+     * 
+     * @param rect the rectangular region of RenderedImage.
+     * 
+     * @return the image data of the image's region as one tile.
+     */
+    public Raster getData(Rectangle rect);
+
+    /**
+     * Gets all RenderedImage objects which are the source of this
+     * RenderedImage object.
+     * 
+     * @return a Vector of RenderedImage objects which are the source 
+     * of this RenderedImage object or null, if there is no information
+     * about them.
+     */
+    public Vector<RenderedImage> getSources();
+
+    /**
+     * Gets the set of all property names for this RenderedImage.
+     * 
+     * @return the array of all property names for this RenderedImage.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Gets the SampleModel of this RenderedImage.
+     * 
+     * @return the SampleModel of this RenderedImage.
+     */
+    public SampleModel getSampleModel();
+
+    /**
+     * Gets the tile corresponded to the specified indices in the tile
+     * array.
+     * 
+     * @param tileX the X index of the tile.  
+     * @param tileY the Y index of the tile. 
+     * 
+     * @return the tile corresponded to the specified indices in the tile
+     * array.
+     */
+    public Raster getTile(int tileX, int tileY);
+
+    /**
+     * Gets the image data of this image as one tile.
+     * 
+     * @return the image data of this image as one tile.
+     */
+    public Raster getData();
+
+    /**
+     * Gets the ColorModel of this RenderedImage.
+     * 
+     * @return the ColorModel of this RenderedImage.
+     */
+    public ColorModel getColorModel();
+
+    /**
+     * Gets the width of the RenderedImage.
+     * 
+     * @return the width of the RenderedImage.
+     */
+    public int getWidth();
+
+    /**
+     * Gets the tile width.
+     * 
+     * @return the tile width in pixels.
+     */
+    public int getTileWidth();
+
+    /**
+     * Gets the tile height.
+     * 
+     * @return the tile height in pixels.
+     */
+    public int getTileHeight();
+
+    /**
+     * Gets the Y offset of the tile grid.
+     * 
+     * @return the Y offset of the tile grid.
+     */
+    public int getTileGridYOffset();
+
+    /**
+     * Gets the X offset of the tile grid.
+     * 
+     * @return the X offset of the tile grid.
+     */
+    public int getTileGridXOffset();
+
+    /**
+     * Gets the number of tiles along Y direction.
+     * 
+     * @return the number of tiles along Y direction.
+     */
+    public int getNumYTiles();
+
+    /**
+     * Gets the number of tiles along X direction.
+     * 
+     * @return the number of tiles along X direction.
+     */
+    public int getNumXTiles();
+
+    /**
+     * Gets the minimum Y coordinate of this RenderedImage.
+     * 
+     * @return the minimum Y coordinate of this RenderedImage.
+     */
+    public int getMinY();
+
+    /**
+     * Gets the minimum X coordinate of this RenderedImage.
+     * 
+     * @return the minimum X coordinate of this RenderedImage.
+     */
+    public int getMinX();
+
+    /**
+     * Gets the minimum tile's index along the Y direction.
+     * 
+     * @return the minimum tile's index along the Y direction.
+     */
+    public int getMinTileY();
+
+    /**
+     * Gets the minimum tile's index along the X direction.
+     * 
+     * @return the minimum tile's index along the X direction.
+     */
+    public int getMinTileX();
+
+    /**
+     * Gets the height of the RenderedImage.
+     * 
+     * @return the height of the RenderedImage.
+     */
+    public int getHeight();
+
+}
+
diff --git a/awt/java/awt/image/ReplicateScaleFilter.java b/awt/java/awt/image/ReplicateScaleFilter.java
new file mode 100644
index 0000000..9298125
--- /dev/null
+++ b/awt/java/awt/image/ReplicateScaleFilter.java
@@ -0,0 +1,213 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The ReplicateScaleFilter class scales an source image 
+ * by replicating rows and columns of pixels to scale up or 
+ * omitting rows and columns of pixels to scale down.
+ */
+public class ReplicateScaleFilter extends ImageFilter {
+
+    /** The width of a source image. */
+    protected int srcWidth;
+
+    /** The height of a source image. */
+    protected int srcHeight;
+
+    /** The width of a destination image. */
+    protected int destWidth;
+
+    /** The height of a destination image. */
+    protected int destHeight;
+
+    /** The int array of source rows. */
+    protected int[] srcrows;
+
+    /** The int array of source columns. */
+    protected int[] srccols;
+
+    /** 
+     * An Object (byte array with a destination width) provides 
+     * a row of pixel data to the ImageConsumer. 
+     */
+    protected Object outpixbuf;
+
+    /**
+     * Instantiates a new ReplicateScaleFilter that filters 
+     * the image with the specified width and height.
+     * 
+     * @param width the width of scaled image.
+     * @param height the height of scaled image.
+     */
+    public ReplicateScaleFilter(int width, int height) {
+        if(width == 0 || height == 0) {
+            // awt.234=Width or Height equals zero
+            throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$
+        }
+
+        this.destWidth = width;
+        this.destHeight = height;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Rescale Filters"; //$NON-NLS-1$
+        String prop = "destWidth=" + destWidth + "; " +  //$NON-NLS-1$ //$NON-NLS-2$
+        "destHeight=" + destHeight; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+     }
+
+    // setPixels methods produce pixels according to Java API Spacification
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, int[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        int buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof int[])){
+            buff = new int[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (int[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, byte[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        byte buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof byte[])){
+            buff = new byte[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (byte[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        srcWidth = w;
+        srcHeight = h;
+
+        if(destWidth < 0 && destHeight < 0){
+            destWidth = srcWidth;
+            destHeight = srcHeight;
+        }else if(destWidth < 0){
+            destWidth = destHeight * srcWidth / srcHeight;
+        }else if(destHeight < 0){
+            destHeight = destWidth * srcHeight / srcWidth;
+        }
+        consumer.setDimensions(destWidth, destHeight);
+    }
+
+    /**
+     * Initialization of srccols and srcrows arrays.
+     */
+    private void initArrays(){
+        if ((destWidth < 0) || (destHeight < 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+        
+        srccols = new int[destWidth];
+        int ca = srcWidth >>> 1;
+        for(int i = 0; i < destWidth; i++){
+            srccols[i] = (i * srcWidth + ca) / destWidth;
+        }
+
+        srcrows = new int[destHeight];
+        int ra = srcHeight >>> 1;
+        for(int i = 0; i < destHeight; i++){
+            srcrows[i] = (i * srcHeight + ra) / destHeight;
+        }
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/RescaleOp.java b/awt/java/awt/image/RescaleOp.java
new file mode 100644
index 0000000..0e96031
--- /dev/null
+++ b/awt/java/awt/image/RescaleOp.java
@@ -0,0 +1,659 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 6, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RescaleOp performs rescaling of the source image data
+ * by multiplying the pixel values with a scale factor 
+ * and then adding an offset.
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp {
+    
+    /** The scale factors. */
+    private float scaleFactors[];
+    
+    /** The offsets. */
+    private float offsets[];
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factors and offsets.
+     * 
+     * @param scaleFactors the array of scale factor values.
+     * @param offsets the array of offset values.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float[] scaleFactors, float[] offsets, RenderingHints hints) {
+        int numFactors = Math.min(scaleFactors.length, offsets.length);
+
+        this.scaleFactors = new float[numFactors];
+        this.offsets = new float[numFactors];
+
+        System.arraycopy(scaleFactors, 0, this.scaleFactors, 0, numFactors);
+        System.arraycopy(offsets, 0, this.offsets, 0, numFactors);
+
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factor and offset.
+     * 
+     * @param scaleFactor the scale factor.
+     * @param offset the offset.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float scaleFactor, float offset, RenderingHints hints) {
+        scaleFactors = new float[1];
+        offsets = new float[1];
+
+        scaleFactors[0] = scaleFactor;
+        offsets[0] = offset;
+
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the number of scaling factors.
+     * 
+     * @return the number of scaling factors.
+     */
+    public final int getNumFactors() {
+        return scaleFactors.length;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    /**
+     * Gets the scale factors of this RescaleOp.
+     * 
+     * @param scaleFactors the desired scale factors array will be copied 
+     * to this array.
+     * 
+     * @return the scale factors array.
+     */
+    public final float[] getScaleFactors(float[] scaleFactors) {
+        if (scaleFactors == null) {
+            scaleFactors = new float[this.scaleFactors.length];
+        }
+
+        int minLength = Math.min(scaleFactors.length, this.scaleFactors.length);
+        System.arraycopy(this.scaleFactors, 0, scaleFactors, 0, minLength);
+        return scaleFactors;
+    }
+
+    /**
+     * Gets the offsets array of this RescaleOp.
+     * 
+     * @param offsets the desired offsets array will be copied to this array.
+     * 
+     * @return the offsets array of this RescaleOp.
+     */
+    public final float[] getOffsets(float[] offsets) {
+        if (offsets == null) {
+            offsets = new float[this.offsets.length];
+        }
+
+        int minLength = Math.min(offsets.length, this.offsets.length);
+        System.arraycopy(this.offsets, 0, offsets, 0, minLength);
+        return offsets;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                // awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
+                throw new IllegalArgumentException(Messages.getString("awt.21D", //$NON-NLS-1$
+                        src.getNumBands(), dst.getNumBands()));
+            }
+        }
+
+        if (
+                this.scaleFactors.length != 1 &&
+                this.scaleFactors.length != src.getNumBands()
+        ) {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        SampleModel sm = src.getSampleModel();
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int srcMinX = src.getMinX();
+        int srcMinY = src.getMinY();
+        int dstMinX = dst.getMinX();
+        int dstMinY = dst.getMinY();
+
+        int[] maxValues = new int[numBands];
+        int[] masks = new int[numBands];
+        int[] sampleSizes = sm.getSampleSize();
+
+        for (int i=0; i < numBands; i++){
+            maxValues[i] = (1 << sampleSizes[i]) - 1;
+            masks[i] = ~(maxValues[i]);
+        }
+
+        // Processing bounds
+        float[] pixels = null;
+        pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+
+        // Cycle over pixels to be calculated
+        if (skipAlpha) { // Always suppose that alpha channel is the last band
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            }
+        } else {
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, pixels);
+
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (scaleFactors.length == 1 || scaleFactors.length == nComponents-1) {
+                skipAlpha = true;
+            } else if (scaleFactors.length == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.21E=Number of scaling constants is not equal to the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+            }
+        } else if (scaleFactors.length == 1 || scaleFactors.length == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, srcCM);
+        } else if (!srcCM.equals(dst.getColorModel())) {
+            // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+            if (
+                    !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                       src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                      (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                       dst.getType() == BufferedImage.TYPE_INT_ARGB))
+            ) {
+                finalDst = dst;
+                dst = createCompatibleDestImage(src, srcCM);
+            }
+        }
+
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // Don't forget to pass allocated arrays for levels and values, size should be numBands*4
+    /**
+     * Creates the levels.
+     * 
+     * @param sm the sm
+     * @param numBands the num bands
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createLevels(
+            SampleModel sm, int numBands, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        // Suppose same sample size for all channels, otherwise use slow filter
+        int maxValue = (1 << sm.getSampleSize(0)) - 1;
+
+        // For simplicity introduce these arrays
+        float extScaleFactors[] = new float[numBands];
+        float extOffsets[] = new float[numBands];
+
+        if (scaleFactors.length != 1) {
+            System.arraycopy(scaleFactors, 0, extScaleFactors, 0, scaleFactors.length);
+            System.arraycopy(offsets, 0, extOffsets, 0, scaleFactors.length);
+        } else {
+            for (int i = 0; i < numBands; i++) {
+                extScaleFactors[i] = scaleFactors[0];
+                extOffsets[i] = offsets[0];
+            }
+        }
+
+        if (skipAlpha) {
+            extScaleFactors[numBands-1] = 1;
+            extOffsets[numBands-1] = 0;
+        }
+
+        // Create a levels
+        for (int i=0; i<numBands; i++) {
+            if (extScaleFactors[i] == 0) {
+                levels[i*4] = 0;
+                levels[i*4+1] = 0;
+                levels[i*4+2] = maxValue+1;
+                levels[i*4+3] = maxValue+1;
+            }
+
+            float minLevel = -extOffsets[i] / extScaleFactors[i];
+            float maxLevel = (maxValue - extOffsets[i]) / extScaleFactors[i];
+
+            if (minLevel < 0) {
+                minLevel = 0;
+            } else if (minLevel > maxValue){
+                minLevel = maxValue;
+            }
+
+            if (maxLevel < 0) {
+                maxLevel = 0;
+            } else if (maxLevel > maxValue){
+                maxLevel = maxValue;
+            }
+
+            levels[i*4] = 0;
+            if (minLevel > maxLevel) {
+                levels[i*4+1] = (int) maxLevel;
+                levels[i*4+2] = (int) minLevel;
+            } else {
+                levels[i*4+1] = (int) minLevel;
+                levels[i*4+2] = (int) maxLevel;
+            }
+            levels[i*4+3] = maxValue+1;
+
+            // Fill values
+            for (int k=0; k<4; k++) {
+                int idx = i*4+k;
+                values[idx] = (int) (extScaleFactors[i] * levels[idx] + extOffsets[i]);
+                if (values[idx] < 0) {
+                    values[idx] = 0;
+                } else if (values[idx] > maxValue){
+                    values[idx] = maxValue;
+                }
+            }
+        }
+
+        // Reorder data if channels are stored in different order
+        if (channelsOrder != null) {
+            int len = numBands*4;
+            int savedLevels[] = new int[len];
+            int savedValues[] = new int[len];
+            System.arraycopy(levels, 0, savedLevels, 0, len);
+            System.arraycopy(values, 0, savedValues, 0, len);
+            for (int i = 0; i < channelsOrder.length; i++) {
+                System.arraycopy(savedLevels, i*4, levels, channelsOrder[i]*4, 4);
+                System.arraycopy(savedValues, i*4, values, channelsOrder[i]*4, 4);
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = new int[4*channels];
+        int values[] = new int[4*channels];
+
+        createLevels(src.getSampleModel(), channels, skipAlpha, levels, values, channelsOrder);
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = LookupOp.ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            true
+        );
+
+        return res;
+    }
+}
diff --git a/awt/java/awt/image/SampleModel.java b/awt/java/awt/image/SampleModel.java
new file mode 100644
index 0000000..44059a0
--- /dev/null
+++ b/awt/java/awt/image/SampleModel.java
@@ -0,0 +1,1053 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SampleModel class is abstract class for retrieving pixel's samples
+ * in the data of an image. Each pixel contains several samples. A 
+ * sample is the set of values of the bands for single pixel. 
+ * For example, each pixel in the RGB model contains three samples 
+ * and there are three corresponding bands in the image 
+ * data of such pixels representing red, green and blue components.
+ * <p> 
+ * The image data is represented as a Raster with a DataBuffer 
+ * and a SampleModel. The SampleModel allows access to the samples in the 
+ * DataBuffer. 
+ */
+public abstract class SampleModel {
+
+    /** The width of the image data which this SampleModel describes. */
+    protected int width;
+
+    /** The height of the image data which this SampleModel describes. */
+    protected int height;
+
+    /** The number of bands of image data which this SampleModel describes. */
+    protected int numBands;
+
+    /** The data type of the image data which this SampleModel describes. */
+    protected int dataType;
+
+    /**
+     * Instantiates a new SampleModel with the specified data type,
+     * width, height and number of bands.
+     * 
+     * @param dataType the data type of the image data.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numBands the number of bands of the image data.
+     */
+    public SampleModel(int dataType, int w, int h, int numBands) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        double squre = ((double) w) * ((double) h);
+        if (squre >= Integer.MAX_VALUE) {
+            // awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+            throw new IllegalArgumentException(Messages.getString("awt.22F")); //$NON-NLS-1$
+        }
+
+        if (dataType < DataBuffer.TYPE_BYTE ||
+                dataType > DataBuffer.TYPE_DOUBLE &&
+                dataType != DataBuffer.TYPE_UNDEFINED) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (numBands < 1) {
+            // awt.231=Number of bands must be more then 0
+            throw new IllegalArgumentException(Messages.getString("awt.231")); //$NON-NLS-1$
+        }
+
+        this.dataType = dataType;
+        this.width = w;
+        this.height = h;
+        this.numBands = numBands;
+
+    }
+
+    /**
+     * Gets the data array for the specified pixel of the specified 
+     * DataBuffer with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object is a data where the result will be stored.
+     * @param data the image data.
+     * 
+     * @return the data array for the specified pixel of the specified 
+     * DataBuffer.
+     */
+    public abstract Object getDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Gets the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer with one of 
+     * the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * 
+     * @param x the X coordinate of the rectangular pixel area.
+     * @param y the Y coordinate of the rectangular pixel area.
+     * @param w the width of the rectangular pixel area.
+     * @param h the height of the rectangular pixel area.
+     * @param obj the Object is an array with the primitive type,
+     * where the result array will be stored.
+     * @param data the image data.
+     * 
+     * @return the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer object.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            byte bbuf[] = null;
+
+            if (obj == null) {
+                bdata = new byte[numDataElements * w * h];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    bbuf = (byte[]) getDataElements(j, i, bbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        bdata[idx++] = bbuf[n];
+                    }
+                }
+            }
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            short sbuf[] = null;
+
+            if (obj == null) {
+                sdata = new short[numDataElements * w * h];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    sbuf = (short[]) getDataElements(j, i, sbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        sdata[idx++] = sbuf[n];
+                    }
+                }
+            }
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            int ibuf[] = null;
+
+            if (obj == null) {
+                idata = new int[numDataElements * w * h];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    ibuf = (int[]) getDataElements(j, i, ibuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        idata[idx++] = ibuf[n];
+                    }
+                }
+            }
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            float fbuf[] = null;
+
+            if (obj == null) {
+                fdata = new float[numDataElements * w * h];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    fbuf = (float[]) getDataElements(j, i, fbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        fdata[idx++] = fbuf[n];
+                    }
+                }
+            }
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            double dbuf[] = null;
+
+            if (obj == null) {
+                ddata = new double[numDataElements * w * h];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    dbuf = (double[]) getDataElements(j, i, dbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        ddata[idx++] = dbuf[n];
+                    }
+                }
+            }
+            obj = ddata;
+            break;
+
+        }
+
+        return obj;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer
+     * from a primitive array with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public abstract void setDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Sets the data elements for a rectangular area of pixels in 
+     * the specified DataBuffer from a primitive array with one of 
+     * the following types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of the specified rectangular area.
+     * @param y the Y coordinate of the specified rectangular area.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bbuf[] = new byte[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        bbuf[n] = ((byte[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, bbuf, data);
+                }
+            }
+
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sbuf[] = new short[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        sbuf[n] = ((short[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, sbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ibuf[] = new int[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        ibuf[n] = ((int[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, ibuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fbuf[] = new float[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        fbuf[n] = ((float[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, fbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dbuf[] = new double[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        dbuf[n] = ((double[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, dbuf, data);
+                }
+            }
+            break;
+
+        }
+    }
+
+    /**
+     * Creates a new SampleModel with the specified bands of 
+     * this SampleModel.
+     * 
+     * @param bands the array of bands from this SampleModel.
+     * 
+     * @return the SampleModel with the specified bands of 
+     * this SampleModel.
+     */
+    public abstract SampleModel createSubsetSampleModel(int bands[]);
+
+    /**
+     * Creates the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     * 
+     * @param a0 the width of the image data.
+     * @param a1 the height of the image data.
+     * 
+     * @return the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     */
+    public abstract SampleModel createCompatibleSampleModel(int a0, int a1);
+
+    /**
+     * Gets the samples of the specified pixel as a int array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified pixel.
+
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a int array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a float array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified pixel.
+     */
+    public float[] getPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixel[];
+
+        if (fArray == null) {
+            pixel = new float[numBands];
+        } else {
+            pixel = fArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleFloat(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a float array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, fArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a double array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified pixel.
+     */
+    public double[] getPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixel[];
+
+        if (dArray == null) {
+            pixel = new double[numBands];
+        } else {
+            pixel = dArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleDouble(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a double array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, dArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as an int.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a float.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a double.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[];
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from an int array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixels[];
+        int idx = 0;
+
+        if (fArray == null) {
+            pixels = new float[w * h * numBands];
+        } else {
+            pixels = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleFloat(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a float array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, fArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixels[];
+        int idx = 0;
+
+        if (dArray == null) {
+            pixels = new double[w * h * numBands];
+        } else {
+            pixels = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleDouble(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a double array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, dArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as int value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as an int value.
+     * @param data the image data.
+     */
+    public abstract void setSample(int x, int y, int b, int s, DataBuffer data);
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a int array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an int array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a float array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b,
+            float fArray[], DataBuffer data) {
+        float samples[];
+        int idx = 0;
+
+        if (fArray == null) {
+            samples = new float[w * h];
+        } else {
+            samples = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleFloat(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an float array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, fArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a double array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[], DataBuffer data) {
+        double samples[];
+        int idx = 0;
+
+        if (dArray == null) {
+            samples = new double[w * h];
+        } else {
+            samples = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleDouble(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an double array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, dArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as float value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as float value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as double value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as double value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Creates a DataBuffer object which corresponds to the SampleModel. 
+     *  
+     * @return the DataBuffer object which corresponds to 
+     * the SampleModel.
+     */
+    public abstract DataBuffer createDataBuffer();
+
+    /**
+     * Gets the sample size in bits for the specified band.
+     * 
+     * @param band the specified band.
+     * 
+     * @return the sample size in bits for the specified band.
+     */
+    public abstract int getSampleSize(int band);
+
+    /**
+     * Gets an array of the sample size in bits for all bands.
+     *  
+     * @return an array of the sample size in bits for all bands.
+     */
+    public abstract int[] getSampleSize();
+
+    /**
+     * Gets the width of the image data of this SampleModel object.
+     * 
+     * @return the width of the image data of this SampleModel object.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the transfer type used to transfer pixels via 
+     * the getDataElements and setDataElements methods.
+     * Transfer type value can be one of the predefined type 
+     * from DataBuffer class or not.
+     * 
+     * @return the transfer type.
+     */
+    public int getTransferType() {
+        return dataType;
+    }
+
+    /**
+     * Returns the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods. 
+     * 
+     * @return the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods.
+     */
+    public abstract int getNumDataElements();
+
+    /**
+     * Gets the number of bands in the image data of this 
+     * SampleModel object.
+     * 
+     * @return the number of bands in the image data of this 
+     * SampleModel object.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the height of the image data of this SampleModel object.
+     * 
+     * @return the height of the image data of this SampleModel object.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the data type of image data of this SampleModel object.
+     * 
+     * @return the data type of image data of this SampleModel object.
+     */
+    public final int getDataType() {
+        return dataType;
+    }
+
+}
+
diff --git a/awt/java/awt/image/ShortLookupTable.java b/awt/java/awt/image/ShortLookupTable.java
new file mode 100644
index 0000000..77c9c45
--- /dev/null
+++ b/awt/java/awt/image/ShortLookupTable.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+
+/**
+ * The ShortLookupTable class provides provides functionality for 
+ * lookup operations, and is defined by an input short array for 
+ * bands or components of image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an unsigned short array.
+ */
+public class ShortLookupTable extends LookupTable {
+    
+    /** The data. */
+    private short data[][];
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array which represents lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array.
+     */
+    public ShortLookupTable(int offset, short[] data) {
+        super(offset, 1);
+        this.data = new short[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array of arrays which represents lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of arrays for each band.
+     */
+    public ShortLookupTable(int offset, short[][] data) {
+        super(offset, data.length);
+        this.data = new short[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ShortLookupTable object. If 
+     * this ShortLookupTable object has one short array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ShortLookupTable object.
+     */
+    public final short[][] getTable() {
+        return data;
+    }
+
+    /**
+     * Returns a short array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ShortLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the short array of translated samples of a pixel.
+     */
+    public short[] lookupPixel(short[] src, short[] dst) {
+        if (dst == null) {
+            dst = new short[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/SinglePixelPackedSampleModel.java b/awt/java/awt/image/SinglePixelPackedSampleModel.java
new file mode 100644
index 0000000..311395a
--- /dev/null
+++ b/awt/java/awt/image/SinglePixelPackedSampleModel.java
@@ -0,0 +1,508 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SinglePixelPackedSampleModel class represents pixel data 
+ * where several samples combine to create a single pixel and 
+ * are stored in a single data array element. This class 
+ * supports TYPE_BYTE, TYPE_USHORT, TYPE_INT data types. 
+ */
+public class SinglePixelPackedSampleModel extends SampleModel {
+
+    /** The bit masks. */
+    private int bitMasks[];
+
+    /** The bit offsets. */
+    private int bitOffsets[];
+
+    /** The bit sizes. */
+    private int bitSizes[];
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The max bit size. */
+    private int maxBitSize;
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int bitMasks[]) {
+        this(dataType, w, h, w, bitMasks);
+    }
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride The scanline stride of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int scanlineStride, int bitMasks[]) {
+
+        super(dataType, w, h, bitMasks.length);
+
+        if (dataType != DataBuffer.TYPE_BYTE &&
+                dataType != DataBuffer.TYPE_USHORT &&
+                dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        this.bitMasks = bitMasks.clone();
+        this.bitOffsets = new int[this.numBands];
+        this.bitSizes = new int[this.numBands];
+
+        this.maxBitSize = 0;
+
+        for (int i = 0; i < this.numBands; i++) {
+            int offset = 0;
+            int size = 0;
+            int mask = bitMasks[i];
+
+            if (mask != 0) {
+                while ((mask & 1) == 0) {
+                    mask >>>= 1;
+                    offset++;
+                }
+
+                while ((mask & 1) == 1) {
+                    mask >>>= 1;
+                    size++;
+                }
+
+                if (mask != 0) {
+                    // awt.62=Wrong mask : {0}
+                    throw new IllegalArgumentException(Messages.getString(
+                            "awt.62", bitMasks[i])); //$NON-NLS-1$
+                }
+            }
+
+            this.bitOffsets[i] = offset;
+            this.bitSizes[i] = size;
+
+            if (this.maxBitSize < size) {
+                this.maxBitSize = size;
+            }
+
+        }
+
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            bdata[0] = (byte) data.getElem(y * scanlineStride + x);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            sdata[0] = (short) data.getElem(y * scanlineStride + x);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            idata[0] = data.getElem(y * scanlineStride + x);
+            obj = idata;
+            break;
+        }
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            data.setElem(y * scanlineStride + x, ((byte[]) obj)[0] & 0xff);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data.setElem(y * scanlineStride + x, ((short[]) obj)[0] & 0xffff);
+            break;
+        case DataBuffer.TYPE_INT:
+            data.setElem(y * scanlineStride + x, ((int[]) obj)[0]);
+            break;
+        }
+    }
+
+    /**
+     * Compares this SinglePixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if this SinglePixelPackedSampleModel object is 
+     * equal to the specified object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel) o;
+        return this.width == model.width &&
+                this.height == model.height &&
+                this.numBands == model.numBands &&
+                this.dataType == model.dataType &&
+                Arrays.equals(this.bitMasks, model.bitMasks) &&
+                Arrays.equals(this.bitOffsets, model.bitOffsets) &&
+                Arrays.equals(this.bitSizes, model.bitSizes) &&
+                this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int masks[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            masks[i] = this.bitMasks[bands[i]];
+        }
+        return new SinglePixelPackedSampleModel(this.dataType, this.width,
+                this.height, this.scanlineStride, masks);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(this.dataType, w, h,
+                this.bitMasks);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[this.numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < this.numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < this.numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int sample = data.getElem(y * scanlineStride + x);
+        return ((sample & this.bitMasks[b]) >>> this.bitOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int pixels[];
+
+        if (iArray == null) {
+            pixels = new int[w * h * this.numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int tmp = data.getElem(y * scanlineStride + x);
+        tmp &= ~this.bitMasks[b];
+        tmp |= (s << this.bitOffsets[b]) & this.bitMasks[b];
+        data.setElem(y * scanlineStride + x, tmp);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(x + j, y + i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = (this.height - 1) * scanlineStride + width;
+
+        switch (this.dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return data;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return (y * scanlineStride + x);
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return bitSizes[band];
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        return bitSizes.clone();
+    }
+
+    /**
+     * Gets an array of the bit offsets of the data array elements. 
+     * 
+     * @return an array of the bit offsets.
+     */
+    public int[] getBitOffsets() {
+        return bitOffsets.clone();
+    }
+
+    /**
+     * Gets an array of the bit masks for all bands.
+     * 
+     * @return an array of the bit masks for all bands.
+     */
+    public int[] getBitMasks() {
+        return bitMasks.clone();
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bitMasks) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitSizes) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride.
+     * 
+     * @return the scanline stride
+     */
+    public int getScanlineStride() {
+        return this.scanlineStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+}
+
diff --git a/awt/java/awt/image/TileObserver.java b/awt/java/awt/image/TileObserver.java
new file mode 100644
index 0000000..39ded02
--- /dev/null
+++ b/awt/java/awt/image/TileObserver.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * An asynchronous update interface for receiving notifications
+ * about tile information when tiles of a WritableRenderedImage 
+ * become modifiable or unmodifiable.
+ */
+public interface TileObserver {
+
+    /**
+     * This method is called when information about a tile
+     * update is available.
+     * 
+     * @param source the source image.
+     * @param tileX the X index of the tile.
+     * @param tileY the Y index of the tile.
+     * @param willBeWritable parameter which indicates whether
+     * the tile will be grabbed for writing or be released.
+     */
+    public void tileUpdate(WritableRenderedImage source, int tileX, int tileY, boolean willBeWritable);
+
+}
+
diff --git a/awt/java/awt/image/VolatileImage.java b/awt/java/awt/image/VolatileImage.java
new file mode 100644
index 0000000..3b0cfb2
--- /dev/null
+++ b/awt/java/awt/image/VolatileImage.java
@@ -0,0 +1,144 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.ImageCapabilities;
+import java.awt.Transparency;
+
+/**
+ * The VolatileImage abstract class represents an image which can lose 
+ * its contents at any point. VolatileImage objects are device specific.
+ * This class provies methods for checking if operation of this image
+ * are compatible for the GraphicsConfiguration. 
+ */
+public abstract class VolatileImage extends Image
+    // Volatile image implements Transparency since 1.5
+    implements Transparency {
+    
+    /** 
+     * The Constant IMAGE_INCOMPATIBLE indicates that this VolatileImage 
+     * is not applicable for the GraphicsConfiguration object. 
+     */
+    public static final int IMAGE_INCOMPATIBLE = 2;
+
+    /** 
+     * The Constant IMAGE_OK indicates that VolatileImage is ready 
+     * for using.
+     */
+    public static final int IMAGE_OK = 0;
+
+    /** 
+     * The Constant IMAGE_RESTORED indicates that VolatileImage
+     * will be ready to use after restoring. 
+     */
+    public static final int IMAGE_RESTORED = 1;
+
+    /** 
+     * The transparency value of this image. 
+     */
+    protected int transparency = OPAQUE;
+
+    /**
+     * Instantiates a new VolatileImage object.
+     */
+    public VolatileImage() {
+        super();
+    }
+
+    /**
+     * Returns true if rendering data is lost during validating.
+     * This method should be called after rendering operation of image.
+     * 
+     * @return true, if contents lost during validating, false otherwise.
+     */
+
+    public abstract boolean contentsLost();
+
+    /**
+     * Creates a Graphics2D used to draw in this VolatileImage.
+     * 
+     * @return the Graphics2D object.
+     */
+    public abstract Graphics2D createGraphics();
+
+    /**
+     * Gets the ImageCapabilities of this VolatileImage.
+     * 
+     * @return the ImageCapabilities of this VolatileImage.
+     */
+    public abstract ImageCapabilities getCapabilities();
+
+    /**
+     * Gets the height of this VolatileImage.
+     * 
+     * @return the height of this VolatileImage.
+     */
+    public abstract int getHeight();
+
+    /**
+     * Gets a BufferedImage representation of current VolatileImage that
+     * won't be affected by any changes to this VolatileImage.
+     * 
+     * @return a BufferedImage representation of current VolatileImage.
+     */
+    public abstract BufferedImage getSnapshot();
+
+    /**
+     * Gets the width of this VolatileImage.
+     * 
+     * @return the width of this VolatileImage.
+     */
+    public abstract int getWidth();
+
+    /**
+     * Validates the drawing surface of the image if the surface had been 
+     * lost and if the spacified GraphicsConfiguration object is  
+     * applicable to this image. 
+     * 
+     * @param gc GraphicsConfiguration object.
+     * 
+     * @return one of the image status constants: IMAGE_OK, IMAGE_RESTORED or
+     * IMAGE_INCOMPATIBLE.
+     */
+    public abstract int validate(GraphicsConfiguration gc);
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return getSnapshot().getSource();
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+}
diff --git a/awt/java/awt/image/WritableRaster.java b/awt/java/awt/image/WritableRaster.java
new file mode 100644
index 0000000..0893915
--- /dev/null
+++ b/awt/java/awt/image/WritableRaster.java
@@ -0,0 +1,516 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The WritableRaster class provides functionality for 
+ * writing samples and pixel capabilities to the Raster.
+ */
+public class WritableRaster extends Raster {
+
+    /**
+     * Instantiates a new WritableRaster object with the specified 
+     * SampleModel, DataBuffer, rectangular region and parent 
+     * WritableRaster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel to the new WritableRaster coordinates.
+     * @param parent the parent of this WritableRaster.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate,
+            WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    /**
+     * Instantiates a new WritableRaster object with the specified
+     * SampleModel which defines a layout of this WritableRaster and 
+     * DataBuffer objects which defines the image data.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param origin the point of origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.width, sampleModel.height), origin, null);
+    }
+
+    /**
+     * Instantiates a new WritableRaster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.width, sampleModel.height),
+                origin, null);
+    }
+
+    /**
+     * Sets the data for a single pixel from an input Object which 
+     * represents an array of primitive types: DataBuffer.TYPE_BYTE, 
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param inData the input data.
+     */
+    public void setDataElements(int x, int y, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, inData, dataBuffer);
+    }
+
+    /**
+     * Sets the data elements which represent pixel data to the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param inData the array of primitive type data to be set to the
+     * specified area.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, inData, dataBuffer);
+    }
+
+    /**
+     * Creates the child of this WritableRaster by sharing the specified 
+     * rectangular area in this WritableRaster. 
+     * The parentX, parentY, width and height parameters specify rectangular
+     * area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param parentY the Y coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param w the width of the child area.
+     * @param h the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the child WritableRaster.
+     */
+    public WritableRaster createWritableChild(int parentX, int parentY, int w,
+            int h, int childMinX, int childMinY, int bandList[]) {
+        if (w <= 0 || h <= 0) {
+            // awt.244=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + w > this.minX + this.width) {
+            // awt.245=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + h > this.minY + this.height) {
+            // awt.246=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + w > Integer.MAX_VALUE) {
+            // awt.247=parentX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + h > Integer.MAX_VALUE) {
+            // awt.248=parentY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + w > Integer.MAX_VALUE) {
+            // awt.249=childMinX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + h > Integer.MAX_VALUE) {
+            // awt.24A=childMinY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new WritableRaster(childModel, dataBuffer,
+                new Rectangle(childMinX, childMinY, w, h),
+                new Point(childTranslateX + sampleModelTranslateX,
+                        childTranslateY + sampleModelTranslateY),
+                this);
+    }
+
+    /**
+     * Creates the translated child of this WritableRaster. 
+     * New WritableRaster object is a reference to the this 
+     * WritableRaster and with different location. 
+     *  
+     * @param childMinX the X coordinate of the new WritableRaster.
+     * @param childMinY the Y coordinate of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+            int childMinY) {
+        return createWritableChild(minX, minY, width, height, childMinX,
+                childMinY, null);
+    }
+
+    /**
+     * Gets the parent WritableRaster for this WritableRaster object. 
+     * 
+     * @return the parent WritableRaster for this WritableRaster object.
+     */
+    public WritableRaster getWritableParent() {
+        return (WritableRaster) parent;
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster.
+     * 
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(Raster srcRaster) {
+        setRect(0, 0, srcRaster);
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster. Each pixel with (x, y) coordinates from the source 
+     * Raster is copied to pixel with (x+dx, y+dy) coordinates in this
+     * WritableRaster. The pixels with (x+dx, y+dy) coordinates which
+     * are out the bounds of this raster are ignored. 
+     *  
+     * @param dx the distance the pixel's X coordinate in the source
+     * Raster is translated when writtien to this WritableRaster. 
+     * @param dy the distance the pixel's Y coordinate in the source
+     * Raster is translated when writtien to this WritableRaster.
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        int w = srcRaster.getWidth();
+        int h = srcRaster.getHeight();
+
+        int srcX = srcRaster.getMinX();
+        int srcY = srcRaster.getMinY();
+
+        int dstX = srcX + dx;
+        int dstY = srcY + dy;
+
+        if (dstX < this.minX) {
+            int minOffX = this.minX - dstX;
+            w -= minOffX;
+            dstX = this.minX;
+            srcX += minOffX;
+        }
+
+        if (dstY < this.minY) {
+            int minOffY = this.minY - dstY;
+            h -= minOffY;
+            dstY = this.minY;
+            srcY += minOffY;
+        }
+
+        if (dstX + w > this.minX + this.width) {
+            int maxOffX = (dstX + w) - (this.minX + this.width);
+            w -= maxOffX;
+        }
+
+        if (dstY + h > this.minY + this.height) {
+            int maxOffY = (dstY + h) - (this.minY + this.height);
+            h -= maxOffY;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        switch (sampleModel.getDataType()) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            int iPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        iPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, iPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        fPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, fPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        dPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, dPixelsLine);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from an input Raster to
+     * this WritableRaster.
+     * 
+     * @param x the X coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param y the Y coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param inRaster the input Raster.
+     */
+    public void setDataElements(int x, int y, Raster inRaster) {
+        int dstX = x + inRaster.getMinX();
+        int dstY = y + inRaster.getMinY();
+
+        int w = inRaster.getWidth();
+        int h = inRaster.getHeight();
+
+        if (dstX < this.minX || dstX + w > this.minX + this.width ||
+                dstY < this.minY || dstY + h > this.minY + this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int srcX = inRaster.getMinX();
+        int srcY = inRaster.getMinY();
+        Object line = null;
+
+        for (int i = 0; i < h; i++) {
+            line = inRaster.getDataElements(srcX, srcY + i, w, 1, line);
+            setDataElements(dstX, dstY + i, w, 1, line);
+        }
+    }
+
+    /**
+     * Sets a int array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array of samples.
+     */
+    public void setPixel(int x, int y, int iArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array of samples.
+     */
+    public void setPixel(int x, int y, float fArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array of samples.
+     */
+    public void setPixel(int x, int y, double dArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets a int array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param iArray the int array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param fArray the float array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param dArray the double array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with an int array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param iArray the int array of samples.
+
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a float array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param fArray the float array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a double array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param dArray the double array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with an int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, int s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a float sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, float s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, double s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+}
+
diff --git a/awt/java/awt/image/WritableRenderedImage.java b/awt/java/awt/image/WritableRenderedImage.java
new file mode 100644
index 0000000..ee1cb9e
--- /dev/null
+++ b/awt/java/awt/image/WritableRenderedImage.java
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The WriteableRenderedImage interface is interface for objects which
+ * contains Raster data of one or several tiles. This interface provides
+ * notification mehanism for obtaining tile's writing status.    
+ */
+public interface WritableRenderedImage extends RenderedImage {
+
+    /**
+     * Gets and checks out the writable tile for writing. 
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster getWritableTile(int tileX, int tileY);
+
+    /**
+     * Removes the registered TileObserver.
+     * 
+     * @param to the TileObserver which is registered for this
+     * WritableRenderedImage.
+     */
+    public void removeTileObserver(TileObserver to);
+
+    /**
+     * Adds the specified TileObserver to this WritableRenderedImage.
+     * 
+     * @param to the TileObserver object to be added.
+     */
+    public void addTileObserver(TileObserver to);
+
+    /**
+     * Sets this image to the contents of the specified Raster.  
+     * 
+     * @param r the specified Raster.
+     */
+    public void setData(Raster r);
+
+    /**
+     * Gets the array of points wich represent indices of tiles which
+     * are check out for writing.
+     * 
+     * @return the array of Points.
+     */
+    public Point[] getWritableTileIndices();
+
+    /**
+     * Checks if the specified tile is writable or not.
+     * 
+     * @param tileX the X index of tile. 
+     * @param tileY the Y index of tile.
+     * 
+     * @return true, if the specified tile is writable,
+     * false otherwise.
+     */
+    public boolean isTileWritable(int tileX, int tileY);
+
+    /**
+     * Release the specified writable tile. This method removes the writer 
+     * from the tile.
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     */
+    public void releaseWritableTile(int tileX, int tileY);
+
+    /**
+     * Checks if there is a tile which is checked out for writing.
+     * 
+     * @return true, if any tile is checked out for writing, false if there
+     * is no such tile.
+     */
+    public boolean hasTileWriters();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
new file mode 100644
index 0000000..3e96637
--- /dev/null
+++ b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating ContextualRenderedImage objects with utilities 
+ * for manipulating the properties in the parameter block.
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory {
+
+    /**
+     * Maps a render context to a parameter block and a renderable image.
+     * 
+     * @param a0 the index
+     * @param a1 the RenderContext
+     * @param a2 the ParameterBlock
+     * @param a3 the RenderableImage
+     * 
+     * @return the render context
+     */
+    public RenderContext mapRenderContext(int a0, RenderContext a1, ParameterBlock a2, RenderableImage a3);
+
+    /**
+     * Gets the value of the property from the parameter block.
+     * 
+     * @param a0 the parameter block to examine to find the property
+     * @param a1 the name of the property
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(ParameterBlock a0, String a1);
+
+    /**
+     * Creates the rendered image determined by the render context and
+     * parameter block.
+     * 
+     * @param a0 the RenderContext
+     * @param a1 the ParameterBlock
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(RenderContext a0, ParameterBlock a1);
+
+    /**
+     * Gets the bounding rectangle from the parameter block.
+     * 
+     * @param a0 the parameter block to read the bounds from
+     * 
+     * @return the bounding rectangle
+     */
+    public Rectangle2D getBounds2D(ParameterBlock a0);
+
+    /**
+     * Gets the names of all of the supported properties.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Checks if this image factory is dynamic.
+     * 
+     * @return true, if this image factory is dynamic
+     */
+    public boolean isDynamic();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ParameterBlock.java b/awt/java/awt/image/renderable/ParameterBlock.java
new file mode 100644
index 0000000..1555f45
--- /dev/null
+++ b/awt/java/awt/image/renderable/ParameterBlock.java
@@ -0,0 +1,548 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.RenderedImage;
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ * The Class ParameterBlock groups an indexed set of parameter data 
+ * with a set of renderable (source) images.  The mapping between
+ * the indexed parameters and their property names is provided 
+ * by a {@link ContextualRenderedImageFactory}
+ */
+public class ParameterBlock implements Cloneable, Serializable {
+
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7577115551785240750L;
+
+    /** The sources (renderable images). */
+    protected Vector<Object> sources = new Vector<Object>();
+
+    /** The parameters. */
+    protected Vector<Object> parameters = new Vector<Object>();
+
+    /**
+     * Instantiates a new parameter block.
+     * 
+     * @param sources the vector of source images
+     * @param parameters the vector of parameters
+     */
+    public ParameterBlock(Vector<Object> sources, Vector<Object> parameters) {
+        setSources(sources);
+        setParameters(parameters);
+    }
+
+    /**
+     * Instantiates a new parameter block with no parameters.
+     * 
+     * @param sources the vector of source images
+     */
+    public ParameterBlock(Vector<Object> sources) {
+        setSources(sources);
+    }
+
+    /**
+     * Instantiates a new parameter block with no image or parameter vectors.
+     */
+    public ParameterBlock() {}
+
+    /**
+     * Sets the source image at the specified index.
+     * 
+     * @param source the source image
+     * @param index the index where the source will be placed
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock setSource(Object source, int index) {
+        if(sources.size() < index + 1){
+            sources.setSize(index + 1);
+        }
+        sources.setElementAt(source, index);
+        return this;
+    }
+
+    /**
+     * Sets the parameter value object at the specified index.
+     * 
+     * @param obj the parameter value to place at the desired index
+     * @param index the index where the object is to be placed in the 
+     * vector of parameters
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(Object obj, int index) {
+        if(parameters.size() < index + 1){
+            parameters.setSize(index + 1);
+        }
+        parameters.setElementAt(obj, index);
+        return this;
+    }
+
+    /**
+     * Adds a source to the vector of sources.
+     * 
+     * @param source the source to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock addSource(Object source) {
+        sources.addElement(source);
+        return this;
+    }
+
+    /**
+     * Adds the object to the vector of parameter values
+     * 
+     * @param obj the obj to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(Object obj) {
+        parameters.addElement(obj);
+        return this;
+    }
+
+    /**
+     * Sets the vector of sources, replacing the existing
+     * vector of sources, if any.
+     * 
+     * @param sources the new sources
+     */
+    public void setSources(Vector<Object> sources) {
+        this.sources = sources;
+    }
+
+    /**
+     * Sets the vector of parameters, replacing the existing
+     * vector of parameters, if any.
+     * 
+     * @param parameters the new parameters
+     */
+    public void setParameters(Vector<Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Gets the vector of sources.
+     * 
+     * @return the sources
+     */
+    public Vector<Object> getSources() {
+        return sources;
+    }
+
+    /**
+     * Gets the vector of parameters.
+     * 
+     * @return the parameters
+     */
+    public Vector<Object> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Gets the source at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the source object found at the specified index
+     */
+    public Object getSource(int index) {
+        return sources.elementAt(index);
+    }
+
+    /**
+     * Gets the object parameter found at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the parameter object found at the specified index
+     */
+    public Object getObjectParameter(int index) {
+        return parameters.elementAt(index);
+    }
+
+    /**
+     * Shallow clone (clones using the superclass clone method).
+     * 
+     * @return the clone of this object
+     */
+    public Object shallowClone() {
+        try{
+            return super.clone();
+        }catch(Exception e){
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        ParameterBlock replica;
+        try{
+            replica = (ParameterBlock)super.clone();
+        }catch(Exception e){
+            return null;
+        }
+        if(sources != null){
+            replica.setSources((Vector<Object>)(sources.clone()));
+        }
+        if(parameters != null){
+            replica.setParameters((Vector<Object>)(parameters.clone()));
+        }
+        return replica;
+    }
+
+    /**
+     * Gets an array of classes corresponding to all of the parameter
+     * values found in the array of parameters, in order.
+     * 
+     * @return the parameter classes
+     */
+    public Class[] getParamClasses() {
+        int count = parameters.size();
+        Class paramClasses[] = new Class[count];
+
+        for(int i = 0; i < count; i++){
+            paramClasses[i] = parameters.elementAt(i).getClass();
+        }
+        return paramClasses;
+    }
+
+    /**
+     * Gets the renderable source image found at the specified index
+     * in the source array.
+     * 
+     * @param index the index
+     * 
+     * @return the renderable source image
+     */
+    public RenderableImage getRenderableSource(int index) {
+        return (RenderableImage)sources.elementAt(index);
+    }
+
+    /**
+     * Wraps the short value in a Short and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param s the short value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(short s, int index) {
+        return set(new Short(s), index);
+    }
+
+    /**
+     * Wraps the short value in a Short and adds it to the 
+     * parameter block.
+     * 
+     * @param s the short value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(short s) {
+        return add(new Short(s));
+    }
+
+    /**
+     * Wraps the long value in a Long and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param l the long value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(long l, int index) {
+        return set(new Long(l), index);
+    }
+
+    /**
+     * Wraps the long value in a Long and adds it to the 
+     * parameter block.
+     * 
+     * @param l the long value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(long l) {
+        return add(new Long(l));
+    }
+
+    /**
+     * Wraps the int value in an Integer and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param i the int value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(int i, int index) {
+        return set(new Integer(i), index);
+    }
+
+    /**
+     * Wraps the int value in an Integer and adds it to the 
+     * parameter block.
+     * 
+     * @param i the int value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(int i) {
+        return add(new Integer(i));
+    }
+
+    /**
+     * Wraps the float value in a Float and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param f the float value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(float f, int index) {
+        return set(new Float(f), index);
+    }
+
+    /**
+     * Wraps the float value in a Float and adds it to the 
+     * parameter block.
+     * 
+     * @param f the float value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(float f) {
+        return add(new Float(f));
+    }
+
+    /**
+     * Wraps the double value in a Double and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param d the double value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(double d, int index) {
+        return set(new Double(d), index);
+    }
+
+    /**
+     * Wraps the double value in a Double and adds it to the 
+     * parameter block.
+     * 
+     * @param d the double value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(double d) {
+        return add(new Double(d));
+    }
+
+    /**
+     * Wraps the char value in a Character and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param c the char value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(char c, int index) {
+        return set(new Character(c), index);
+    }
+
+    /**
+     * Wraps the char value in a Character and adds it to the 
+     * parameter block.
+     * 
+     * @param c the char value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(char c) {
+        return add(new Character(c));
+    }
+
+    /**
+     * Wraps the byte value in a Byte and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param b the byte value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(byte b, int index) {
+        return set(new Byte(b), index);
+    }
+
+    /**
+     * Wraps the byte value in a Byte and adds it to the 
+     * parameter block.
+     * 
+     * @param b the byte value of the parameter
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock add(byte b) {
+        return add(new Byte(b));
+    }
+
+    /**
+     * Gets the RenderedImage at the specified index from the 
+     * vector of source images.
+     * 
+     * @param index the index
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage getRenderedSource(int index) {
+        return (RenderedImage)sources.elementAt(index);
+    }
+
+    /**
+     * Gets the short-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the short parameter
+     */
+    public short getShortParameter(int index) {
+        return ((Short)parameters.elementAt(index)).shortValue();
+    }
+
+    /**
+     * Gets the long-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the long parameter
+     */
+    public long getLongParameter(int index) {
+        return ((Long)parameters.elementAt(index)).longValue();
+    }
+
+    /**
+     * Gets the int-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the int parameter
+     */
+    public int getIntParameter(int index) {
+        return ((Integer)parameters.elementAt(index)).intValue();
+    }
+
+    /**
+     * Gets the float-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the float parameter
+     */
+    public float getFloatParameter(int index) {
+        return ((Float)parameters.elementAt(index)).floatValue();
+    }
+
+    /**
+     * Gets the double-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the double parameter
+     */
+    public double getDoubleParameter(int index) {
+        return ((Double)parameters.elementAt(index)).doubleValue();
+    }
+
+    /**
+     * Gets the char-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the char parameter
+     */
+    public char getCharParameter(int index) {
+        return ((Character)parameters.elementAt(index)).charValue();
+    }
+
+    /**
+     * Gets the byte-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the byte parameter
+     */
+    public byte getByteParameter(int index) {
+        return ((Byte)parameters.elementAt(index)).byteValue();
+    }
+
+    /**
+     * Clears the vector of sources.
+     */
+    public void removeSources() {
+        sources.removeAllElements();
+    }
+
+    /**
+     * Clears the vector of parameters.
+     */
+    public void removeParameters() {
+        parameters.removeAllElements();
+    }
+
+    /**
+     * Gets the number of elements in the vector of sources.
+     * 
+     * @return the number of elements in the vector of sources
+     */
+    public int getNumSources() {
+        return sources.size();
+    }
+
+    /**
+     * Gets the number of elements in the vector of parameters.
+     * 
+     * @return the number of elements in the vector of parameters
+     */
+    public int getNumParameters() {
+        return parameters.size();
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderContext.java b/awt/java/awt/image/renderable/RenderContext.java
new file mode 100644
index 0000000..3a3b93c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderContext.java
@@ -0,0 +1,196 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+/**
+ * The Class RenderContext stores data on how an image is to be 
+ * rendered: the affine transform, the area of interest, and 
+ * the rendering hints.
+ */
+public class RenderContext implements Cloneable {
+
+    /** The affine transform. */
+    AffineTransform transform;
+    
+    /** The area of interest. */
+    Shape aoi;
+    
+    /** The rendering hints. */
+    RenderingHints hints;
+
+    /**
+     * Instantiates a new render context.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi, RenderingHints hints) {
+        this.transform = (AffineTransform)usr2dev.clone();
+        this.aoi = aoi;
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new render context with no specified hints.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi) {
+        this(usr2dev, aoi, null);
+    }
+
+    /**
+     * Instantiates a new render context with no specified area of interest.
+     * 
+     * @param usr2dev the affine transform
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
+        this(usr2dev, null, hints);
+    }
+
+    /**
+     * Instantiates a new render context with no rendering hints or 
+     * area of interest.
+     * 
+     * @param usr2dev the affine transform
+     */
+    public RenderContext(AffineTransform usr2dev) {
+        this(usr2dev, null, null);
+    }
+
+    @Override
+    public Object clone() {
+        return new RenderContext(transform, aoi, hints);
+    }
+
+    /**
+     * Sets the affine transform for this render context.
+     * 
+     * @param newTransform the new affine transform
+     */
+    public void setTransform(AffineTransform newTransform) {
+        transform = (AffineTransform)newTransform.clone();
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#preConcatenateTransform(AffineTransform)}
+     */
+    @Deprecated    
+    public void preConcetenateTransform(AffineTransform modTransform) {
+        preConcatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void preConcatenateTransform(AffineTransform modTransform) {
+        transform.preConcatenate(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#concatenateTransform(AffineTransform)}
+     */
+    @Deprecated
+    public void concetenateTransform(AffineTransform modTransform) {
+        concatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void concatenateTransform(AffineTransform modTransform) {
+        transform.concatenate(modTransform);
+    }
+
+    /**
+     * Gets the transform.
+     * 
+     * @return the transform
+     */
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    /**
+     * Sets the area of interest.
+     * 
+     * @param newAoi the new area of interest
+     */
+    public void setAreaOfInterest(Shape newAoi) {
+        aoi = newAoi;
+    }
+
+    /**
+     * Gets the area of interest.
+     * 
+     * @return the area of interest
+     */
+    public Shape getAreaOfInterest() {
+        return aoi;
+    }
+
+    /**
+     * Sets the rendering hints.
+     * 
+     * @param hints the new rendering hints
+     */
+    public void setRenderingHints(RenderingHints hints) {
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the rendering hints.
+     * 
+     * @return the rendering hints
+     */
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderableImage.java b/awt/java/awt/image/renderable/RenderableImage.java
new file mode 100644
index 0000000..885dc06
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImage.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Interface RenderableImage is implemented by an object that
+ * collects all of the image-specific data that defines a single image 
+ * that could be rendered to different rendering targets.
+ */
+public interface RenderableImage {
+
+    /** The Constant HINTS_OBSERVED indicates that the rendering
+     * hints are applied rather than ignored. */
+    public static final String HINTS_OBSERVED = "HINTS_OBSERVED"; //$NON-NLS-1$
+
+    /**
+     * Gets the property from the RenderableImage's parameter block.
+     * 
+     * @param name the name of the property to get.
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Creates the rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param renderContext the render context giving rendering specifications
+     * such as transformations
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createRendering(RenderContext renderContext);
+
+    /**
+     * Creates the scaled rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param w the desired width after scaling or zero if the scaling 
+     * should be proportional, based on the height
+     * @param h the desired height after scaling or zero if the scaling 
+     * should be proportional, based on the width
+     * @param hints the rendering hints to use
+     * 
+     * @return the rendered image
+     * 
+     * @throws IllegalArgumentException if both the height and width are zero
+     */
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+
+    /**
+     * Gets the vector of sources from the parameter block.
+     * 
+     * @return the sources
+     */
+    public Vector<RenderableImage> getSources();
+
+    /**
+     * Gets the names of all of the supported properties in the current context.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Creates the default rendering (using the identity transform
+     * and default render context).
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createDefaultRendering();
+
+    /**
+     * Checks if this context supports dynamic rendering.
+     * 
+     * @return true, if this context supports dynamic rendering
+     */
+    public boolean isDynamic();
+
+    /**
+     * Gets the width of the image.
+     * 
+     * @return the width of the image
+     */
+    public float getWidth();
+
+    /**
+     * Gets the y coordinate of the upper left corner.
+     * 
+     * @return the y coordinate of the upper left corner
+     */
+    public float getMinY();
+
+    /**
+     * Gets the x coordinate of the upper left corner.
+     * 
+     * @return the x coordinate of the upper left corner
+     */
+    public float getMinX();
+
+    /**
+     * Gets the height of the image.
+     * 
+     * @return the height of the image
+     */
+    public float getHeight();
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageOp.java b/awt/java/awt/image/renderable/RenderableImageOp.java
new file mode 100644
index 0000000..993ba5f
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageOp.java
@@ -0,0 +1,182 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RenderableImageOp is a basic implementation of RenderableImage, 
+ * with methods to access the parameter data and perform rendering
+ * operations.
+ */
+public class RenderableImageOp implements RenderableImage {
+
+    /** The CRIF. */
+    ContextualRenderedImageFactory CRIF;
+    
+    /** The param block. */
+    ParameterBlock paramBlock;
+    
+    /** The height. */
+    float minX, minY, width, height;
+
+    /**
+     * Instantiates a new renderable image op.
+     * 
+     * @param CRIF the cRIF
+     * @param paramBlock the param block
+     */
+    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
+        this.CRIF = CRIF;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        Rectangle2D r = CRIF.getBounds2D(paramBlock);
+        minX = (float) r.getMinX();
+        minY = (float) r.getMinY();
+        width = (float) r.getWidth();
+        height = (float) r.getHeight();
+    }
+
+    public Object getProperty(String name) {
+        return CRIF.getProperty(paramBlock, name);
+    }
+
+    /**
+     * Sets the parameter block.
+     * 
+     * @param paramBlock the param block
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
+        ParameterBlock oldParam = this.paramBlock;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        return oldParam;
+    }
+
+    public RenderedImage createRendering(RenderContext renderContext) {
+
+        Vector<RenderableImage> sources = getSources();
+        ParameterBlock rdParam = (ParameterBlock) paramBlock.clone();
+
+        if (sources != null) {
+            Vector<Object> rdSources = new Vector<Object>();
+            int i = 0;
+            while (i < sources.size()) {
+                RenderContext newContext = CRIF.mapRenderContext(i, renderContext, paramBlock,
+                        this);
+                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
+
+                if (rdim != null) {
+                    rdSources.addElement(rdim);
+                }
+                i++;
+            }
+            if (rdSources.size() > 0) {
+                rdParam.setSources(rdSources);
+            }
+        }
+        return CRIF.create(renderContext, rdParam);
+    }
+
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
+        if(w == 0 && h == 0) {
+            // awt.60=Width and Height mustn't be equal zero both
+            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
+        }
+        if(w == 0){
+            w = Math.round(h*(getWidth()/getHeight()));
+        }
+
+        if(h == 0){
+            h = Math.round(w*(getHeight()/getWidth()));
+        }
+
+        double sx = (double)w/getWidth();
+        double sy = (double)h/getHeight();
+
+        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
+        RenderContext context = new RenderContext(at, hints);
+        return createRendering(context);
+    }
+
+    public Vector<RenderableImage> getSources() {
+        if(paramBlock.getNumSources() == 0) {
+            return null;
+        }
+        Vector<RenderableImage> v = new Vector<RenderableImage>();
+        int  i = 0;
+        while(i < paramBlock.getNumSources()){
+            Object o = paramBlock.getSource(i);
+            if(o instanceof RenderableImage){
+                v.addElement((RenderableImage) o);
+            }
+            i++;
+        }
+        return v;
+    }
+
+    public String[] getPropertyNames() {
+        return CRIF.getPropertyNames();
+    }
+
+    /**
+     * Gets the parameter block.
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock getParameterBlock() {
+        return paramBlock;
+    }
+
+    public RenderedImage createDefaultRendering() {
+        AffineTransform at = new AffineTransform();
+        RenderContext context = new RenderContext(at);
+        return createRendering(context);
+    }
+
+    public boolean isDynamic() {
+        return CRIF.isDynamic();
+    }
+
+    public float getWidth() {
+        return width;
+    }
+
+    public float getMinY() {
+        return minY;
+    }
+
+    public float getMinX() {
+        return minX;
+    }
+
+    public float getHeight() {
+        return height;
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageProducer.java b/awt/java/awt/image/renderable/RenderableImageProducer.java
new file mode 100644
index 0000000..7fda98c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageProducer.java
@@ -0,0 +1,141 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Class RenderableImageProducer provides the implementation for 
+ * the image rendering.
+ */
+public class RenderableImageProducer implements ImageProducer, Runnable {
+
+    /** The rbl. */
+    RenderableImage rbl;
+    
+    /** The rc. */
+    RenderContext rc;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers = new Vector<ImageConsumer>();
+
+    /**
+     * Instantiates a new renderable image producer.
+     * 
+     * @param rdblImage the rdbl image
+     * @param rc the rc
+     */
+    public RenderableImageProducer(RenderableImage rdblImage, RenderContext rc) {
+        this.rbl = rdblImage;
+        this.rc = rc;
+    }
+
+    /**
+     * Sets the render context.
+     * 
+     * @param rc the new render context
+     */
+    public synchronized void setRenderContext(RenderContext rc) {
+        this.rc = rc;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        Thread t = new Thread(this, "RenderableImageProducer thread"); //$NON-NLS-1$
+        t.start();
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {}
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            consumers.removeElement(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !consumers.contains(ic)){
+            consumers.addElement(ic);
+        }
+    }
+
+    /**
+     * Creates the rendered image in a new thread.
+     */
+    public void run() {
+        if(rbl == null) {
+            return;
+        }
+
+        RenderedImage rd;
+        if(rc != null) {
+            rd = rbl.createRendering(rc);
+        } else {
+            rd = rbl.createDefaultRendering();
+        }
+
+        ColorModel cm = rd.getColorModel();
+        if(cm == null) {
+            cm = ColorModel.getRGBdefault();
+        }
+
+        Raster r = rd.getData();
+        int w = r.getWidth();
+        int h = r.getHeight();
+
+        for (ImageConsumer c : consumers) {
+            c.setDimensions(w, h);
+            c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                    ImageConsumer.COMPLETESCANLINES |
+                    ImageConsumer.SINGLEFRAME |
+                    ImageConsumer.SINGLEPASS);
+        }
+
+        int scanLine[] = new int[w];
+        int pixel[] = null;
+
+        for(int y = 0; y < h; y++){
+            for(int x = 0; x < w; x++){
+                pixel = r.getPixel(x, y, pixel);
+                scanLine[x] = cm.getDataElement(pixel, 0);
+            }
+
+            for (ImageConsumer c : consumers) {
+                c.setPixels(0, y, w, 1, cm, scanLine, 0, w);
+            }
+        }
+
+        for (ImageConsumer c : consumers) {
+            c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderedImageFactory.java b/awt/java/awt/image/renderable/RenderedImageFactory.java
new file mode 100644
index 0000000..345d82c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderedImageFactory.java
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating RenderedImage objects based on parameters
+ * and rendering hints.
+ */
+public interface RenderedImageFactory {
+
+    /**
+     * Creates the rendered image.
+     * 
+     * @param a0 the ParameterBlock
+     * @param a1 the RenderingHints
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(ParameterBlock a0, RenderingHints a1);
+
+}
+
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
new file mode 100644
index 0000000..cc45b49
--- /dev/null
+++ b/awt/java/awt/peer/ButtonPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ButtonPeer {
+
+}
diff --git a/awt/java/awt/peer/CanvasPeer.java b/awt/java/awt/peer/CanvasPeer.java
new file mode 100644
index 0000000..e276366
--- /dev/null
+++ b/awt/java/awt/peer/CanvasPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CanvasPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxMenuItemPeer.java b/awt/java/awt/peer/CheckboxMenuItemPeer.java
new file mode 100644
index 0000000..296f422
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxMenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxMenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxPeer.java b/awt/java/awt/peer/CheckboxPeer.java
new file mode 100644
index 0000000..e9f8dd1
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxPeer {
+
+}
diff --git a/awt/java/awt/peer/ChoicePeer.java b/awt/java/awt/peer/ChoicePeer.java
new file mode 100644
index 0000000..57b7629
--- /dev/null
+++ b/awt/java/awt/peer/ChoicePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ChoicePeer {
+
+}
diff --git a/awt/java/awt/peer/ComponentPeer.java b/awt/java/awt/peer/ComponentPeer.java
new file mode 100644
index 0000000..bc26791
--- /dev/null
+++ b/awt/java/awt/peer/ComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/DialogPeer.java b/awt/java/awt/peer/DialogPeer.java
new file mode 100644
index 0000000..8ae3049
--- /dev/null
+++ b/awt/java/awt/peer/DialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface DialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FileDialogPeer.java b/awt/java/awt/peer/FileDialogPeer.java
new file mode 100644
index 0000000..0d15e48
--- /dev/null
+++ b/awt/java/awt/peer/FileDialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FileDialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FontPeer.java b/awt/java/awt/peer/FontPeer.java
new file mode 100644
index 0000000..fd9815f
--- /dev/null
+++ b/awt/java/awt/peer/FontPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FontPeer {
+
+}
diff --git a/awt/java/awt/peer/FramePeer.java b/awt/java/awt/peer/FramePeer.java
new file mode 100644
index 0000000..9cfc40b
--- /dev/null
+++ b/awt/java/awt/peer/FramePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FramePeer {
+
+}
diff --git a/awt/java/awt/peer/LabelPeer.java b/awt/java/awt/peer/LabelPeer.java
new file mode 100644
index 0000000..052ca9d
--- /dev/null
+++ b/awt/java/awt/peer/LabelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LabelPeer {
+
+}
diff --git a/awt/java/awt/peer/LightweightPeer.java b/awt/java/awt/peer/LightweightPeer.java
new file mode 100644
index 0000000..1dee905
--- /dev/null
+++ b/awt/java/awt/peer/LightweightPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LightweightPeer {
+
+}
diff --git a/awt/java/awt/peer/ListPeer.java b/awt/java/awt/peer/ListPeer.java
new file mode 100644
index 0000000..0a27885
--- /dev/null
+++ b/awt/java/awt/peer/ListPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ListPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuBarPeer.java b/awt/java/awt/peer/MenuBarPeer.java
new file mode 100644
index 0000000..3ad2c16
--- /dev/null
+++ b/awt/java/awt/peer/MenuBarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuBarPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuComponentPeer.java b/awt/java/awt/peer/MenuComponentPeer.java
new file mode 100644
index 0000000..3ac3b34
--- /dev/null
+++ b/awt/java/awt/peer/MenuComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuItemPeer.java b/awt/java/awt/peer/MenuItemPeer.java
new file mode 100644
index 0000000..b133897
--- /dev/null
+++ b/awt/java/awt/peer/MenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuPeer.java b/awt/java/awt/peer/MenuPeer.java
new file mode 100644
index 0000000..d643ce7
--- /dev/null
+++ b/awt/java/awt/peer/MenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuPeer {
+
+}
diff --git a/awt/java/awt/peer/MouseInfoPeer.java b/awt/java/awt/peer/MouseInfoPeer.java
new file mode 100644
index 0000000..9173a62
--- /dev/null
+++ b/awt/java/awt/peer/MouseInfoPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MouseInfoPeer {
+
+}
diff --git a/awt/java/awt/peer/PanelPeer.java b/awt/java/awt/peer/PanelPeer.java
new file mode 100644
index 0000000..1faa1fe
--- /dev/null
+++ b/awt/java/awt/peer/PanelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PanelPeer {
+
+}
diff --git a/awt/java/awt/peer/PopupMenuPeer.java b/awt/java/awt/peer/PopupMenuPeer.java
new file mode 100644
index 0000000..cf1ef61
--- /dev/null
+++ b/awt/java/awt/peer/PopupMenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PopupMenuPeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollPanePeer.java b/awt/java/awt/peer/ScrollPanePeer.java
new file mode 100644
index 0000000..df3de83
--- /dev/null
+++ b/awt/java/awt/peer/ScrollPanePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollPanePeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollbarPeer.java b/awt/java/awt/peer/ScrollbarPeer.java
new file mode 100644
index 0000000..eec8961
--- /dev/null
+++ b/awt/java/awt/peer/ScrollbarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollbarPeer {
+
+}
diff --git a/awt/java/awt/peer/TextAreaPeer.java b/awt/java/awt/peer/TextAreaPeer.java
new file mode 100644
index 0000000..636707f
--- /dev/null
+++ b/awt/java/awt/peer/TextAreaPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextAreaPeer {
+
+}
diff --git a/awt/java/awt/peer/TextFieldPeer.java b/awt/java/awt/peer/TextFieldPeer.java
new file mode 100644
index 0000000..2b8232a
--- /dev/null
+++ b/awt/java/awt/peer/TextFieldPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextFieldPeer {
+
+}
diff --git a/awt/java/awt/peer/WindowPeer.java b/awt/java/awt/peer/WindowPeer.java
new file mode 100644
index 0000000..384646f
--- /dev/null
+++ b/awt/java/awt/peer/WindowPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface WindowPeer {
+
+}
diff --git a/awt/java/beans/FeatureDescriptor.java b/awt/java/beans/FeatureDescriptor.java
new file mode 100644
index 0000000..2945c65
--- /dev/null
+++ b/awt/java/beans/FeatureDescriptor.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package java.beans;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * Common base class for Descriptors.
+ */
+public class FeatureDescriptor {
+
+    private Map<String, Object> values;
+
+    boolean preferred, hidden, expert;
+
+    String shortDescription;
+
+    String name;
+
+    String displayName;
+
+    /**
+     * <p>
+     * Constructs an instance.
+     * </p>
+     */
+    public FeatureDescriptor() {
+        this.values = new HashMap<String, Object>();
+    }
+
+    /**
+     * <p>
+     * Sets the value for the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to set a value with.
+     * @param value
+     *            The value to set.
+     */
+    public void setValue(String attributeName, Object value) {
+        if (attributeName == null || value == null) {
+            throw new NullPointerException();
+        }
+        values.put(attributeName, value);
+    }
+
+    /**
+     * <p>
+     * Gets the value associated with the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to get a value for.
+     * @return The attribute's value.
+     */
+    public Object getValue(String attributeName) {
+        Object result = null;
+        if (attributeName != null) {
+            result = values.get(attributeName);
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * Enumerates the attribute names.
+     * </p>
+     * 
+     * @return An instance of {@link Enumeration}.
+     */
+    public Enumeration<String> attributeNames() {
+        // Create a new list, so that the references are copied
+        return Collections.enumeration(new LinkedList<String>(values.keySet()));
+    }
+
+    /**
+     * <p>
+     * Sets the short description.
+     * </p>
+     * 
+     * @param text
+     *            The description to set.
+     */
+    public void setShortDescription(String text) {
+        this.shortDescription = text;
+    }
+
+    /**
+     * <p>
+     * Sets the name.
+     * </p>
+     * 
+     * @param name
+     *            The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * <p>
+     * Sets the display name.
+     * </p>
+     * 
+     * @param displayName
+     *            The display name to set.
+     */
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    /**
+     * <p>
+     * Gets the short description or {@link #getDisplayName()} if not set.
+     * </p>
+     * 
+     * @return The description.
+     */
+    public String getShortDescription() {
+        return shortDescription == null ? getDisplayName() : shortDescription;
+    }
+
+    /**
+     * <p>
+     * Gets the name.
+     * </p>
+     * 
+     * @return The name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * <p>
+     * Gets the display name or {@link #getName()} if not set.
+     * </p>
+     * 
+     * @return The display name.
+     */
+    public String getDisplayName() {
+        return displayName == null ? getName() : displayName;
+    }
+
+    /**
+     * <p>
+     * Sets the preferred indicator.
+     * </p>
+     * 
+     * @param preferred
+     *            <code>true</code> if preferred, <code>false</code>
+     *            otherwise.
+     */
+    public void setPreferred(boolean preferred) {
+        this.preferred = preferred;
+    }
+
+    /**
+     * <p>
+     * Sets the hidden indicator.
+     * </p>
+     * 
+     * @param hidden
+     *            <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public void setHidden(boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    /**
+     * <p>
+     * Sets the expert indicator.
+     * </p>
+     * 
+     * @param expert
+     *            <code>true</code> if expert, <code>false</code> otherwise.
+     */
+    public void setExpert(boolean expert) {
+        this.expert = expert;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is preferred.
+     * </p>
+     * 
+     * @return <code>true</code> if preferred, <code>false</code> otherwise.
+     */
+    public boolean isPreferred() {
+        return preferred;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is hidden.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isHidden() {
+        return hidden;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is an expert feature.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isExpert() {
+        return expert;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyChangeEvent.java b/awt/java/beans/IndexedPropertyChangeEvent.java
new file mode 100644
index 0000000..c9084c6
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyChangeEvent.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package java.beans;
+
+/**
+ * A type of {@link PropertyChangeEvent} that indicates that an indexed property
+ * has changed.
+ * 
+ * @since 1.5
+ */
+public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
+
+    private static final long serialVersionUID = -320227448495806870L;
+
+    private final int index;
+
+    /**
+     * Creates a new property changed event with an indication of the property
+     * index.
+     * 
+     * @param source
+     *            the changed bean.
+     * @param propertyName
+     *            the changed property, or <code>null</code> to indicate an
+     *            unspecified set of the properties have changed.
+     * @param oldValue
+     *            the previous value of the property, or <code>null</code> if
+     *            the <code>propertyName</code> is <code>null</code> or the
+     *            previous value is unknown.
+     * @param newValue
+     *            the new value of the property, or <code>null</code> if the
+     *            <code>propertyName</code> is <code>null</code> or the new
+     *            value is unknown..
+     * @param index
+     *            the index of the property.
+     */
+    public IndexedPropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue, int index) {
+        super(source, propertyName, oldValue, newValue);
+        this.index = index;
+    }
+
+    /**
+     * Answer the index of the property that was changed in this event.
+     * 
+     * @return The property element index.
+     */
+    public int getIndex() {
+        return index;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyDescriptor.java b/awt/java/beans/IndexedPropertyDescriptor.java
new file mode 100644
index 0000000..25667d9
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyDescriptor.java
@@ -0,0 +1,227 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class IndexedPropertyDescriptor extends PropertyDescriptor {
+    private Method indexedGetter;
+
+    private Method indexedSetter;
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
+            String getterName, String setterName, String indexedGetterName,
+            String indexedSetterName) throws IntrospectionException {
+        super(propertyName, beanClass, getterName, setterName);
+
+        // RI behaves like this
+        if (indexedGetterName == null && indexedSetterName == null &&
+                (getterName != null || setterName != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(beanClass, indexedGetterName);
+        setIndexedWriteMethod(beanClass, indexedSetterName);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter,
+            Method indexedGetter, Method indexedSetter) throws IntrospectionException {
+        super(propertyName, getter, setter);
+        
+        // we need this in order to be compatible with RI
+        if (indexedGetter == null && indexedSetter == null &&
+                (getter != null || setter != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(indexedGetter);
+        setIndexedWriteMethod(indexedSetter);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        super(propertyName, beanClass, null, null);
+        String getterName;
+        String setterName;
+        String indexedGetterName;
+        String indexedSetterName;
+
+        // array getter
+        getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        }
+        // array setter
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        // indexed getter
+        indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedGetterName)) {
+            setIndexedReadMethod(beanClass, indexedGetterName);
+        }
+        // indexed setter
+        indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedSetterName)) {
+            setIndexedWriteMethod(beanClass, indexedSetterName);
+        }
+        // RI seems to behave a bit differently
+        if (indexedGetter == null && indexedSetter == null &&
+                getReadMethod() == null && getWriteMethod() == null) {
+            throw new IntrospectionException(
+                    Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+        if (indexedGetter == null && indexedSetter == null) {
+            // not an indexed property indeed
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+    }
+
+    public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException {
+        if (indexedGetter != null) {
+            int modifiers = indexedGetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> returnType;
+            Class<?> indexedPropertyType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedGetter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$
+            }
+            if (!parameterTypes[0].equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$
+            }
+            returnType = indexedGetter.getReturnType();
+            indexedPropertyType = getIndexedPropertyType();
+            if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$
+            }
+        }
+        this.indexedGetter = indexedGetter;
+    }
+
+    public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException {
+        if (indexedSetter != null) {
+            int modifiers = indexedSetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> firstParameterType;
+            Class<?> secondParameterType;
+            Class<?> propType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedSetter.getParameterTypes();
+            if (parameterTypes.length != 2) {
+                throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$
+            }
+            firstParameterType = parameterTypes[0];
+            if (!firstParameterType.equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$
+            }
+            secondParameterType = parameterTypes[1];
+            propType = getIndexedPropertyType();
+            if (propType != null && !secondParameterType.equals(propType)) {
+                throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$
+            }
+        }
+        this.indexedSetter = indexedSetter;
+    }
+
+    public Method getIndexedWriteMethod() {
+        return indexedSetter;
+    }
+
+    public Method getIndexedReadMethod() {
+        return indexedGetter;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        boolean result = super.equals(obj);
+        
+        if (result) {
+            IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj;
+    
+            if (indexedGetter != null) {
+                result = indexedGetter.equals(pd.getIndexedReadMethod());
+            } else if (result && indexedGetter == null) {
+                result = pd.getIndexedReadMethod() == null;
+            }
+                
+            if (result) {
+                if (indexedSetter != null) {
+                    result = indexedSetter.equals(pd.getIndexedWriteMethod());
+                } else if (indexedSetter == null) {
+                    result = pd.getIndexedWriteMethod() == null;
+                }
+            }
+        }
+            
+        return result;
+    }
+
+    public Class<?> getIndexedPropertyType() {
+        Class<?> result = null;
+
+        if (indexedGetter != null) {
+            result = indexedGetter.getReturnType();
+        } else if (indexedSetter != null) {
+            Class<?>[] parameterTypes = indexedSetter.getParameterTypes();
+
+            result = parameterTypes[1];
+        }
+        return result;
+    }
+
+    private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) {
+        Method[] getters = findMethods(beanClass, indexedGetterName);
+        boolean result = false;
+
+        for (Method element : getters) {
+            try {
+                setIndexedReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) {
+        Method[] setters = findMethods(beanClass, indexedSetterName);
+        boolean result = false;
+
+        for (Method element : setters) {
+            try {
+                setIndexedWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/IntrospectionException.java b/awt/java/beans/IntrospectionException.java
new file mode 100644
index 0000000..c895afe
--- /dev/null
+++ b/awt/java/beans/IntrospectionException.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+public class IntrospectionException extends Exception {
+
+    static final long serialVersionUID = -3728150539969542619L;
+
+    public IntrospectionException(String message) {
+        super(message);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeEvent.java b/awt/java/beans/PropertyChangeEvent.java
new file mode 100644
index 0000000..97c703a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeEvent.java
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventObject;
+
+public class PropertyChangeEvent extends EventObject {
+
+    private static final long serialVersionUID = 7042693688939648123L;
+
+    String propertyName;
+
+    Object oldValue;
+
+    Object newValue;
+
+    Object propagationId;
+
+    public PropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue) {
+        super(source);
+
+        this.propertyName = propertyName;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropagationId(Object propagationId) {
+        this.propagationId = propagationId;
+    }
+
+    public Object getPropagationId() {
+        return propagationId;
+    }
+
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    public Object getNewValue() {
+        return newValue;
+    }
+}
diff --git a/awt/java/beans/PropertyChangeListener.java b/awt/java/beans/PropertyChangeListener.java
new file mode 100644
index 0000000..94422c0
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListener.java
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventListener;
+
+public interface PropertyChangeListener extends EventListener {
+
+    public void propertyChange(PropertyChangeEvent event);
+}
diff --git a/awt/java/beans/PropertyChangeListenerProxy.java b/awt/java/beans/PropertyChangeListenerProxy.java
new file mode 100644
index 0000000..f4f3aec
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListenerProxy.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.EventListenerProxy;
+
+public class PropertyChangeListenerProxy extends EventListenerProxy implements
+        PropertyChangeListener {
+
+    String propertyName;
+
+    public PropertyChangeListenerProxy(String propertyName,
+            PropertyChangeListener listener) {
+        super(listener);
+        this.propertyName = propertyName;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void propertyChange(PropertyChangeEvent event) {
+        PropertyChangeListener listener = (PropertyChangeListener) getListener();
+        listener.propertyChange(event);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeSupport.java b/awt/java/beans/PropertyChangeSupport.java
new file mode 100644
index 0000000..d56e63a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeSupport.java
@@ -0,0 +1,351 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class PropertyChangeSupport implements Serializable {
+
+    private static final long serialVersionUID = 6401253773779951803l;
+
+    private transient Object sourceBean;
+
+    private transient List<PropertyChangeListener> allPropertiesChangeListeners =
+            new ArrayList<PropertyChangeListener>();
+
+    private transient Map<String, List<PropertyChangeListener>>
+            selectedPropertiesChangeListeners =
+            new HashMap<String, List<PropertyChangeListener>>();
+
+    // fields for serialization compatibility
+    private Hashtable<String, List<PropertyChangeListener>> children;
+
+    private Object source;
+
+    private int propertyChangeSupportSerializedDataVersion = 1;
+
+    public PropertyChangeSupport(Object sourceBean) {
+        if (sourceBean == null) {
+            throw new NullPointerException();
+        }
+        this.sourceBean = sourceBean;
+    }
+
+    public void firePropertyChange(String propertyName, Object oldValue,
+            Object newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            Object oldValue, Object newValue) {
+
+        // nulls and equals check done in doFire...
+        doFirePropertyChange(new IndexedPropertyChangeEvent(sourceBean,
+                propertyName, oldValue, newValue, index));
+    }
+
+    public synchronized void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((propertyName != null) && (listener != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners != null) {
+                listeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((listener != null) && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners == null) {
+                listeners = new ArrayList<PropertyChangeListener>();
+                selectedPropertiesChangeListeners.put(propertyName, listeners);
+            }
+
+            // RI compatibility
+            if (listener instanceof PropertyChangeListenerProxy) {
+                PropertyChangeListenerProxy proxy =
+                        (PropertyChangeListenerProxy) listener;
+
+                listeners.add(new PropertyChangeListenerProxy(
+                        proxy.getPropertyName(),
+                        (PropertyChangeListener) proxy.getListener()));
+            } else {
+                listeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+            String propertyName) {
+        List<PropertyChangeListener> listeners = null;
+
+        if (propertyName != null) {
+            listeners = selectedPropertiesChangeListeners.get(propertyName);
+        }
+
+        return (listeners == null) ? new PropertyChangeListener[] {}
+                : listeners.toArray(
+                        new PropertyChangeListener[listeners.size()]);
+    }
+
+    public void firePropertyChange(String propertyName, boolean oldValue,
+            boolean newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            boolean oldValue, boolean newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index, Boolean
+                    .valueOf(oldValue), Boolean.valueOf(newValue));
+        }
+    }
+
+    public void firePropertyChange(String propertyName, int oldValue,
+            int newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            int oldValue, int newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index,
+                    new Integer(oldValue), new Integer(newValue));
+        }
+    }
+
+    public synchronized boolean hasListeners(String propertyName) {
+        boolean result = allPropertiesChangeListeners.size() > 0;
+        if (!result && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+            if (listeners != null) {
+                result = listeners.size() > 0;
+            }
+        }
+        return result;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+
+                removePropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+                addPropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+        ArrayList<PropertyChangeListener> result =
+                new ArrayList<PropertyChangeListener>(
+                        allPropertiesChangeListeners);
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> selectedListeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (selectedListeners != null) {
+
+                for (PropertyChangeListener listener : selectedListeners) {
+                    result.add(new PropertyChangeListenerProxy(propertyName,
+                            listener));
+                }
+            }
+        }
+
+        return result.toArray(new PropertyChangeListener[result.size()]);
+    }
+
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        List<PropertyChangeListener> allSerializedPropertiesChangeListeners =
+                new ArrayList<PropertyChangeListener>();
+
+        for (PropertyChangeListener pcl : allPropertiesChangeListeners) {
+            if (pcl instanceof Serializable) {
+                allSerializedPropertiesChangeListeners.add(pcl);
+            }
+        }
+
+        Map<String, List<PropertyChangeListener>>
+                selectedSerializedPropertiesChangeListeners =
+                        new HashMap<String, List<PropertyChangeListener>>();
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> keyValues =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (keyValues != null) {
+                List<PropertyChangeListener> serializedPropertiesChangeListeners
+                        = new ArrayList<PropertyChangeListener>();
+
+                for (PropertyChangeListener pcl : keyValues) {
+                    if (pcl instanceof Serializable) {
+                        serializedPropertiesChangeListeners.add(pcl);
+                    }
+                }
+
+                if (!serializedPropertiesChangeListeners.isEmpty()) {
+                    selectedSerializedPropertiesChangeListeners.put(
+                            propertyName, serializedPropertiesChangeListeners);
+                }
+            }
+        }
+
+        children = new Hashtable<String, List<PropertyChangeListener>>(
+                selectedSerializedPropertiesChangeListeners);
+        children.put("", allSerializedPropertiesChangeListeners); //$NON-NLS-1$
+        oos.writeObject(children);
+
+        Object source = null;
+        if (sourceBean instanceof Serializable) {
+            source = sourceBean;
+        }
+        oos.writeObject(source);
+
+        oos.writeInt(propertyChangeSupportSerializedDataVersion);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream ois) throws IOException,
+            ClassNotFoundException {
+        children = (Hashtable<String, List<PropertyChangeListener>>) ois
+                .readObject();
+
+        selectedPropertiesChangeListeners = new HashMap<String, List<PropertyChangeListener>>(
+                children);
+        allPropertiesChangeListeners = selectedPropertiesChangeListeners
+                .remove(""); //$NON-NLS-1$
+        if (allPropertiesChangeListeners == null) {
+            allPropertiesChangeListeners = new ArrayList<PropertyChangeListener>();
+        }
+
+        sourceBean = ois.readObject();
+        propertyChangeSupportSerializedDataVersion = ois.readInt();
+    }
+
+    public void firePropertyChange(PropertyChangeEvent event) {
+        doFirePropertyChange(event);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            Object oldValue, Object newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            boolean oldValue, boolean newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            int oldValue, int newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private void doFirePropertyChange(PropertyChangeEvent event) {
+        String propertyName = event.getPropertyName();
+        Object oldValue = event.getOldValue();
+        Object newValue = event.getNewValue();
+
+        if ((newValue != null) && (oldValue != null)
+                && newValue.equals(oldValue)) {
+            return;
+        }
+
+        /*
+         * Copy the listeners collections so they can be modified while we fire
+         * events.
+         */
+
+        // Listeners to all property change events
+        PropertyChangeListener[] listensToAll;
+        // Listens to a given property change
+        PropertyChangeListener[] listensToOne = null;
+        synchronized (this) {
+            listensToAll = allPropertiesChangeListeners
+                    .toArray(new PropertyChangeListener[allPropertiesChangeListeners
+                            .size()]);
+
+            List<PropertyChangeListener> listeners = selectedPropertiesChangeListeners
+                    .get(propertyName);
+            if (listeners != null) {
+                listensToOne = listeners
+                        .toArray(new PropertyChangeListener[listeners.size()]);
+            }
+        }
+
+        // Fire the listeners
+        for (PropertyChangeListener listener : listensToAll) {
+            listener.propertyChange(event);
+        }
+        if (listensToOne != null) {
+            for (PropertyChangeListener listener : listensToOne) {
+                listener.propertyChange(event);
+            }
+        }
+    }
+
+}
diff --git a/awt/java/beans/PropertyDescriptor.java b/awt/java/beans/PropertyDescriptor.java
new file mode 100644
index 0000000..9389152
--- /dev/null
+++ b/awt/java/beans/PropertyDescriptor.java
@@ -0,0 +1,300 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Vector;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyDescriptor extends FeatureDescriptor {
+    private Method getter;
+
+    private Method setter;
+
+    private Class<?> propertyEditorClass;
+
+    private boolean constrained;
+
+    private boolean bound;
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
+            String setterName) throws IntrospectionException {
+        super();
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        if (setterName != null) {
+            if (hasMethod(beanClass, setterName)) {
+                setWriteMethod(beanClass, setterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$
+            }
+        }
+        if (getterName != null) {
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    public PropertyDescriptor(String propertyName, Method getter, Method setter)
+            throws IntrospectionException {
+        super();
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        setWriteMethod(setter);
+        setReadMethod(getter);
+    }
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        String getterName;
+        String setterName;
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        } else {
+            getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            }
+        }
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        if (getter == null && setter == null) {
+            throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+    }
+
+    public void setWriteMethod(Method setter) throws IntrospectionException {
+        if (setter != null) {
+            int modifiers = setter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$
+            }
+            Class<?> parameterType = parameterTypes[0];
+            Class<?> propertyType = getPropertyType();
+            if (propertyType != null && !propertyType.equals(parameterType)) {
+                throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$
+            }
+        }
+        this.setter = setter;
+    }
+
+    public void setReadMethod(Method getter) throws IntrospectionException {
+        if (getter != null) {
+            int modifiers = getter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = getter.getParameterTypes();
+            if (parameterTypes.length != 0) {
+                throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$
+            }
+            Class<?> returnType = getter.getReturnType();
+            if (returnType.equals(Void.TYPE)) {
+                throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$
+            }
+            Class<?> propertyType = getPropertyType();
+            if ((propertyType != null) && !returnType.equals(propertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$
+            }
+        }
+        this.getter = getter;
+    }
+
+    public Method getWriteMethod() {
+        return setter;
+    }
+
+    public Method getReadMethod() {
+        return getter;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        boolean result = (object != null && object instanceof PropertyDescriptor);
+        if (result) {
+            PropertyDescriptor pd = (PropertyDescriptor) object;
+            boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null)
+                    || (this.getter != null) && (this.getter.equals(pd.getReadMethod()));
+            boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null)
+                    || (this.setter != null) && (this.setter.equals(pd.getWriteMethod()));
+            boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType();
+            boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd
+                    .getPropertyEditorClass();
+            boolean boundPropertyAreEqual = this.isBound() == pd.isBound();
+            boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained();
+            result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual
+                    && propertyEditorClassesAreEqual && boundPropertyAreEqual
+                    && constrainedPropertyAreEqual;
+        }
+        return result;
+    }
+
+    public void setPropertyEditorClass(Class<?> propertyEditorClass) {
+        this.propertyEditorClass = propertyEditorClass;
+    }
+
+    public Class<?> getPropertyType() {
+        Class<?> result = null;
+        if (getter != null) {
+            result = getter.getReturnType();
+        } else if (setter != null) {
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            result = parameterTypes[0];
+        }
+        return result;
+    }
+
+    public Class<?> getPropertyEditorClass() {
+        return propertyEditorClass;
+    }
+
+    public void setConstrained(boolean constrained) {
+        this.constrained = constrained;
+    }
+
+    public void setBound(boolean bound) {
+        this.bound = bound;
+    }
+
+    public boolean isConstrained() {
+        return constrained;
+    }
+
+    public boolean isBound() {
+        return bound;
+    }
+
+    boolean hasMethod(Class<?> beanClass, String methodName) {
+        Method[] methods = findMethods(beanClass, methodName);
+        return (methods.length > 0);
+    }
+
+    String createDefaultMethodName(String propertyName, String prefix) {
+        String result = null;
+        if (propertyName != null) {
+            String bos = propertyName.substring(0, 1).toUpperCase();
+            String eos = propertyName.substring(1, propertyName.length());
+            result = prefix + bos + eos;
+        }
+        return result;
+    }
+
+    Method[] findMethods(Class<?> aClass, String methodName) {
+        Method[] allMethods = aClass.getMethods();
+        Vector<Method> matchedMethods = new Vector<Method>();
+        Method[] result;
+        for (Method method : allMethods) {
+            if (method.getName().equals(methodName)) {
+                matchedMethods.add(method);
+            }
+        }
+        result = new Method[matchedMethods.size()];
+        for (int j = 0; j < matchedMethods.size(); ++j) {
+            result[j] = matchedMethods.elementAt(j);
+        }
+        return result;
+    }
+
+    void setReadMethod(Class<?> beanClass, String getterName) {
+        boolean result = false;
+        Method[] getters = findMethods(beanClass, getterName);
+        for (Method element : getters) {
+            try {
+                setReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException {
+        boolean result = false;
+        Method[] setters = findMethods(beanClass, setterName);
+        for (Method element : setters) {
+            try {
+                setWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    public PropertyEditor createPropertyEditor(Object bean) {
+        PropertyEditor editor;
+        if (propertyEditorClass == null) {
+            return null;
+        }
+        if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) {
+            // beans.48=Property editor is not assignable from the
+            // PropertyEditor interface
+            throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$
+        }
+        try {
+            Constructor<?> constr;
+            try {
+                // try to look for the constructor with single Object argument
+                constr = propertyEditorClass.getConstructor(Object.class);
+                editor = (PropertyEditor) constr.newInstance(bean);
+            } catch (NoSuchMethodException e) {
+                // try no-argument constructor
+                constr = propertyEditorClass.getConstructor();
+                editor = (PropertyEditor) constr.newInstance();
+            }
+        } catch (Exception e) {
+            // beans.47=Unable to instantiate property editor
+            RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$
+            throw re;
+        }
+        return editor;
+    }
+}
diff --git a/awt/java/beans/PropertyEditor.java b/awt/java/beans/PropertyEditor.java
new file mode 100644
index 0000000..65bedea
--- /dev/null
+++ b/awt/java/beans/PropertyEditor.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+public interface PropertyEditor {
+
+    public void paintValue(Graphics gfx, Rectangle box);
+
+    public void setAsText(String text) throws IllegalArgumentException;
+
+    public String[] getTags();
+
+    public String getJavaInitializationString();
+
+    public String getAsText();
+
+    public void setValue(Object value);
+
+    public Object getValue();
+
+    public void removePropertyChangeListener(PropertyChangeListener listener);
+
+    public void addPropertyChangeListener(PropertyChangeListener listener);
+
+    public Component getCustomEditor();
+
+    public boolean supportsCustomEditor();
+
+    public boolean isPaintable();
+}
diff --git a/awt/java/beans/PropertyEditorManager.java b/awt/java/beans/PropertyEditorManager.java
new file mode 100644
index 0000000..ed55829
--- /dev/null
+++ b/awt/java/beans/PropertyEditorManager.java
@@ -0,0 +1,114 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PropertyEditorManager {
+
+    private static String[] path = { "org.apache.harmony.beans.editors" }; //$NON-NLS-1$
+
+    private static final Map<Class<?>, Class<?>> registeredEditors = new HashMap<Class<?>, Class<?>>();
+
+    public PropertyEditorManager() {
+    }
+
+    public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+        if (editorClass != null) {
+            registeredEditors.put(targetType, editorClass);
+        } else {
+            registeredEditors.remove(targetType);
+        }
+    }
+
+    public static synchronized PropertyEditor findEditor(Class<?> targetType) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        Class<?> editorClass = null;
+        PropertyEditor editor = null;
+
+        editorClass = registeredEditors.get(targetType);
+
+        if (editorClass == null) {
+            String editorClassName = targetType.getName() + "Editor"; //$NON-NLS-1$
+            ClassLoader loader = targetType.getClassLoader();
+
+            if (loader == null) {
+                loader = Thread.currentThread().getContextClassLoader();
+            }
+
+            try {
+                editorClass = Class.forName(editorClassName, true, loader);
+            } catch (ClassNotFoundException cnfe) {
+                String shortEditorClassName = editorClassName
+                        .substring(editorClassName.lastIndexOf(".") + 1); //$NON-NLS-1$
+
+                if (targetType.isPrimitive()) {
+                    shortEditorClassName = shortEditorClassName.substring(0, 1)
+                            .toUpperCase()
+                            + shortEditorClassName.substring(1);
+                }
+
+                for (String element : path) {
+                    editorClassName = element + "." + shortEditorClassName; //$NON-NLS-1$
+
+                    try {
+                        editorClass = Class.forName(editorClassName, true,
+                                loader);
+                        break;
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        if (editorClass != null) {
+            try {
+                editor = (PropertyEditor) editorClass.newInstance();
+            } catch (Exception e) {
+            }
+        }
+
+        return editor;
+    }
+
+    public static synchronized void setEditorSearchPath(String[] apath) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+
+        path = apath;
+    }
+
+    public static synchronized String[] getEditorSearchPath() {
+        return path;
+    }
+}
diff --git a/awt/java/beans/PropertyEditorSupport.java b/awt/java/beans/PropertyEditorSupport.java
new file mode 100644
index 0000000..c3929a1
--- /dev/null
+++ b/awt/java/beans/PropertyEditorSupport.java
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyEditorSupport implements PropertyEditor {
+
+    Object source = null;
+
+    List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+    Object oldValue = null;
+
+    Object newValue = null;
+
+    public PropertyEditorSupport(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public PropertyEditorSupport() {
+        source = this;
+    }
+
+    public void paintValue(Graphics gfx, Rectangle box) {
+    }
+
+    public void setAsText(String text) throws IllegalArgumentException {
+        if (newValue instanceof String) {
+            setValue(text);
+        } else {
+            throw new IllegalArgumentException(text);
+        }
+    }
+
+    public String[] getTags() {
+        return null;
+    }
+
+    public String getJavaInitializationString() {
+        return "???"; //$NON-NLS-1$
+    }
+
+    public String getAsText() {
+        return newValue == null ? "null" : newValue.toString(); //$NON-NLS-1$
+    }
+
+    public void setValue(Object value) {
+        this.oldValue = this.newValue;
+        this.newValue = value;
+        firePropertyChange();
+    }
+
+    public Object getValue() {
+        return newValue;
+    }
+
+    public void setSource(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listeners != null) {
+            listeners.remove(listener);
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        listeners.add(listener);
+    }
+
+    public Component getCustomEditor() {
+        return null;
+    }
+
+    public boolean supportsCustomEditor() {
+        return false;
+    }
+
+    public boolean isPaintable() {
+        return false;
+    }
+
+    public void firePropertyChange() {
+        if (listeners.size() > 0) {
+            PropertyChangeEvent event = new PropertyChangeEvent(source, null,
+                    oldValue, newValue);
+            Iterator<PropertyChangeListener> iterator = listeners.iterator();
+
+            while (iterator.hasNext()) {
+                PropertyChangeListener listener = iterator.next();
+                listener.propertyChange(event);
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/PropertyVetoException.java b/awt/java/beans/PropertyVetoException.java
new file mode 100644
index 0000000..c7f092a
--- /dev/null
+++ b/awt/java/beans/PropertyVetoException.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.beans;
+
+/**
+ * Indicates that a proposed property change is unacceptable.
+ */
+public class PropertyVetoException extends Exception {
+
+    private static final long serialVersionUID = 129596057694162164L;
+
+    private final PropertyChangeEvent evt;
+
+    /**
+     * <p>
+     * Constructs an instance with a message and the change event.
+     * </p>
+     * 
+     * @param message
+     *            A description of the veto.
+     * @param event
+     *            The event that was vetoed.
+     */
+    public PropertyVetoException(String message, PropertyChangeEvent event) {
+        super(message);
+        this.evt = event;
+    }
+
+    /**
+     * <p>
+     * Gets the property change event.
+     * </p>
+     * 
+     * @return An instance of {@link PropertyChangeEvent}
+     */
+    public PropertyChangeEvent getPropertyChangeEvent() {
+        return evt;
+    }
+}
