6315717: Support for mouse with multiple scroll wheels and 4 or more buttons
authordav
Tue, 16 Sep 2008 12:17:02 +0400
changeset 1962 6c293d33645b
parent 1961 436a5a828d9f
child 1963 16c7a0981e65
6315717: Support for mouse with multiple scroll wheels and 4 or more buttons Summary: implementation of the more mouse buttons support Reviewed-by: art, dcherepanov
jdk/make/sun/xawt/mapfile-vers
jdk/src/share/classes/java/awt/Robot.java
jdk/src/share/classes/java/awt/Toolkit.java
jdk/src/share/classes/java/awt/doc-files/DesktopProperties.html
jdk/src/share/classes/java/awt/event/InputEvent.java
jdk/src/share/classes/java/awt/event/MouseEvent.java
jdk/src/share/classes/java/awt/peer/RobotPeer.java
jdk/src/share/classes/sun/awt/HeadlessToolkit.java
jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java
jdk/src/solaris/classes/sun/awt/X11/XConstants.java
jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java
jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java
jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
jdk/src/solaris/classes/sun/awt/X11/XWindow.java
jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java
jdk/src/solaris/native/sun/awt/awt_Robot.c
jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java
jdk/src/windows/classes/sun/awt/windows/WToolkit.java
jdk/src/windows/native/sun/windows/awt_Component.cpp
jdk/src/windows/native/sun/windows/awt_Component.h
jdk/src/windows/native/sun/windows/awt_Robot.cpp
jdk/src/windows/native/sun/windows/awt_Robot.h
jdk/src/windows/native/sun/windows/awt_Toolkit.cpp
jdk/src/windows/native/sun/windows/awt_Toolkit.h
jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp
jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java
jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ModifierPermutation.java
jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java
jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java
jdk/test/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java
jdk/test/java/awt/Robot/ManualInstructions/ManualInstructions.java
jdk/test/java/awt/Robot/RobotExtraButton/RobotExtraButton.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_1.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_2.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_3.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_4.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_5.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Disable.java
jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java
jdk/test/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java
jdk/test/java/awt/event/MouseEvent/AcceptExtraButton/AcceptExtraButton.java
jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions.java
jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions_Disable.java
jdk/test/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java
--- a/jdk/make/sun/xawt/mapfile-vers	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/make/sun/xawt/mapfile-vers	Tue Sep 16 12:17:02 2008 +0400
@@ -151,6 +151,7 @@
         Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
         Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
         Java_sun_awt_X11_XRobotPeer_setup;
+        Java_sun_awt_X11_XRobotPeer_getNumberOfButtonsImpl;
         Java_java_awt_Component_initIDs;
         Java_java_awt_Container_initIDs;
         Java_java_awt_Button_initIDs;
--- a/jdk/src/share/classes/java/awt/Robot.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Robot.java	Tue Sep 16 12:17:02 2008 +0400
@@ -70,10 +70,7 @@
     private RobotPeer peer;
     private boolean isAutoWaitForIdle = false;
     private int autoDelay = 0;
-    private static final int LEGAL_BUTTON_MASK =
-                                            InputEvent.BUTTON1_MASK|
-                                            InputEvent.BUTTON2_MASK|
-                                            InputEvent.BUTTON3_MASK;
+    private static int LEGAL_BUTTON_MASK;
 
     // location of robot's GC, used in mouseMove(), getPixelColor() and captureScreenImage()
     private Point gdLoc;
@@ -98,6 +95,19 @@
         }
         init(GraphicsEnvironment.getLocalGraphicsEnvironment()
             .getDefaultScreenDevice());
+        int tmpMask = 0;
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            for (int i = 0; i < peer.getNumberOfButtons(); i++){
+                tmpMask |= InputEvent.getMaskForButton(i+1);
+            }
+        }
+        tmpMask |= InputEvent.BUTTON1_MASK|
+            InputEvent.BUTTON2_MASK|
+            InputEvent.BUTTON3_MASK|
+            InputEvent.BUTTON1_DOWN_MASK|
+            InputEvent.BUTTON2_DOWN_MASK|
+            InputEvent.BUTTON3_DOWN_MASK;
+        LEGAL_BUTTON_MASK = tmpMask;
     }
 
     /**
@@ -187,18 +197,55 @@
 
     /**
      * Presses one or more mouse buttons.  The mouse buttons should
-     * be released using the <code>mouseRelease</code> method.
+     * be released using the {@link #mouseRelease(int)} method.
      *
-     * @param buttons   the Button mask; a combination of one or more
-     * of these flags:
+     * @param buttons the Button mask; a combination of one or more
+     * mouse button masks.
+     * <p>
+     * It is allowed to use only a combination of valid values as a {@code buttons} parameter.
+     * A valid combination consists of {@code InputEvent.BUTTON1_DOWN_MASK},
+     * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK}
+     * and values returned by the
+     * {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)} method.
+     *
+     * The valid combination also depends on a
+     * {@link Toolkit#areExtraMouseButtonsEnabled() Toolkit.areExtraMouseButtonsEnabled()} value as follows:
      * <ul>
-     * <li><code>InputEvent.BUTTON1_MASK</code>
-     * <li><code>InputEvent.BUTTON2_MASK</code>
-     * <li><code>InputEvent.BUTTON3_MASK</code>
+     * <li> If support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * then it is allowed to use only the following standard button masks:
+     * {@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+     * {@code InputEvent.BUTTON3_DOWN_MASK}.
+     * <li> If support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+     * then it is allowed to use the standard button masks
+     * and masks for existing extended mouse buttons, if the mouse has more then three buttons.
+     * In that way, it is allowed to use the button masks corresponding to the buttons
+     * in the range from 1 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+     * <br>
+     * It is recommended to use the {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)}
+     * method to obtain the mask for any mouse button by its number.
      * </ul>
-     * @throws  IllegalArgumentException if the button mask is not a
-     *          valid combination
+     * <p>
+     * The following standard button masks are also accepted:
+     * <ul>
+     * <li>{@code InputEvent.BUTTON1_MASK}
+     * <li>{@code InputEvent.BUTTON2_MASK}
+     * <li>{@code InputEvent.BUTTON3_MASK}
+     * </ul>
+     * However, it is recommended to use {@code InputEvent.BUTTON1_DOWN_MASK},
+     * {@code InputEvent.BUTTON2_DOWN_MASK},  {@code InputEvent.BUTTON3_DOWN_MASK} instead.
+     * Either extended {@code _DOWN_MASK} or old {@code _MASK} values
+     * should be used, but both those models should not be mixed.
+     * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+     *         and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+     *         that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
      * @see #mouseRelease(int)
+     * @see InputEvent#getMaskForButton(int)
+     * @see Toolkit#areExtraMouseButtonsEnabled()
+     * @see java.awt.MouseInfo#getNumberOfButtons()
+     * @see java.awt.event.MouseEvent
      */
     public synchronized void mousePress(int buttons) {
         checkButtonsArgument(buttons);
@@ -209,16 +256,53 @@
     /**
      * Releases one or more mouse buttons.
      *
-     * @param buttons   the Button mask; a combination of one or more
-     * of these flags:
+     * @param buttons the Button mask; a combination of one or more
+     * mouse button masks.
+     * <p>
+     * It is allowed to use only a combination of valid values as a {@code buttons} parameter.
+     * A valid combination consists of {@code InputEvent.BUTTON1_DOWN_MASK},
+     * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK}
+     * and values returned by the
+     * {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)} method.
+     *
+     * The valid combination also depends on a
+     * {@link Toolkit#areExtraMouseButtonsEnabled() Toolkit.areExtraMouseButtonsEnabled()} value as follows:
      * <ul>
-     * <li><code>InputEvent.BUTTON1_MASK</code>
-     * <li><code>InputEvent.BUTTON2_MASK</code>
-     * <li><code>InputEvent.BUTTON3_MASK</code>
+     * <li> If the support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * then it is allowed to use only the following standard button masks:
+     * {@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+     * {@code InputEvent.BUTTON3_DOWN_MASK}.
+     * <li> If the support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+     * then it is allowed to use the standard button masks
+     * and masks for existing extended mouse buttons, if the mouse has more then three buttons.
+     * In that way, it is allowed to use the button masks corresponding to the buttons
+     * in the range from 1 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+     * <br>
+     * It is recommended to use the {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)}
+     * method to obtain the mask for any mouse button by its number.
      * </ul>
+     * <p>
+     * The following standard button masks are also accepted:
+     * <ul>
+     * <li>{@code InputEvent.BUTTON1_MASK}
+     * <li>{@code InputEvent.BUTTON2_MASK}
+     * <li>{@code InputEvent.BUTTON3_MASK}
+     * </ul>
+     * However, it is recommended to use {@code InputEvent.BUTTON1_DOWN_MASK},
+     * {@code InputEvent.BUTTON2_DOWN_MASK},  {@code InputEvent.BUTTON3_DOWN_MASK} instead.
+     * Either extended {@code _DOWN_MASK} or old {@code _MASK} values
+     * should be used, but both those models should not be mixed.
+     * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+     *         and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+     *         that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
      * @see #mousePress(int)
-     * @throws  IllegalArgumentException if the button mask is not a valid
-     *          combination
+     * @see InputEvent#getMaskForButton(int)
+     * @see Toolkit#areExtraMouseButtonsEnabled()
+     * @see java.awt.MouseInfo#getNumberOfButtons()
+     * @see java.awt.event.MouseEvent
      */
     public synchronized void mouseRelease(int buttons) {
         checkButtonsArgument(buttons);
--- a/jdk/src/share/classes/java/awt/Toolkit.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Toolkit.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2550,4 +2550,37 @@
             }
         }
     }
+
+    /**
+    * Reports whether events from extra mouse buttons are allowed to be processed and posted into
+    * {@code EventQueue}.
+    * <br>
+    * To change the returned value it is necessary to set the {@code sun.awt.enableExtraMouseButtons}
+    * property before the {@code Toolkit} class initialization. This setting could be done on the application
+    * startup by the following command:
+    * <pre>
+    * java -Dsun.awt.enableExtraMouseButtons=false Application
+    * </pre>
+    * Alternatively, the property could be set in the application by using the following code:
+    * <pre>
+    * System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+    * </pre>
+    * before the {@code Toolkit} class initialization.
+    * If not set by the time of the {@code Toolkit} class initialization, this property will be
+    * initialized with {@code true}.
+    * Changing this value after the {@code Toolkit} class initialization will have no effect.
+    * <p>
+    * The current value could be queried by using the
+    * {@code System.getProperty("sun.awt.enableExtraMouseButtons")} method.
+    * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
+    * @return {@code true} if events from extra mouse buttons are allowed to be processed and posted;
+    *         {@code false} otherwise
+    * @see System#getProperty(String propertyName)
+    * @see System#setProperty(String propertyName, String value)
+    * @see java.awt.EventQueue
+    * @since 1.7
+     */
+    public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+        return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
+    }
 }
--- a/jdk/src/share/classes/java/awt/doc-files/DesktopProperties.html	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/doc-files/DesktopProperties.html	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 <!--
- Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,11 @@
 <td valign="TOP"><a href="../../util/Map.html">java.util.Map<a/></td>
 <td valign="TOP">Font smoothing (text antialiasing) settings.<a/></td>
 </tr>
+<tr>
+<td valign="TOP"><A href=#"sun.awt.enableExtraMouseButtons">sun.awt.enableExtraMouseButtons</A</td>
+<td valign="TOP"><a href="../../lang/Boolean.html">java.lang.Boolean<a/></td>
+<td valign="TOP">Controls if mouse events from extra buttons are to be generated or not<a/></td>
+</tr>
 </table>
 <p>
 <h2>Desktop Font Rendering Hints</h2>
@@ -219,5 +224,50 @@
 determine that there is a non-null return for any screen device using
 the per-device property name.
 </ul>
+<h2>Mouse Functionality</h2>
+<b>Desktop Property: <A name="sun.awt.enableExtraMouseButtons">"sun.awt.enableExtraMouseButtons"</A></b>
+<p>
+This property determines if events from extra mouse buttons (if they are exist and are
+enabled by the underlying operating system) are allowed to be processed and posted into
+{@code EventQueue}.
+<br>
+The value could be changed by passing "sun.awt.enableExtraMouseButtons"
+property value into java before application starts. This could be done with the following command:
+<pre>
+java -Dsun.awt.enableExtraMouseButtons=false Application
+</pre>
+Once set on application startup, it is impossible to change this value after.
+<br>
+Current value could also be queried using getDesktopProperty("sun.awt.enableExtraMouseButtons")
+method.
+<br>
+If the property is set to {@code true} then 
+<ul>
+<li> it is still legal to create {@code MouseEvent} objects with
+standard buttons and, if the mouse has more
+then three buttons, it is also legal to use buttons from the range started
+from 0 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}.
+
+<li> it is legal to use standard button masks when using {@code Robot.mousePress()}
+and {@code Robot.mouseRelease()} methods and, if the mouse has more then three buttons,
+it is also legal to use masks for existing extended mouse buttons.
+That way, if there are more then three buttons on the mouse then it is allowed to
+use button masks corresponding to the buttons 
+in the range from 1 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}
+</ul>
+<br>
+If the property is set to {@code false} then 
+<ul>
+<li> it is legal to create {@code MouseEvent} objects with standard buttons 
+only: {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} and
+{@code BUTTON3}
+<li> it is legal to use standard button masks only:
+{@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+{@code InputEvent.BUTTON3_DOWN_MASK}
+</ul>
+
+This property should be used when there is no need in listening mouse events fired as a result of
+activity with extra mouse button.
+By default this property is set to {@code true}.
 </body>
 </html>
--- a/jdk/src/share/classes/java/awt/event/InputEvent.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/event/InputEvent.java	Tue Sep 16 12:17:02 2008 +0400
@@ -31,6 +31,7 @@
 import java.awt.Toolkit;
 import java.util.logging.Logger;
 import java.util.logging.Level;
+import java.util.Arrays;
 
 /**
  * The root event class for all component-level input events.
@@ -153,13 +154,93 @@
      */
     public static final int ALT_GRAPH_DOWN_MASK = 1 << 13;
 
+    /**
+     * An array of extended modifiers for additional buttons.
+     * @see getButtonDownMasks
+     * @since 7.0
+     */
+    private static final int [] BUTTON_DOWN_MASK = new int [] { BUTTON1_DOWN_MASK,
+                                                               BUTTON2_DOWN_MASK,
+                                                               BUTTON3_DOWN_MASK,
+                                                               1<<14, //4th phisical button (this is not a wheel!)
+                                                               1<<15, //(this is not a wheel!)
+                                                               1<<16,
+                                                               1<<17,
+                                                               1<<18,
+                                                               1<<19,
+                                                               1<<20,
+                                                               1<<21 };
+
+    /**
+     * A method to access an array of extended modifiers for additional buttons.
+     * @since 7.0
+     */
+    private static int [] getButtonDownMasks(){
+        return Arrays.copyOf(BUTTON_DOWN_MASK, BUTTON_DOWN_MASK.length);
+    }
+
+
+    /**
+     * A method to obtain a mask for any existing mouse button.
+     * The returned mask may be used for different purposes. Following are some of them:
+     * <ul>
+     * <li> {@link java.awt.Robot#mousePress(int) mousePress(buttons)} and
+     *      {@link java.awt.Robot#mouseRelease(int) mouseRelease(buttons)}
+     * <li> as a {@code modifiers} parameter when creating a new {@link MouseEvent} instance
+     * <li> to check {@link MouseEvent#getModifiersEx() modifiersEx} of existing {@code MouseEvent}
+     * </ul>
+     * @param button is a number to represent a button starting from 1.
+     * For example,
+     * <pre>
+     * int button = InputEvent.getMaskForButton(1);
+     * </pre>
+     * will have the same meaning as
+     * <pre>
+     * int button = InputEvent.getMaskForButton(MouseEvent.BUTTON1);
+     * </pre>
+     * because {@link MouseEvent#BUTTON1 MouseEvent.BUTTON1} equals to 1.
+     * If a mouse has three enabled buttons(see {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()})
+     * then the values from the left column passed into the method will return
+     * corresponding values from the right column:
+     * <PRE>
+     *    <b>button </b>   <b>returned mask</b>
+     *    {@link MouseEvent#BUTTON1 BUTTON1}  {@link MouseEvent#BUTTON1_DOWN_MASK BUTTON1_DOWN_MASK}
+     *    {@link MouseEvent#BUTTON2 BUTTON2}  {@link MouseEvent#BUTTON2_DOWN_MASK BUTTON2_DOWN_MASK}
+     *    {@link MouseEvent#BUTTON3 BUTTON3}  {@link MouseEvent#BUTTON3_DOWN_MASK BUTTON3_DOWN_MASK}
+     * </PRE>
+     * If a mouse has more than three enabled buttons then more values
+     * are admissible (4, 5, etc.). There is no assigned constants for these extended buttons.
+     * The button masks for the extra buttons returned by this method have no assigned names like the
+     * first three button masks.
+     * <p>
+     * This method has the following implementation restriction.
+     * It returns masks for a limited number of buttons only. The maximum number is
+     * implementation dependent and may vary.
+     * This limit is defined by the relevant number
+     * of buttons that may hypothetically exist on the mouse but it is greater than the
+     * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+     * <p>
+     * @throws IllegalArgumentException if {@code button} is less than zero or greater than the number
+     *         of button masks reserved for buttons
+     * @since 7.0
+     * @see java.awt.MouseInfo#getNumberOfButtons()
+     * @see Toolkit#areExtraMouseButtonsEnabled()
+     * @see MouseEvent#getModifiers()
+     * @see MouseEvent#getModifiersEx()
+     */
+    public static int getMaskForButton(int button) {
+        if (button <= 0 || button > BUTTON_DOWN_MASK.length) {
+            throw new IllegalArgumentException("button doesn\'t exist " + button);
+        }
+        return BUTTON_DOWN_MASK[button - 1];
+    }
+
     // the constant below MUST be updated if any extra modifier
     // bits are to be added!
     // in fact, it is undesirable to add modifier bits
     // to the same field as this may break applications
     // see bug# 5066958
-
-    static final int FIRST_HIGH_BIT = 1 << 14;
+    static final int FIRST_HIGH_BIT = 1 << 22;
 
     static final int JDK_1_3_MODIFIERS = SHIFT_DOWN_MASK - 1;
     static final int HIGH_MODIFIERS = ~( FIRST_HIGH_BIT - 1 );
@@ -382,7 +463,7 @@
      * cause the returning an empty string.
      *
      * @param modifiers a modifier mask describing the extended
-       *                modifier keys and mouse buttons for the event
+     *                modifier keys and mouse buttons for the event
      * @return a text description of the combination of extended
      *         modifier keys and mouse buttons that were held down
      *         during the event.
@@ -410,17 +491,14 @@
             buf.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph"));
             buf.append("+");
         }
-        if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) {
-            buf.append(Toolkit.getProperty("AWT.button1", "Button1"));
-            buf.append("+");
-        }
-        if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) {
-            buf.append(Toolkit.getProperty("AWT.button2", "Button2"));
-            buf.append("+");
-        }
-        if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) {
-            buf.append(Toolkit.getProperty("AWT.button3", "Button3"));
-            buf.append("+");
+
+        int buttonNumber = 1;
+        for (int mask : InputEvent.BUTTON_DOWN_MASK){
+            if ((modifiers & mask) != 0) {
+                buf.append(Toolkit.getProperty("AWT.button"+buttonNumber, "Button"+buttonNumber));
+                buf.append("+");
+            }
+            buttonNumber++;
         }
         if (buf.length() > 0) {
             buf.setLength(buf.length()-1); // remove trailing '+'
--- a/jdk/src/share/classes/java/awt/event/MouseEvent.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java	Tue Sep 16 12:17:02 2008 +0400
@@ -32,6 +32,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.awt.IllegalComponentStateException;
+import java.awt.MouseInfo;
 
 /**
  * An event which indicates that a mouse action occurred in a component.
@@ -135,7 +136,15 @@
  * for <code>BUTTON2_MASK</code> arrives first,
  * followed by the pair for <code>BUTTON1_MASK</code>.
  * <p>
- *
+ * Some extra mouse buttons are added to extend the standard set of buttons
+ * represented by the following constants:{@code BUTTON1}, {@code BUTTON2}, and {@code BUTTON3}.
+ * Extra buttons have no assigned {@code BUTTONx}
+ * constants as well as their button masks have no assigned {@code BUTTONx_DOWN_MASK}
+ * constants. Nevertheless, ordinal numbers starting from 4 may be
+ * used as button numbers (button ids). Values obtained by the
+ * {@link InputEvent#getMaskForButton(int) getMaskForButton(button)} method may be used
+ * as button masks.
+ * <p>
  * <code>MOUSE_DRAGGED</code> events are delivered to the <code>Component</code>
  * in which the mouse button was pressed until the mouse button is released
  * (regardless of whether the mouse position is within the bounds of the
@@ -324,13 +333,31 @@
     /**
      * Indicates which, if any, of the mouse buttons has changed state.
      *
-     * The only legal values are the following constants:
-     * <code>NOBUTTON</code>,
-     * <code>BUTTON1</code>,
-     * <code>BUTTON2</code> or
-     * <code>BUTTON3</code>.
+     * The valid values are ranged from 0 to the value returned by the
+     * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()} method.
+     * This range already includes constants {@code NOBUTTON}, {@code BUTTON1},
+     * {@code BUTTON2}, and {@code BUTTON3}
+     * if these buttons are present. So it is allowed to use these constants too.
+     * For example, for a mouse with two buttons this field may contain the following values:
+     * <ul>
+     * <li> 0 ({@code NOBUTTON})
+     * <li> 1 ({@code BUTTON1})
+     * <li> 2 ({@code BUTTON2})
+     * </ul>
+     * If a mouse has 5 buttons, this field may contain the following values:
+     * <ul>
+     * <li> 0 ({@code NOBUTTON})
+     * <li> 1 ({@code BUTTON1})
+     * <li> 2 ({@code BUTTON2})
+     * <li> 3 ({@code BUTTON3})
+     * <li> 4
+     * <li> 5
+     * </ul>
+     * If support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled()} disabled by Java
+     * then the field may not contain the value larger than {@code BUTTON3}.
      * @serial
-     * @see #getButton().
+     * @see #getButton()
+     * @see java.awt.Toolkit#areExtraMouseButtonsEnabled()
      */
     int button;
 
@@ -385,6 +412,15 @@
     }
 
     /**
+     * A number of buttons available on the mouse at the {@code Toolkit} machinery startup.
+     */
+    private static int cachedNumberOfButtons;
+
+    static {
+        cachedNumberOfButtons = MouseInfo.getNumberOfButtons();
+    }
+
+    /**
      * Returns the absolute horizontal x position of the event.
      * In a virtual device multi-screen environment in which the
      * desktop area could span multiple physical screen devices,
@@ -421,7 +457,8 @@
     /**
      * Constructs a <code>MouseEvent</code> object with the
      * specified source component,
-     * type, modifiers, coordinates, and click count.
+     * type, time, modifiers, coordinates, click count, popupTrigger flag,
+     * and button number.
      * <p>
      * Creating an invalid event (such
      * as by using more than one of the old _MASKs, or modifier/button
@@ -464,7 +501,33 @@
      * @param popupTrigger A boolean that equals {@code true} if this event
      *                     is a trigger for a popup menu
      * @param button       An integer that indicates, which of the mouse buttons has
-     *                     changed its state
+     *                     changed its state.
+     * The following rules are applied to this parameter:
+     * <ul>
+     * <li>If support for the extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * then it is allowed to create {@code MouseEvent} objects only with the standard buttons:
+     * {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, and
+     * {@code BUTTON3}.
+     * <li> If support for the extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+     * then it is allowed to create {@code MouseEvent} objects with
+     * the standard buttons.
+     * In case the support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java, then
+     * in addition to the standard buttons, {@code MouseEvent} objects can be created
+     * using buttons from the range starting from 4 to
+     * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+     * if the mouse has more than three buttons.
+     * </ul>
+     * @throws IllegalArgumentException if {@code button} is less then zero
+     * @throws IllegalArgumentException if <code>source</code> is null
+     * @throws IllegalArgumentException if {@code button} is greater then BUTTON3 and the support for extended mouse buttons is
+     *                                  {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * @throws IllegalArgumentException if {@code button} is greater then the
+     *                                  {@link java.awt.MouseInfo#getNumberOfButtons() current number of buttons} and the support
+     *                                  for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
+     *                                  by Java
      * @throws IllegalArgumentException if an invalid <code>button</code>
      *            value is passed in
      * @throws IllegalArgumentException if <code>source</code> is null
@@ -498,7 +561,7 @@
     /**
      * Constructs a <code>MouseEvent</code> object with the
      * specified source component,
-     * type, modifiers, coordinates, and click count.
+     * type, modifiers, coordinates, click count, and popupTrigger flag.
      * An invocation of the form
      * <tt>MouseEvent(source, id, when, modifiers, x, y, clickCount, popupTrigger)</tt>
      * behaves in exactly the same way as the invocation
@@ -551,10 +614,26 @@
      }
 
 
+    /* if the button is an extra button and it is released or clicked then in Xsystem its state
+       is not modified. Exclude this button number from ExtModifiers mask.*/
+    transient private boolean shouldExcludeButtonFromExtModifiers = false;
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getModifiersEx() {
+        int tmpModifiers = modifiers;
+        if (shouldExcludeButtonFromExtModifiers) {
+            tmpModifiers &= ~(InputEvent.getMaskForButton(getButton()));
+        }
+        return tmpModifiers & ~JDK_1_3_MODIFIERS;
+    }
+
     /**
      * Constructs a <code>MouseEvent</code> object with the
      * specified source component,
-     * type, modifiers, coordinates, absolute coordinates, and click count.
+     * type, time, modifiers, coordinates, absolute coordinates, click count, popupTrigger flag,
+     * and button number.
      * <p>
      * Creating an invalid event (such
      * as by using more than one of the old _MASKs, or modifier/button
@@ -595,7 +674,33 @@
      * @param popupTrigger A boolean that equals {@code true} if this event
      *                     is a trigger for a popup menu
      * @param button       An integer that indicates, which of the mouse buttons has
-     *                     changed its state
+     *                     changed its state.
+     * The following rules are applied to this parameter:
+     * <ul>
+     * <li>If support for the extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * then it is allowed to create {@code MouseEvent} objects only with the standard buttons:
+     * {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, and
+     * {@code BUTTON3}.
+     * <li> If support for the extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+     * then it is allowed to create {@code MouseEvent} objects with
+     * the standard buttons.
+     * In case the support for extended mouse buttons is
+     * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java, then
+     * in addition to the standard buttons, {@code MouseEvent} objects can be created
+     * using buttons from the range starting from 4 to
+     * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+     * if the mouse has more than three buttons.
+     * </ul>
+     * @throws IllegalArgumentException if {@code button} is less then zero
+     * @throws IllegalArgumentException if <code>source</code> is null
+     * @throws IllegalArgumentException if {@code button} is greater then BUTTON3 and the support for extended mouse buttons is
+     *                                  {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * @throws IllegalArgumentException if {@code button} is greater then the
+     *                                  {@link java.awt.MouseInfo#getNumberOfButtons() current number of buttons} and the support
+     *                                  for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
+     *                                  by Java
      * @throws IllegalArgumentException if an invalid <code>button</code>
      *            value is passed in
      * @throws IllegalArgumentException if <code>source</code> is null
@@ -610,6 +715,10 @@
      * @see #getClickCount()
      * @see #isPopupTrigger()
      * @see #getButton()
+     * @see #button
+     * @see Toolkit#areExtraMouseButtonsEnabled()
+     * @see java.awt.MouseInfo#getNumberOfButtons()
+     * @see InputEvent#getMaskForButton(int)
      * @since 1.6
      */
     public MouseEvent(Component source, int id, long when, int modifiers,
@@ -623,14 +732,41 @@
         this.yAbs = yAbs;
         this.clickCount = clickCount;
         this.popupTrigger = popupTrigger;
-        if (button < NOBUTTON || button >BUTTON3) {
-            throw new IllegalArgumentException("Invalid button value");
+        if (button < NOBUTTON){
+            throw new IllegalArgumentException("Invalid button value :" + button);
         }
+        //TODO: initialize MouseInfo.cachedNumber on toolkit creation.
+        if (button > BUTTON3) {
+            if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+                throw new IllegalArgumentException("Extra mouse events are disabled " + button);
+            } else {
+                if (button > cachedNumberOfButtons) {
+                    throw new IllegalArgumentException("Nonexistent button " + button);
+                }
+            }
+            // XToolkit: extra buttons are not reporting about their state correctly.
+            // Being pressed they report the state=0 both on the press and on the release.
+            // For 1-3 buttons the state value equals zero on press and non-zero on release.
+            // Other modifiers like Shift, ALT etc seem report well with extra buttons.
+            // The problem reveals as follows: one button is pressed and then another button is pressed and released.
+            // So, the getModifiersEx() would not be zero due to a first button and we will skip this modifier.
+            // This may have to be moved into the peer code instead if possible.
+
+            if (getModifiersEx() != 0) { //There is at least one more button in a pressed state.
+                if (id == MouseEvent.MOUSE_RELEASED || id == MouseEvent.MOUSE_CLICKED){
+                    System.out.println("MEvent. CASE!");
+                    shouldExcludeButtonFromExtModifiers = true;
+                }
+            }
+        }
+
         this.button = button;
+
         if ((getModifiers() != 0) && (getModifiersEx() == 0)) {
             setNewModifiers();
         } else if ((getModifiers() == 0) &&
-                   (getModifiersEx() != 0 || button != NOBUTTON))
+                   (getModifiersEx() != 0 || button != NOBUTTON) &&
+                   (button <= BUTTON3))
         {
             setOldModifiers();
         }
@@ -701,13 +837,55 @@
 
     /**
      * Returns which, if any, of the mouse buttons has changed state.
+     * The returned value is ranged
+     * from 0 to the {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+     * value.
+     * The returned value includes at least the following constants:
+     * <ul>
+     * <li> {@code NOBUTTON}
+     * <li> {@code BUTTON1}
+     * <li> {@code BUTTON2}
+     * <li> {@code BUTTON3}
+     * </ul>
+     * It is allowed to use those constants to compare with the returned button number in the application.
+     * For example,
+     * <pre>
+     * if (anEvent.getButton() == MouseEvent.BUTTON1) {
+     * </pre>
+     * In particular, for a mouse with one, two, or three buttons this method may return the following values:
+     * <ul>
+     * <li> 0 ({@code NOBUTTON})
+     * <li> 1 ({@code BUTTON1})
+     * <li> 2 ({@code BUTTON2})
+     * <li> 3 ({@code BUTTON3})
+     * </ul>
+     * Button numbers greater then {@code BUTTON3} have no constant identifier. So if a mouse with five buttons is
+     * installed, this method may return the following values:
+     * <ul>
+     * <li> 0 ({@code NOBUTTON})
+     * <li> 1 ({@code BUTTON1})
+     * <li> 2 ({@code BUTTON2})
+     * <li> 3 ({@code BUTTON3})
+     * <li> 4
+     * <li> 5
+     * </ul>
+     * <p>
+     * Note: If support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+     * then the AWT event subsystem does not produce mouse events for the extended mouse
+     * buttons. So it is not expected that this method returns anything except {@code NOBUTTON}, {@code BUTTON1},
+     * {@code BUTTON2}, {@code BUTTON3}.
      *
-     * @return one of the following constants:
-     * <code>NOBUTTON</code>,
-     * <code>BUTTON1</code>,
-     * <code>BUTTON2</code> or
-     * <code>BUTTON3</code>.
+     * @return one of the values from 0 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+     *         if support for the extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java.
+     *         That range includes {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, {@code BUTTON3};
+     *         <br>
+     *         {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} or {@code BUTTON3}
+     *         if support for the extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
      * @since 1.4
+     * @see Toolkit#areExtraMouseButtonsEnabled()
+     * @see java.awt.MouseInfo#getNumberOfButtons()
+     * @see #MouseEvent(Component, int, long, int, int, int, int, int, int, boolean, int)
+     * @see InputEvent#getMaskForButton(int)
      */
     public int getButton() {
         return button;
@@ -746,7 +924,7 @@
      * and will cause the returning an unspecified string.
      * Zero parameter means that no modifiers were passed and will
      * cause the returning an empty string.
-     *
+     * <p>
      * @param modifiers A modifier mask describing the modifier keys and
      *                  mouse buttons that were down during the event
      * @return string   string text description of the combination of modifier
@@ -788,6 +966,24 @@
             buf.append(Toolkit.getProperty("AWT.button3", "Button3"));
             buf.append("+");
         }
+
+        int mask;
+
+        // TODO: add a toolkit field that holds a number of button on the mouse.
+        // As the method getMouseModifiersText() is static and obtain
+        // an integer as a parameter then we may not restrict this with the number
+        // of buttons installed on the mouse.
+        // It's a temporary solution. We need to somehow hold the number of buttons somewhere else.
+        for (int i = 1; i <= cachedNumberOfButtons; i++){
+            mask = InputEvent.getMaskForButton(i);
+            if ((modifiers & mask) != 0 &&
+                buf.indexOf(Toolkit.getProperty("AWT.button"+i, "Button"+i)) == -1) //1,2,3 buttons may already be there; so don't duplicate it.
+            {
+                buf.append(Toolkit.getProperty("AWT.button"+i, "Button"+i));
+                buf.append("+");
+            }
+        }
+
         if (buf.length() > 0) {
             buf.setLength(buf.length()-1); // remove trailing '+'
         }
@@ -836,14 +1032,18 @@
         str.append(",(").append(x).append(",").append(y).append(")");
         str.append(",absolute(").append(xAbs).append(",").append(yAbs).append(")");
 
-        str.append(",button=").append(getButton());
+        if (id != MOUSE_DRAGGED && id != MOUSE_MOVED){
+            str.append(",button=").append(getButton());
+        }
 
         if (getModifiers() != 0) {
             str.append(",modifiers=").append(getMouseModifiersText(modifiers));
         }
 
         if (getModifiersEx() != 0) {
-            str.append(",extModifiers=").append(getModifiersExText(modifiers));
+            //Using plain "modifiers" here does show an excluded extended buttons in the string event representation.
+            //getModifiersEx() solves the problem.
+            str.append(",extModifiers=").append(getModifiersExText(getModifiersEx()));
         }
 
         str.append(",clickCount=").append(clickCount);
--- a/jdk/src/share/classes/java/awt/peer/RobotPeer.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/peer/RobotPeer.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,4 +52,5 @@
     public int [] getRGBPixels(Rectangle bounds);
 
     public void dispose();
+    public int getNumberOfButtons();
 }
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -468,4 +468,8 @@
     throws HeadlessException{
         throw new HeadlessException();
     }
+
+    public boolean areExtraMouseButtonsEnabled() throws HeadlessException{
+        throw new HeadlessException();
+    }
 }
--- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Tue Sep 16 12:17:02 2008 +0400
@@ -979,8 +979,13 @@
      */
     public void handleButtonPressRelease(XEvent xev) {
         XButtonEvent xbe = xev.get_xbutton();
-        final int buttonState = xbe.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask
-            | XConstants.Button3Mask | XConstants.Button4Mask | XConstants.Button5Mask);
+        int buttonState = 0;
+        for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
+            // A bug in WM implementation: extra buttons doesn't have state!=0 as they should on Release message.
+            if ((i != 4) && (i != 5)){
+                buttonState |= (xbe.get_state() & XConstants.buttonsMask[i]);
+            }
+        }
         switch (xev.get_type()) {
         case XConstants.ButtonPress:
             if (buttonState == 0) {
@@ -1011,19 +1016,11 @@
      * Checks ButtonRelease released all Mouse buttons
      */
     static boolean isFullRelease(int buttonState, int button) {
-        switch (button) {
-        case XConstants.Button1:
-            return buttonState == XConstants.Button1Mask;
-        case XConstants.Button2:
-            return buttonState == XConstants.Button2Mask;
-        case XConstants.Button3:
-            return buttonState == XConstants.Button3Mask;
-        case XConstants.Button4:
-            return buttonState == XConstants.Button4Mask;
-        case XConstants.Button5:
-            return buttonState == XConstants.Button5Mask;
+        if (button < 0 || button > XToolkit.getNumMouseButtons()) {
+            return buttonState == 0;
+        } else {
+            return buttonState == XConstants.buttonsMask[button - 1];
         }
-        return buttonState == 0;
     }
 
     static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XConstants.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XConstants.java	Tue Sep 16 12:17:02 2008 +0400
@@ -197,12 +197,30 @@
 
     /* button masks.  Used in same manner as Key masks above. Not to be confused
        with button names below. */
-
-    public static final int Button1Mask = (1<<8) ;
-    public static final int Button2Mask = (1<<9) ;
-    public static final int Button3Mask = (1<<10) ;
-    public static final int Button4Mask = (1<<11) ;
-    public static final int Button5Mask = (1<<12) ;
+    public static final int [] buttonsMask = new int []{ 1<<8,
+                                                         1<<9,
+                                                         1<<10,
+                                                         1<<11,
+                                                         1<<12,
+                                                         1<<13,
+                                                         1<<14,
+                                                         1<<15,
+                                                         1<<16,
+                                                         1<<17,
+                                                         1<<18,
+                                                         1<<19,
+                                                         1<<20,
+                                                         1<<21,
+                                                         1<<22,
+                                                         1<<23,
+                                                         1<<24,
+                                                         1<<25,
+                                                         1<<26,
+                                                         1<<27,
+                                                         1<<28,
+                                                         1<<29,
+                                                         1<<30,
+                                                         1<<31 };
 
     public static final int AnyModifier = (1<<15) ; /* used in GrabButton, GrabKey */
 
@@ -211,11 +229,7 @@
        and ButtonRelease events.  Not to be confused with button masks above.
        Note that 0 is already defined above as "AnyButton".  */
 
-    public static final int Button1 = 1 ;
-    public static final int Button2 = 2 ;
-    public static final int Button3 = 3 ;
-    public static final int Button4 = 4 ;
-    public static final int Button5 = 5 ;
+    public static final int buttons [] = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
 
     /* Notify modes */
 
--- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java	Tue Sep 16 12:17:02 2008 +0400
@@ -694,8 +694,8 @@
             } finally {
                 xmotion.dispose();
             }
-            if (xbutton.get_button() == XConstants.Button1
-                    || xbutton.get_button() == XConstants.Button2) {
+            if (xbutton.get_button() == XConstants.buttons[0]
+                || xbutton.get_button() == XConstants.buttons[1]) {
                 // drag is initiated with Button1 or Button2 pressed and
                 // ended on release of either of these buttons (as the same
                 // behavior was with our old Motif DnD-based implementation)
--- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,11 +81,16 @@
         return pixelArray;
     }
 
+    public int getNumberOfButtons(){
+        return getNumberOfButtonsImpl();
+    }
+
     private static native synchronized void setup();
 
     private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
     private static native synchronized void mousePressImpl(int buttons);
     private static native synchronized void mouseReleaseImpl(int buttons);
+    private static native synchronized int getNumberOfButtonsImpl();
     private static native synchronized void mouseWheelImpl(int wheelAmt);
 
     private static native synchronized void keyPressImpl(int keycode);
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Tue Sep 16 12:17:02 2008 +0400
@@ -74,6 +74,10 @@
     // Dynamic Layout Resize client code setting
     protected static boolean dynamicLayoutSetting = false;
 
+    //Is it allowed to generate events assigned to extra mouse buttons.
+    //Set to true by default.
+    private static boolean areExtraMouseButtonsEnabled = true;
+
     /**
      * True when the x settings have been loaded.
      */
@@ -273,6 +277,9 @@
 
             arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
                 XCursorFontConstants.XC_arrow);
+            areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
+            //set system property if not yet assigned
+            System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
         } finally {
             awtUnlock();
         }
@@ -1383,7 +1390,7 @@
         }
     }
 
-    private int getNumMouseButtons() {
+    public static int getNumMouseButtons() {
         awtLock();
         try {
             return XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0);
@@ -2166,4 +2173,8 @@
     }
 
     public static native void setNoisyXErrorHandler();
+
+    public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+        return areExtraMouseButtonsEnabled;
+    }
 }
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java	Tue Sep 16 12:17:02 2008 +0400
@@ -553,6 +553,10 @@
     }
 
     static int getModifiers(int state, int button, int keyCode) {
+        return getModifiers(state, button, keyCode, 0,  false);
+    }
+
+    static int getModifiers(int state, int button, int keyCode, int type, boolean wheel_mouse) {
         int modifiers = 0;
 
         if (((state & XConstants.ShiftMask) != 0) ^ (keyCode == KeyEvent.VK_SHIFT)) {
@@ -570,14 +574,23 @@
         if (((state & XToolkit.modeSwitchMask) != 0) ^ (keyCode == KeyEvent.VK_ALT_GRAPH)) {
             modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
         }
-        if (((state & XConstants.Button1Mask) != 0) ^ (button == MouseEvent.BUTTON1)) {
-            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
-        }
-        if (((state & XConstants.Button2Mask) != 0) ^ (button == MouseEvent.BUTTON2)) {
-            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
-        }
-        if (((state & XConstants.Button3Mask) != 0) ^ (button == MouseEvent.BUTTON3)) {
-            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+        //InputEvent.BUTTON_DOWN_MASK array is starting from BUTTON1_DOWN_MASK on index == 0.
+        // button currently reflects a real button number and starts from 1. (except NOBUTTON which is zero )
+
+        /* this is an attempt to refactor button IDs in : MouseEvent, InputEvent, XlibWrapper and XWindow.*/
+
+        //reflects a button number similar to MouseEvent.BUTTON1, 2, 3 etc.
+        for (int i = 0; i < XConstants.buttonsMask.length; i ++){
+            //modifier should be added if :
+            // 1) current button is now still in PRESSED state (means that user just pressed mouse but not released yet) or
+            // 2) if Xsystem reports that "state" represents that button was just released. This only happens on RELEASE with 1,2,3 buttons.
+            // ONLY one of these conditions should be TRUE to add that modifier.
+            if (((state & XConstants.buttonsMask[i]) != 0) != (button == XConstants.buttons[i])){
+                //exclude wheel buttons from adding their numbers as modifiers
+                if (!wheel_mouse) {
+                    modifiers |= InputEvent.getMaskForButton(i+1);
+                }
+            }
         }
         return modifiers;
     }
@@ -603,17 +616,6 @@
         return res;
     }
 
-    private static int getButtonMask(long mouseButton) {
-        if (mouseButton == XConstants.Button1) {
-            return XConstants.Button1Mask;
-        } else if (mouseButton == XConstants.Button2) {
-            return XConstants.Button2Mask;
-        } else if (mouseButton == XConstants.Button3) {
-            return XConstants.Button3Mask;
-        }
-        return 0;
-    }
-
     /**
      * Returns true if this event is disabled and shouldn't be passed to Java.
      * Default implementation returns false for all events.
@@ -648,7 +650,7 @@
         boolean popupTrigger = false;
         int button=0;
         boolean wheel_mouse = false;
-        long lbutton = xbe.get_button();
+        int lbutton = xbe.get_button();
         int type = xev.get_type();
         when = xbe.get_time();
         long jWhen = XToolkit.nowMillisUTC_offset(when);
@@ -663,7 +665,7 @@
 
         if (type == XConstants.ButtonPress) {
             //Allow this mouse button to generate CLICK event on next ButtonRelease
-            mouseButtonClickAllowed |= getButtonMask(lbutton);
+            mouseButtonClickAllowed |= XConstants.buttonsMask[lbutton];
             XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
             /*
                multiclick checking
@@ -693,21 +695,22 @@
             }
         }
 
-        if (lbutton == XConstants.Button1)
-            button = MouseEvent.BUTTON1;
-        else if (lbutton ==  XConstants.Button2 )
-            button = MouseEvent.BUTTON2;
-        else if (lbutton == XConstants.Button3)
-            button = MouseEvent.BUTTON3;
-        else if (lbutton == XConstants.Button4) {
-            button = 4;
-            wheel_mouse = true;
-        } else if (lbutton == XConstants.Button5) {
-            button = 5;
+        button = XConstants.buttons[lbutton - 1];
+        // 4 and 5 buttons are usually considered assigned to a first wheel
+        if (lbutton == XConstants.buttons[3] ||
+            lbutton == XConstants.buttons[4]) {
             wheel_mouse = true;
         }
 
-        modifiers = getModifiers(xbe.get_state(),button,0);
+        // mapping extra buttons to numbers starting from 4.
+        if ((button > XConstants.buttons[4]) && (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled())){
+            return;
+        }
+
+        if (button > XConstants.buttons[4]){
+            button -= 2;
+        }
+        modifiers = getModifiers(xbe.get_state(),button,0, type, wheel_mouse);
 
         if (!wheel_mouse) {
             MouseEvent me = new MouseEvent((Component)getEventSource(),
@@ -720,7 +723,7 @@
             postEventToEventQueue(me);
 
             if ((type == XConstants.ButtonRelease) &&
-                ((mouseButtonClickAllowed & getButtonMask(lbutton)) != 0) ) // No up-button in the drag-state
+                ((mouseButtonClickAllowed & XConstants.buttonsMask[lbutton]) != 0) ) // No up-button in the drag-state
             {
                 postEventToEventQueue(me = new MouseEvent((Component)getEventSource(),
                                                      MouseEvent.MOUSE_CLICKED,
@@ -750,7 +753,7 @@
         /* Update the state variable AFTER the CLICKED event post. */
         if (type == XConstants.ButtonRelease) {
             /* Exclude this mouse button from allowed list.*/
-            mouseButtonClickAllowed &= ~getButtonMask(lbutton);
+            mouseButtonClickAllowed &= ~XConstants.buttonsMask[lbutton];
         }
     }
 
@@ -761,7 +764,19 @@
             return;
         }
 
-        int mouseKeyState = (xme.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask | XConstants.Button3Mask));
+        int mouseKeyState = 0; //(xme.get_state() & (XConstants.buttonsMask[0] | XConstants.buttonsMask[1] | XConstants.buttonsMask[2]));
+
+        //this doesn't work for extra buttons because Xsystem is sending state==0 for every extra button event.
+        // we can't correct it in MouseEvent class as we done it with modifiers, because exact type (DRAG|MOVE)
+        // should be passed from XWindow.
+        //TODO: eliminate it with some other value obtained w/o AWTLock.
+        for (int i = 0; i < XToolkit.getNumMouseButtons(); i++){
+            // TODO : here is the bug in WM: extra buttons doesn't have state!=0 as they should.
+            if ((i != 4) && (i != 5)) {
+                mouseKeyState = mouseKeyState | (xme.get_state() & XConstants.buttonsMask[i]);
+            }
+        }
+
         boolean isDragging = (mouseKeyState != 0);
         int mouseEventType = 0;
 
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1936,7 +1936,13 @@
                         new Object[] {xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root())});
         }
         if (isGrabbed()) {
-            boolean dragging = (xme.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask | XConstants.Button3Mask)) != 0;
+            boolean dragging = false;
+            for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
+                // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
+                if ((i != 4) && (i != 5)){
+                    dragging = dragging || ((xme.get_state() & XConstants.buttonsMask[i]) != 0);
+                }
+            }
             // When window is grabbed, all events are dispatched to
             // it.  Retarget them to the corresponding windows (notice
             // that XBaseWindow.dispatchEvent does the opposite
@@ -1990,12 +1996,12 @@
             try {
                 grabLog.log(Level.FINER, "  -  Grab event target {0} (press target {1})", new Object[] {target, pressTarget});
                 if (xbe.get_type() == XConstants.ButtonPress
-                    && xbe.get_button() == XConstants.Button1)
+                    && xbe.get_button() == XConstants.buttons[0])
                 {
                     // need to keep it to retarget mouse release
                     pressTarget = target;
                 } else if (xbe.get_type() == XConstants.ButtonRelease
-                           && xbe.get_button() == XConstants.Button1
+                           && xbe.get_button() == XConstants.buttons[0]
                            && pressTarget != target)
                 {
                     // during grab we do receive mouse release on different component (not on the source
--- a/jdk/src/solaris/native/sun/awt/awt_Robot.c	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
 // 2 would be more correct, however that's how Robot originally worked
 // and tests start to fail if this value is changed
 static int32_t num_buttons = 3;
+static jint * masks;
 
 static int32_t isXTestAvailable() {
     int32_t major_opcode, first_event, first_error;
@@ -208,6 +209,26 @@
 Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) {
     int32_t xtestAvailable;
 
+// this should be called from XRobotPeer constructor
+    jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent");
+    jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I");
+    jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID);
+    jsize len = (*env)->GetArrayLength(env, obj);
+    jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE);
+
+    masks  = (jint *)malloc(sizeof(jint)*len);
+    if (masks == (jint *) NULL) {
+        JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL);
+        goto finally;
+    }
+
+    int i;
+    for (i = 0; i < len; i++) {
+        masks[i] = tmp[i];
+    }
+    (*env)->ReleaseIntArrayElements(env, obj, tmp, 0);
+    (*env)->DeleteLocalRef(env, obj);
+
     DTRACE_PRINTLN("RobotPeer: setup()");
 
     AWT_LOCK();
@@ -221,8 +242,15 @@
     }
 
     getNumButtons();
+    finally:
+    AWT_UNLOCK();
+}
 
-    AWT_UNLOCK();
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XRobotPeer_getNumberOfButtonsImpl(JNIEnv *env,
+                                                   jclass cls) {
+    // At the moment this routine being called we already should have an initialized num_buttons variable.
+    return num_buttons;
 }
 
 JNIEXPORT void JNICALL
@@ -352,6 +380,8 @@
 Java_sun_awt_X11_XRobotPeer_mousePressImpl (JNIEnv *env,
                            jclass cls,
                            jint buttonMask) {
+    mouseAction(env, cls, buttonMask, True);
+/*
     AWT_LOCK();
 
     DTRACE_PRINTLN1("RobotPeer: mousePressImpl(%i)", buttonMask);
@@ -370,12 +400,15 @@
     XSync(awt_display, False);
 
     AWT_UNLOCK();
+*/
 }
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl (JNIEnv *env,
                              jclass cls,
                              jint buttonMask) {
+    mouseAction(env, cls, buttonMask, False);
+/*
     AWT_LOCK();
 
     DTRACE_PRINTLN1("RobotPeer: mouseReleaseImpl(%i)", buttonMask);
@@ -394,8 +427,57 @@
     XSync(awt_display, False);
 
     AWT_UNLOCK();
+*/
 }
 
+/*
+  * Function joining the code of mousePressImpl and mouseReleaseImpl
+  */
+void mouseAction(JNIEnv *env,
+                 jclass cls,
+                 jint buttonMask,
+                 Bool isMousePress)
+{
+    AWT_LOCK();
+
+    DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask);
+    DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress);
+
+    if (buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+        buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK )
+    {
+        XTestFakeButtonEvent(awt_display, 1, isMousePress, CurrentTime);
+    }
+    if ((buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+         buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) &&
+        (num_buttons >= 2)) {
+        XTestFakeButtonEvent(awt_display, 2, isMousePress, CurrentTime);
+    }
+    if ((buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+         buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) &&
+        (num_buttons >= 3)) {
+        XTestFakeButtonEvent(awt_display, 3, isMousePress, CurrentTime);
+    }
+
+    if (num_buttons > 3){
+        int32_t i;
+        int32_t button = 0;
+        for (i = 3; i<num_buttons; i++){
+            if ((buttonMask & masks[i])) {
+                // arrays starts from zero index => +1
+                // users wants to affect 4 or 5 button but they are assigned
+                // to the wheel so => we have to shift it to the right by 2.
+                button = i + 3;
+                XTestFakeButtonEvent(awt_display, button, isMousePress, CurrentTime);
+            }
+        }
+    }
+
+    XSync(awt_display, False);
+    AWT_UNLOCK();
+}
+
+
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XRobotPeer_mouseWheelImpl (JNIEnv *env,
                            jclass cls,
--- a/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,8 @@
     }
     public native int getRGBPixelImpl(int x, int y);
 
+    public native int getNumberOfButtons();
+
     public int [] getRGBPixels(Rectangle bounds) {
         int pixelArray[] = new int[bounds.width*bounds.height];
         getRGBPixels(bounds.x, bounds.y, bounds.width, bounds.height, pixelArray);
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java	Tue Sep 16 12:17:02 2008 +0400
@@ -80,6 +80,10 @@
     // Dynamic Layout Resize client code setting
     protected boolean dynamicLayoutSetting = false;
 
+    //Is it allowed to generate events assigned to extra mouse buttons.
+    //Set to true by default.
+    private static boolean areExtraMouseButtonsEnabled = true;
+
     /**
      * Initialize JNI field and method IDs
      */
@@ -249,6 +253,11 @@
         // Enabled "live resizing" by default.  It remains controlled
         // by the native system though.
         setDynamicLayout(true);
+
+        areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
+        //set system property if not yet assigned
+        System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
+        setExtraMouseButtonsEnabledNative(areExtraMouseButtonsEnabled);
     }
 
     public void run() {
@@ -961,4 +970,9 @@
         return new WDesktopPeer();
     }
 
+    public static native void setExtraMouseButtonsEnabledNative(boolean enable);
+
+    public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+        return areExtraMouseButtonsEnabled;
+    }
 }
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Tue Sep 16 12:17:02 2008 +0400
@@ -187,6 +187,8 @@
 UINT   AwtComponent::m_CodePage
                        = AwtComponent::LangToCodePage(m_idLang);
 
+jint *AwtComponent::masks;
+
 static BOOL bLeftShiftIsDown = false;
 static BOOL bRightShiftIsDown = false;
 static UINT lastShiftKeyPressed = 0; // init to safe value
@@ -1177,6 +1179,9 @@
         WIN_MSG(WM_MBUTTONDOWN)
         WIN_MSG(WM_MBUTTONUP)
         WIN_MSG(WM_MBUTTONDBLCLK)
+        WIN_MSG(WM_XBUTTONDBLCLK)
+        WIN_MSG(WM_XBUTTONDOWN)
+        WIN_MSG(WM_XBUTTONUP)
         WIN_MSG(WM_MOUSEWHEEL)
         WIN_MSG(WM_PARENTNOTIFY)
         WIN_MSG(WM_ENTERMENULOOP)
@@ -1612,6 +1617,9 @@
       case WM_MBUTTONDOWN:
       case WM_MBUTTONDBLCLK:
       case WM_MBUTTONUP:
+      case WM_XBUTTONDBLCLK:
+      case WM_XBUTTONDOWN:
+      case WM_XBUTTONUP:
       case WM_MOUSEMOVE:
       case WM_MOUSEWHEEL:
       case WM_AWT_MOUSEENTER:
@@ -1642,6 +1650,31 @@
               mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
                                MIDDLE_BUTTON);
               break;
+          case WM_XBUTTONDOWN:
+          case WM_XBUTTONDBLCLK:
+              if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
+                  if (HIWORD(wParam) == 1) {
+                      mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
+                                       X1_BUTTON);
+                  }
+                  if (HIWORD(wParam) == 2) {
+                      mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
+                                       X2_BUTTON);
+                  }
+              }
+              break;
+          case WM_XBUTTONUP:
+              if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
+                  if (HIWORD(wParam) == 1) {
+                      mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
+                                     X1_BUTTON);
+                  }
+                  if (HIWORD(wParam) == 2) {
+                      mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
+                                     X2_BUTTON);
+                  }
+              }
+              break;
           case WM_RBUTTONDOWN:
           case WM_RBUTTONDBLCLK:
               mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
@@ -2549,8 +2582,12 @@
         lastComp = this;
         lastX = x;
         lastY = y;
-
-        if ( (flags & ALL_MK_BUTTONS) != 0 ) {
+        BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled();
+        if (((flags & (ALL_MK_BUTTONS)) != 0) ||
+            (extraButtonsEnabled && (flags & (X_BUTTONS)) != 0))
+//        if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) ||
+//            ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) ))
+        {
             // 6404008 : if Dragged event fired we shouldn't fire
             // Clicked event: m_firstDragSent set to TRUE.
             // This is a partial backout of 5039416 fix.
@@ -2728,7 +2765,7 @@
         modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK;
     }
     if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) {
-        modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
+       modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
     }
     if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) {
         modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
@@ -2736,6 +2773,13 @@
     if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) {
         modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;
     }
+
+    if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) {
+        modifiers |= masks[3];
+    }
+    if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) {
+        modifiers |= masks[4];
+    }
     return modifiers;
 }
 
@@ -2750,6 +2794,11 @@
         return java_awt_event_MouseEvent_BUTTON2;
     case RIGHT_BUTTON:
         return java_awt_event_MouseEvent_BUTTON3;
+    case X1_BUTTON: //16 :
+        //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now
+        return 4;
+    case X2_BUTTON: //32
+        return 5;
     }
     return java_awt_event_MouseEvent_NOBUTTON;
 }
@@ -2764,6 +2813,10 @@
         return MK_MBUTTON;
     case RIGHT_BUTTON:
         return MK_RBUTTON;
+    case X1_BUTTON:
+        return MK_XBUTTON1;
+    case X2_BUTTON:
+        return MK_XBUTTON2;
     }
     return 0;
 }
@@ -2781,6 +2834,14 @@
 #define VK_NONCONVERT     0x1D
 #endif
 
+#ifndef VK_XBUTTON1
+#define VK_XBUTTON1      0x05
+#endif
+
+#ifndef VK_XBUTTON2
+#define VK_XBUTTON2      0x06
+#endif
+
 typedef struct {
     UINT javaKey;
     UINT windowsKey;
@@ -5068,7 +5129,12 @@
           if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) {
               wLow |= MK_MBUTTON;
           }
-
+          if (modifiers & X1_BUTTON) {
+              wLow |= GetButtonMK(X1_BUTTON);
+          }
+          if (modifiers & X2_BUTTON) {
+              wLow |= GetButtonMK(X2_BUTTON);
+          }
 
           wheelAmt = (jint)JNU_CallMethodByName(env,
                                                NULL,
@@ -6165,6 +6231,18 @@
 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
 {
     TRY;
+    jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");
+    jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");
+    jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);
+    jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);
+
+    jsize len = env->GetArrayLength(obj);
+    AwtComponent::masks = new jint[len];
+    for (int i = 0; i < len; i++) {
+        AwtComponent::masks[i] = tmp[i];
+    }
+    env->ReleaseIntArrayElements(obj, tmp, 0);
+    env->DeleteLocalRef(obj);
 
     /* class ids */
     jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer");
--- a/jdk/src/windows/native/sun/windows/awt_Component.h	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h	Tue Sep 16 12:17:02 2008 +0400
@@ -53,6 +53,22 @@
 #define MIDDLE_BUTTON 2
 #define RIGHT_BUTTON 4
 #define DBL_CLICK 8
+#define X1_BUTTON 16
+#define X2_BUTTON 32
+
+#ifndef MK_XBUTTON1
+#define MK_XBUTTON1         0x0020
+#endif
+
+#ifndef MK_XBUTTON2
+#define MK_XBUTTON2         0x0040
+#endif
+
+// combination of standard mouse button flags
+const int ALL_MK_BUTTONS = MK_LBUTTON|MK_MBUTTON|MK_RBUTTON;
+const int X_BUTTONS = MK_XBUTTON1|MK_XBUTTON2;
+
+
 
 // Whether to check for embedded frame and adjust location
 #define CHECK_EMBEDDED 0
@@ -81,11 +97,6 @@
 
 class AwtComponent : public AwtObject {
 public:
-    enum {
-        // combination of all mouse button flags
-        ALL_MK_BUTTONS = MK_LBUTTON|MK_MBUTTON|MK_RBUTTON
-    };
-
     /* java.awt.Component fields and method IDs */
     static jfieldID peerID;
     static jfieldID xID;
@@ -112,6 +123,7 @@
     static jmethodID replaceSurfaceDataLaterMID;
 
     static const UINT WmAwtIsComponent;
+    static jint * masks; //InputEvent mask array
     AwtComponent();
     virtual ~AwtComponent();
 
--- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp	Tue Sep 16 12:17:02 2008 +0400
@@ -31,8 +31,6 @@
 #include "java_awt_event_InputEvent.h"
 #include <winuser.h>
 
-static const int MOUSE_MAX = 65535;
-
 AwtRobot::AwtRobot( jobject peer )
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -103,19 +101,38 @@
     // left handed mouse setup
     BOOL bSwap = ::GetSystemMetrics(SM_SWAPBUTTON);
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+        buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK)
+    {
         dwFlags |= !bSwap ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
     }
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+         buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK)
+    {
         dwFlags |= !bSwap ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN;
     }
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+         buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK)
+    {
         dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
     }
 
-    mouse_event(dwFlags, 0, 0, 0, 0 );
+    INPUT mouseInput = {0};
+    mouseInput.type = INPUT_MOUSE;
+    mouseInput.mi.time = 0;
+    mouseInput.mi.dwFlags = dwFlags;
+    if ( buttonMask & AwtComponent::masks[3] ) {
+        mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XDOWN;
+        mouseInput.mi.mouseData = XBUTTON1;
+    }
+
+    if ( buttonMask & AwtComponent::masks[4] ) {
+        mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XDOWN;
+        mouseInput.mi.mouseData = XBUTTON2;
+    }
+    ::SendInput(1, &mouseInput, sizeof(mouseInput));
 }
 
 void AwtRobot::MouseRelease( jint buttonMask )
@@ -126,19 +143,39 @@
     // left handed mouse setup
     BOOL bSwap = ::GetSystemMetrics(SM_SWAPBUTTON);
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+        buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK)
+    {
         dwFlags |= !bSwap ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
     }
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+         buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK)
+    {
         dwFlags |= !bSwap ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP;
     }
 
-    if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ) {
+    if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+        buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK)
+    {
         dwFlags |= MOUSEEVENTF_MIDDLEUP;
     }
 
-    mouse_event(dwFlags, 0, 0, 0, 0 );
+    INPUT mouseInput = {0};
+    mouseInput.type = INPUT_MOUSE;
+    mouseInput.mi.time = 0;
+    mouseInput.mi.dwFlags = dwFlags;
+
+    if ( buttonMask & AwtComponent::masks[3] ) {
+        mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XUP;
+        mouseInput.mi.mouseData = XBUTTON1;
+    }
+
+    if ( buttonMask & AwtComponent::masks[4] ) {
+        mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XUP;
+        mouseInput.mi.mouseData = XBUTTON2;
+    }
+    ::SendInput(1, &mouseInput, sizeof(mouseInput));
 }
 
 void AwtRobot::MouseWheel (jint wheelAmt) {
@@ -400,3 +437,9 @@
 
     CATCH_BAD_ALLOC;
 }
+
+JNIEXPORT jint JNICALL Java_sun_awt_windows_WRobotPeer_getNumberOfButtons(
+  JNIEnv *, jobject self)
+{
+    return GetSystemMetrics(SM_CMOUSEBUTTONS);
+}
--- a/jdk/src/windows/native/sun/windows/awt_Robot.h	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Robot.h	Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,13 +42,13 @@
         void MouseRelease( jint buttonMask );
 
         void MouseWheel(jint wheelAmt);
+        jint getNumberOfButtons();
 
         jint GetRGBPixel( jint x, jint y);
         void GetRGBPixels(jint x, jint y, jint width, jint height, jintArray pixelArray);
 
         void KeyPress( jint key );
         void KeyRelease( jint key );
-
         static AwtRobot * GetRobot( jobject self );
 
     private:
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Tue Sep 16 12:17:02 2008 +0400
@@ -322,6 +322,7 @@
     m_vmSignalled = FALSE;
 
     m_isDynamicLayoutSet = FALSE;
+    m_areExtraMouseButtonsEnabled = TRUE;
 
     m_verifyComponents = FALSE;
     m_breakOnError = FALSE;
@@ -2092,3 +2093,26 @@
         splashClose();
     }
 }
+
+/*
+ * accessible from awt_Component
+ */
+BOOL AwtToolkit::areExtraMouseButtonsEnabled() {
+    return m_areExtraMouseButtonsEnabled;
+}
+
+/*
+ * Class:     sun_awt_windows_WToolkit
+ * Method:    setExtraMouseButtonsEnabledNative
+ * Signature: (Z)V
+ */
+extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative
+(JNIEnv *env, jclass self, jboolean enable){
+    TRY;
+    AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable);
+    CATCH_BAD_ALLOC;
+}
+
+void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) {
+    m_areExtraMouseButtonsEnabled = enable;
+}
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Tue Sep 16 12:17:02 2008 +0400
@@ -175,6 +175,8 @@
     BOOL IsDynamicLayoutSet();
     BOOL IsDynamicLayoutSupported();
     BOOL IsDynamicLayoutActive();
+    BOOL areExtraMouseButtonsEnabled();
+    void setExtraMouseButtonsEnabled(BOOL enable);
 
     INLINE BOOL localPump() { return m_localPump; }
     INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
@@ -351,6 +353,7 @@
     BOOL m_verbose;
     BOOL m_isActive; // set to FALSE at beginning of Dispose
     BOOL m_isDisposed; // set to TRUE at end of Dispose
+    BOOL m_areExtraMouseButtonsEnabled;
 
     BOOL m_vmSignalled; // set to TRUE if QUERYENDSESSION has successfully
                         // raised SIGTERM
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp	Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp	Tue Sep 16 12:17:02 2008 +0400
@@ -393,7 +393,7 @@
         lastX = x;
         lastY = y;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
-        if ((flags & AwtComponent::ALL_MK_BUTTONS) != 0) {
+        if ((flags & ALL_MK_BUTTONS) != 0) {
             m_mouseButtonClickAllowed = 0;
         } else {
             SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::windowsToUTC(::GetTickCount()), x, y,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,131 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that drag events are coming for every button if the property is set to true
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main ExtraButtonDrag
+ */
+
+//events from standard should also come
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class ExtraButtonDrag extends Frame {
+    static String tk = Toolkit.getDefaultToolkit().getClass().getName();
+    static Robot robot;
+    static int [] buttonsPressed;
+    static int [] buttonsReleased;
+    static int [] buttonsClicked;
+    volatile static boolean dragged = false;
+    volatile static boolean moved = false;
+
+    public ExtraButtonDrag(){
+        super("ExtraButtonDrag");
+    }
+
+    public static void main(String []s){
+        Frame frame = new ExtraButtonDrag();
+
+        MouseAdapter ma = new MouseAdapter() {
+                public void mouseDragged(MouseEvent e) {
+                    System.out.println("Dragged "+e);// +" : "+ e.getButton() + " : " +e.getButtonState(e.getButton()));
+                    dragged = true;
+                }
+                public void mouseMoved(MouseEvent e) {
+                    System.out.println("Moved "+e);
+                    moved = true;
+                }
+                public void mousePressed(MouseEvent e) {
+                    System.out.println(">>> "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    System.out.println(">>> "+e);
+                }
+
+            };
+
+        frame.addMouseMotionListener(ma);
+        frame.addMouseListener(ma);
+
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+
+        int [] buttonMask = new int [MouseInfo.getNumberOfButtons()]; //InputEvent.getButtonMasks();
+
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonMask[i] = InputEvent.getMaskForButton(i+1);
+            //            System.out.println("TEST: "+tmp[i]);
+        }
+
+        try {
+            robot = new Robot();
+            robot.delay(1000);
+            Point centerFrame = new Point(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+            Point outboundsFrame = new Point(frame.getLocationOnScreen().x + frame.getWidth()*3/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+            System.out.println("areExtraMouseButtonsEnabled() == " + Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() );
+
+            for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+                System.out.println("button to drag = " +(i+1) + " : value passed to robot = " +buttonMask[i]);
+
+                try {
+                    dragMouse(buttonMask[i], centerFrame.x, centerFrame.y, outboundsFrame.x, outboundsFrame.y);
+                } catch (IllegalArgumentException e){
+                    throw new RuntimeException("Test failed. Exception occured.", e);
+                }
+
+                robot.delay(500);
+                //this is a choice-case for X protocol issue: native events from extra buttons doesn't contain
+                // the correct state so it's unable to decide if there is a drag or move. By default we send MOVED event.
+                //XToolkit: extra buttons should report MOVED events only
+                //WToolkit: extra buttons should report DRAGGED events only
+                if (i > 2){ //extra buttons only
+                    if (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) {
+                        if (!moved || dragged) {
+                            throw new RuntimeException("Test failed."+ tk +" Button = " +(i+1) + " moved = "+moved +" : dragged = " +dragged);
+                        }
+                    } else { //WToolkit
+                        if (moved || !dragged) {
+                            throw new RuntimeException("Test failed."+ tk +" Button = " +(i+1) + " moved = "+moved +" : dragged = " +dragged);
+                        }
+                    }
+                } else {
+                    if (moved || !dragged){
+                        throw new RuntimeException("Test failed. Button = " +(i+1) + " not dragged.");
+                    }
+                }
+            }
+        } catch (Exception e){
+            throw new RuntimeException("", e);
+        }
+    }
+
+    public static void dragMouse(int button, int x0, int y0, int x1, int y1){
+        int curX = x0;
+        int curY = y0;
+        int dx = x0 < x1 ? 1 : -1;
+        int dy = y0 < y1 ? 1 : -1;
+        robot.mouseMove(x0, y0);
+
+        robot.delay(200);
+        dragged = false;
+        moved = false;
+
+        robot.mousePress(button);
+
+        while (curX != x1){
+            curX += dx;
+            robot.mouseMove(curX, curY);
+            robot.delay(5);
+        }
+        while (curY != y1 ){
+            curY += dy;
+            robot.mouseMove(curX, curY);
+            robot.delay(5);
+        }
+        robot.mouseRelease(button);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ModifierPermutation.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,320 @@
+/*
+  test %I% %E%
+  @bug 6315717
+  @summary presses buttons in all permutations and verifies modifiers
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main ModifierPermutation
+ */
+//package modifierpermutation;
+
+/*
+The test will try to press-release every button present on the mouse in different order.
+Here are some abbreviations:
+ BUTTON1 press = P1
+ BUTTON2 press = P2 etc.
+ BUTTON1 release = R1
+ BUTTON2 release = R2 etc.
+Only sequences alike below are possible : <P1, P2, R2, R1>.
+Sequences like <P1, P2, R1, R2> will not be covered by this test due to its probable complexity.
+ */
+
+import java.awt.*;
+import sun.awt.SunToolkit;
+import java.awt.event.*;
+import java.util.Arrays;
+
+public class ModifierPermutation {
+    static boolean failed = false;
+    final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons();
+
+/*
+ * Because of some problems with BUTTONx_MASK
+ * (they are not ordered. Instead, their values are: 16 8 4)
+ * We have to use array [1..n] and make every permutation on its
+ * containment. After each permutation, make the same thing with
+ * array of buttons and array of expected modifiers.
+ */
+    static SunToolkit st = (SunToolkit)(Toolkit.getDefaultToolkit());
+    //all button masks
+    static int [] mouseButtons = new int [BUTTONSNUMBER]; //BUTTONx_MASK
+    static int [] mouseButtonsDown = new int [BUTTONSNUMBER]; //BUTTONx_DOWN_MASK
+
+    //used to store mouse buttons sequences to press/to release
+    static int [] affectedButtonsToPressRelease;
+//    static int [] buttonsToRelease;
+//    static int [] modifiersToVerifyOnPressRelease;
+
+    static Robot robot;
+    static CheckingAdapter adapterTest1;
+    static Frame f;
+
+    static {
+        for (int i = 0; i < BUTTONSNUMBER; i++){
+            mouseButtons[i] = InputEvent.getMaskForButton(i+1); //then change first three elements here to BUTTONx_MASK
+            mouseButtonsDown[i] = InputEvent.getMaskForButton(i+1);
+        }
+        //mouseButtons initially has following values : 16 8 4.
+/*        mouseButtons[0] = InputEvent.BUTTON1_MASK;
+        mouseButtons[1] = InputEvent.BUTTON2_MASK;
+        mouseButtons[2] = InputEvent.BUTTON3_MASK;
+ */
+    }
+
+    public static void main(String s[]){
+        init();
+
+        try {
+            robot = new Robot();
+        } catch (Exception e){
+            e.printStackTrace();
+            throw new RuntimeException("Test failed.", e);
+        }
+        robot.delay(500);
+        robot.mouseMove(f.getLocationOnScreen().x + f.getWidth()/2, f.getLocationOnScreen().y + f.getHeight()/2);
+        robot.delay(500);
+        //Top limit is the factorial of the number of existing buttons
+        for (int k = 0; k < factorial(mouseButtons.length)-1; k++){
+            //now we will press 2 up to maximum buttons and release them in different order and listen for
+            // PRESSED events and check it's ExModifiers
+            for (int buttonsToPressNumber = 2; buttonsToPressNumber <= BUTTONSNUMBER; buttonsToPressNumber++ ){
+                System.out.println(">>>");
+
+                //Now get the slice of affected buttons
+                affectedButtonsToPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber);
+//                modifiersToVerifyOnPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber);
+
+                //Now press all these buttons in the order as they are in array affectedButtonsToPressRelease
+                //And release all these buttons in back order.
+
+                dumpArray("Affected Buttons ", affectedButtonsToPressRelease);
+                pressAllButtons(affectedButtonsToPressRelease);
+                releaseAllButtonsForwardOrder(affectedButtonsToPressRelease);
+//                    nextPermutation(i, buttonsToRelease);
+                //TODO: press buttons and release them backward
+                //All I have to add is :
+//                pressAllButtons(affectedButtonsToPressRelease);
+//                releaseAllButtonsBackwardOrder(affectedButtonsToPressRelease);
+
+                System.out.println("<<<");
+            }
+            nextPermutation(k, mouseButtons);
+//            PermutationGenerator.nextPermutation(k, mouseButtonsDown);
+            dumpArray("mouseButtons (step="+k+")", mouseButtons);
+//            dumpArray("mouseButtonsDown (step="+k+")", mouseButtonsDown);
+        }
+    }
+
+    private static void init(){
+        adapterTest1 = new CheckingAdapter();
+        f = new Frame("Robot presses mouse here");
+        f.setSize(300, 300);
+        f.setVisible(true);
+        f.addMouseListener(adapterTest1);
+    }
+    public static int factorial(int t){
+        if (t <=1 ) {
+            return 1;
+        } else {
+            return t*factorial(t-1);
+        }
+    }
+
+    // use this variable to get current button on EDT in checkModifiers()
+    static volatile int currentButtonIndexUnderAction;
+
+    public static void pressAllButtons(int []array){
+        for (int i = 0; i <array.length; i ++){
+            if (failed) {
+                throw new RuntimeException("PRESSED_EVENT is not filled with correct values. Review messaage above.");
+            }
+            System.out.println("Pressing button = " + array[i]);
+            currentButtonIndexUnderAction = i;
+            robot.mousePress(array[i]);
+            System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction);
+            st.realSync();
+            //            robot.delay(100);
+        }
+    }
+
+    public static void releaseAllButtonsForwardOrder(int []array){
+        for (int i = 0; i <array.length; i ++){
+            System.out.println("Releasing button = " + array[i]);
+            currentButtonIndexUnderAction = i;
+            robot.mouseRelease(array[i]);
+            System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction);
+            st.realSync();
+            //            robot.delay(100);
+        }
+    }
+
+    public static void checkModifiersOnPress(MouseEvent e){
+        System.out.println("checkModifiers. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction);
+        for (int i = 0; i<= currentButtonIndexUnderAction; i++){
+            if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){
+                System.out.println("ERROR["+i+"]: PRESSED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e);
+                ModifierPermutation.failed = true;
+            } else {
+                System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e);
+            }
+        }
+    }
+
+    /*======================================================================*/
+    public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){
+        System.out.println("Button = "+button + "Modifiers = "+ modifiers + " standard = "+ modifiersStandard);
+        System.out.println("                   ModifiersEx = "+ modifiersEx + " standardEx = "+ modifiersExStandard);
+    }
+
+    public static void dumpArray(String id, int [] array){
+        System.out.print(id);
+        for (int i = 0; i < array.length; i++){
+            System.out.print(array[i]+" ");
+        }
+        System.out.println();
+    }
+    public static void nextPermutation(int step, int []array){
+        int i;
+        int leftEl = 0;
+        int rightEl = 0;
+
+        i = array.length - 2;
+        while (i>=0) {
+            if (array[i] < array[i+1]){
+                leftEl = i;
+                //                        System.out.println("leftEl = "+leftEl);
+                break;
+            }
+            i--;
+        }
+
+        i = array.length - 1;
+        while (i>=0) {
+            if (array[i] > array[leftEl]) {
+                rightEl = i;
+                //                        System.out.println("rightEl = "+rightEl);
+                break;
+            }
+            i--;
+        }
+        swapElements(array, leftEl, rightEl);
+        if (leftEl + 2 <  array.length){
+            //                    System.out.println("sort");
+            Arrays.sort(array, leftEl + 1 , array.length);
+        }
+    }
+
+    public static void swapElements(int [] array, int leftEl, int rightEl){
+        int tmp = array[leftEl];
+        array[leftEl] = array[rightEl];
+        array[rightEl] = tmp;
+    }
+
+    public static void checkModifiersOnRelease(MouseEvent e){
+        System.out.println("CheckModifiersOnRelease. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction);
+        for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){
+            if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){
+                System.out.println("ERROR["+i+"]: RELEASED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e);
+                ModifierPermutation.failed = true;
+            } else {
+                System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e);
+            }
+        }
+    }
+
+    public static void checkModifiersOnClick(MouseEvent e){
+        System.out.println("CheckModifiersOnClick. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction);
+//Actually the same as in checkModifiersOnRelease()
+        for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){
+            if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){
+                System.out.println("ERROR["+i+"]: CLICK_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e);
+                ModifierPermutation.failed = true;
+            } else {
+                System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e);
+            }
+        }
+    }
+}
+///~ ModifierPermutation clas
+
+/* A class that invoke appropriate verification
+ * routine with current modifier.
+ */
+class CheckingAdapter extends MouseAdapter{
+    public CheckingAdapter(){}
+
+    public void mousePressed(MouseEvent e) {
+        System.out.println("PRESSED "+e);
+        ModifierPermutation.checkModifiersOnPress(e);
+    }
+    public void mouseReleased(MouseEvent e) {
+        System.out.println("RELEASED "+e);
+        ModifierPermutation.checkModifiersOnRelease(e);
+
+    }
+    public void mouseClicked(MouseEvent e) {
+        System.out.println("CLICKED "+e);
+        ModifierPermutation.checkModifiersOnClick(e);
+    }
+}
+
+// A class that could make a standard permutation with no regard to the
+// values of array passed in.
+// It uses a buttonIndicesToPermutate array with [1..N] values to perform
+// these permutations.
+//Note that nextPermutation is a static method and you can't keep track
+// of more the single permutation sequence.
+/*
+class PermutationGenerator{
+    final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons();
+    static int [] buttonIndicesToPermutate = new int [BUTTONSNUMBER];;
+    public PermutationGenerator(){
+        for (int i = 0; i < BUTTONSNUMBER; i++){
+            buttonIndicesToPermutate[i] = i+1; //fill it with [1..N] values
+        }
+    }
+
+    public static void nextPermutation(int step, int []array){
+        if (array.length != buttonIndicesToPermutate.length) {
+            throw new IllegalArgumentException("Array should have length equals to mouse buttons number.");
+        }
+        int i;
+        int leftEl = 0;
+        int rightEl = 0;
+
+        i = array.length - 2;
+        while (i>=0) {
+            if (buttonIndicesToPermutate[i] < buttonIndicesToPermutate[i+1]){
+                leftEl = i;
+                //                        System.out.println("leftEl = "+leftEl);
+                break;
+            }
+            i--;
+        }
+
+        i = array.length - 1;
+        while (i>=0) {
+            if (buttonIndicesToPermutate[i] >buttonIndicesToPermutate[leftEl]) {
+                rightEl = i;
+                //                        System.out.println("rightEl = "+rightEl);
+                break;
+            }
+            i--;
+        }
+        swapElements(array, leftEl, rightEl);
+        swapElements(buttonIndicesToPermutate, leftEl, rightEl);
+
+        if (leftEl + 2 <  array.length){
+            //                    System.out.println("sort");
+//need to make our own sorting because arraysort makes this on actual values in array...
+            Arrays.sort(array, leftEl + 1 , array.length);
+            Arrays.sort(buttonIndicesToPermutate, leftEl + 1 , buttonIndicesToPermutate.length);
+//            sortArray(array, leftEl + 1 , array.length);
+        }
+    }
+    public static void swapElements(int [] array, int leftEl, int rightEl){
+        int tmp = array[leftEl];
+        array[leftEl] = array[rightEl];
+        array[rightEl] = tmp;
+    }
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,490 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that modifiers are correct for extra buttons
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main MouseModifiersUnitTest_Extra
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+// will process extra buttons only
+// asking parameters from CMD: manual/automatic, modifier to test
+
+public class MouseModifiersUnitTest_Extra extends Frame {
+    static final int NONE = 0;
+    static final int SHIFT = 1;
+    static final int CTRL = 2;
+    static final int ALT = 3;
+    static CheckingModifierAdapter adapterTest1;
+    static CheckingModifierAdapter adapterTest2;
+    static CheckingModifierAdapter adapterTest3;
+    static CheckingModifierAdapter adapterTest4;
+
+    static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
+    static boolean autorun = false; //use robot or manual run
+    static int testModifier = NONE;
+
+    static int [] mouseButtons;
+    static int [] mouseButtonDownMasks;
+
+    //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
+    static int [] modifiersExStandard;
+    static int [] modifiersExStandardSHIFT;
+    static int [] modifiersExStandardCTRL;
+    static int [] modifiersExStandardALT;
+
+    //    final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
+    // BUTTON1, 2, 3 press-release.
+    final static int  modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
+
+    public static void checkPressedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 4)*3;
+        dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != modifiersStandard){
+            MessageLogger.reportError("Test failed :  Pressed. modifiers != modifiersStandard");
+        }
+
+        if (modifiersEx != curStandardExModifiers[index]){
+//            System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
+            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
+        }
+
+     //check event.paramString() output
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        System.out.println(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        checkExtModifiersOnPress(testModifier, paramStringElements, button);
+    }
+
+    public static void checkExtModifiersOnReleaseClick(int testModifier, HashMap h, int button){
+        String ethalon = "";
+        switch (testModifier){
+            case SHIFT:{
+                ethalon = "Shift";
+                break;
+            }
+            case ALT:{
+                ethalon = "Alt";
+                break;
+            }
+            case CTRL:{
+                ethalon = "Ctrl";
+                break;
+            }
+        }
+        //
+        if (h.get("extModifiers") == null){
+            h.put("extModifiers", "");
+        }
+        if (!ethalon.equals(h.get("extModifiers"))) {
+            MessageLogger.reportError("Test failed :  Released/Clicked. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
+        }
+    }
+
+    public static void checkExtModifiersOnPress(int testModifier, HashMap h, int button){
+        String ethalon = "";
+        switch (testModifier){
+            case SHIFT:{
+                ethalon = "Shift+";
+                break;
+            }
+            case ALT:{
+                ethalon = "Alt+";
+                break;
+            }
+            case CTRL:{
+                ethalon = "Ctrl+";
+                break;
+            }
+        }
+        ethalon = ethalon + "Button" +button;
+
+        if (!h.get("extModifiers").equals(ethalon)) {
+            MessageLogger.reportError("Test failed :  Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
+        }
+    }
+
+    public static void checkModifiers(int testModifier, HashMap<String, String> h, int button){
+        // none of modifiers for extra button should be null
+        if (h.get("modifiers") != null) {
+            MessageLogger.reportError("Test failed : modifiers != null");
+        }
+    }
+
+    public static void checkButton(HashMap<String, String> h, int button){
+        if (h.get("button") == null) {
+            MessageLogger.reportError("Test failed :  checkButton(). button is absent in paramString()");
+        }
+        if (Integer.parseInt(h.get("button")) != button) {
+            MessageLogger.reportError("Test failed :  checkButton. button in paramString() doesn't equal to button being pressed.");
+        }
+    }
+    public static HashMap<String, String> tokenizeParamString(String param){
+        HashMap <String, String> params = new HashMap<String, String>();
+        StringTokenizer st = new StringTokenizer(param, ",=");
+        while (st.hasMoreTokens()){
+            String tmp = st.nextToken();
+//            System.out.println("PARSER : "+tmp);
+            if (tmp.equals("button") ||
+                    tmp.equals("modifiers") ||
+                    tmp.equals("extModifiers")) {
+                params.put(tmp, st.nextToken());
+            }
+        }
+        return params;
+    }
+
+    public static Vector<String> tokenizeModifiers(String modifierList){
+        Vector<String> modifiers = new Vector<String>();
+        StringTokenizer st = new StringTokenizer(modifierList, "+");
+        while (st.hasMoreTokens()){
+            String tmp = st.nextToken();
+            modifiers.addElement(tmp);
+            System.out.println("MODIFIER PARSER : "+tmp);
+        }
+        return modifiers;
+    }
+
+    public static void checkReleasedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 4)*3 + 1;
+        dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != modifiersStandard){
+            MessageLogger.reportError("Test failed :  Released. modifiers != modifiersStandard");
+        }
+
+        if (modifiersEx != curStandardExModifiers[index]){
+            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers");
+        }
+
+     //check event.paramString() output
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        System.out.println("paramStringElements = "+paramStringElements);
+        checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
+    }
+
+    public static void checkClickedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 4)*3 + 2;
+        dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != modifiersStandard){
+            MessageLogger.reportError("Test failed :  Clicked. modifiers != modifiersStandard");
+        }
+
+        if (modifiersEx != curStandardExModifiers[index]){
+            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
+        }
+
+     //check event.paramString() output
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
+    }
+
+    private static int[] getStandardExArray(int testModifier) {
+        int [] curStandardExModifiers;
+        switch (testModifier){
+            case SHIFT:
+                curStandardExModifiers = modifiersExStandardSHIFT;
+                break;
+            case CTRL:
+                curStandardExModifiers = modifiersExStandardCTRL;
+                break;
+            case ALT:
+                curStandardExModifiers = modifiersExStandardALT;
+                break;
+            default: //NONE by default
+                curStandardExModifiers = modifiersExStandard;
+        }
+        return curStandardExModifiers;
+    }
+
+    static Robot robot;
+    public void init() {
+        this.setLayout(new BorderLayout());
+
+        String[] instructions =
+        {
+            "This test should be used with the mouse having more then three buttons.",
+            "Currently, " + MouseInfo.getNumberOfButtons() +" buttons are available.",
+            "If there are less then three buttons, press PASS.",
+            "1. Press each extra mouse button.",
+            "2. For each mouse event its modifiers and ExModifiers will be printed.",
+            "3. Verify that they are correct.",
+            "4. Press Pass or Fail accordingly."
+        };
+//        Sysout.createDialogWithInstructions( instructions );
+
+//        addMouseListener(adapterTest1);
+        try {
+            robot  = new Robot();
+        } catch (Exception e) {
+            MessageLogger.reportError("Test failed. "+e);
+        }
+    }//End  init()
+
+    public void start() {
+        //Get things going.  Request focus, set size, et cetera
+        setSize(200,200);
+        setVisible(true);
+        validate();
+        if (autorun) {
+            testNONE();
+            testSHIFT();
+            testCTRL();
+            testALT();
+        } else {
+            switch (testModifier){
+                case SHIFT:
+                    this.addMouseListener(adapterTest2);
+                    break;
+                case CTRL:
+                    this.addMouseListener(adapterTest3);
+                    break;
+                case ALT:
+                    this.addMouseListener(adapterTest4);
+                    break;
+                default:  //NONE by default
+                    this.addMouseListener(adapterTest1);
+            }
+        }
+    }// start()
+
+    //000000000000000000000000000000000000000000000000000000000000000
+    public void testNONE(){
+        this.addMouseListener(adapterTest1);
+        robot.delay(1000);
+        robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
+        for (int i = 3; i< mouseButtons.length; i++){
+            System.out.println("testNONE() => " +mouseButtons[i] );
+            robot.mousePress(mouseButtons[i]);
+            robot.delay(100);
+            robot.mouseRelease(mouseButtons[i]);
+        }
+        robot.delay(1000);
+        this.removeMouseListener(adapterTest1);
+    }
+
+    public void testSHIFT(){
+        this.addMouseListener(adapterTest2);
+        robot.delay(1000);
+        robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
+        for (int i = 3; i< mouseButtons.length; i++){
+            robot.keyPress(KeyEvent.VK_SHIFT);
+            System.out.println("testSHIFT() => " +mouseButtons[i] );
+            robot.mousePress(mouseButtons[i]);
+            robot.delay(100);
+            robot.mouseRelease(mouseButtons[i]);
+            robot.keyRelease(KeyEvent.VK_SHIFT);
+        }
+        robot.delay(1000);
+        this.removeMouseListener(adapterTest2);
+    }
+
+    public void testCTRL(){
+        this.addMouseListener(adapterTest3);
+        robot.delay(1000);
+        robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
+        for (int i = 3; i< mouseButtons.length; i++){
+            robot.keyPress(KeyEvent.VK_CONTROL);
+            System.out.println("testCTRL() => " +mouseButtons[i] );
+            robot.mousePress(mouseButtons[i]);
+            robot.delay(100);
+            robot.mouseRelease(mouseButtons[i]);
+            robot.keyRelease(KeyEvent.VK_CONTROL);
+        }
+        robot.delay(1000);
+        this.removeMouseListener(adapterTest3);
+    }
+
+    public void testALT(){
+        this.addMouseListener(adapterTest4);
+        robot.delay(1000);
+        robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
+        for (int i = 3; i< mouseButtons.length; i++){
+            robot.keyPress(KeyEvent.VK_ALT);
+            System.out.println("testALT() => " +mouseButtons[i] );
+            robot.mousePress(mouseButtons[i]);
+            robot.delay(100);
+            robot.mouseRelease(mouseButtons[i]);
+            robot.keyRelease(KeyEvent.VK_ALT);
+        }
+        robot.delay(1000);
+        this.removeMouseListener(adapterTest4);
+    }
+
+    //**************************************************************************************************
+    public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){
+        System.out.println("Button = "+button + "Modifiers = "+ modifiers + "standard = "+ modifiersStandard);
+        System.out.println("Button = "+button + "ModifiersEx = "+ modifiersEx + "standardEx = "+ modifiersExStandard);
+    }
+
+    public static void initParams(String []s){
+        if (s.length != 3){
+            autorun = true;
+            debug = false;
+            testModifier = NONE;
+        } else {
+            autorun = Boolean.valueOf(s[0]);
+            debug = Boolean.valueOf(s[1]);
+
+            if (s[2].equals("NONE")){
+                testModifier = NONE;
+            }
+            if (s[2].equals("SHIFT")){
+                testModifier = SHIFT;
+            }
+            if (s[2].equals("CTRL")){
+                testModifier = CTRL;
+            }
+            if (s[2].equals("ALT")){
+                testModifier = ALT;
+            }
+        }
+        MessageLogger.setDebug(debug);
+        System.out.println("Autorun : " +autorun);
+        System.out.println("Debug mode : " +debug);
+        System.out.println("Modifier to verify : " + testModifier);
+    }
+
+    public static void initAdapters(){
+        adapterTest1 = new CheckingModifierAdapter(NONE);
+        adapterTest2 = new CheckingModifierAdapter(SHIFT);
+        adapterTest3 = new CheckingModifierAdapter(CTRL);
+        adapterTest4 = new CheckingModifierAdapter(ALT);
+    }
+
+    public static void initVars(){
+        int [] tmp = new int [MouseInfo.getNumberOfButtons()];
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            tmp[i] = InputEvent.getMaskForButton(i+1);
+            //            System.out.println("TEST: "+tmp[i]);
+        }
+
+        mouseButtons = Arrays.copyOf(tmp, tmp.length);
+
+        for (int i = 0; i < mouseButtons.length; i++){
+            System.out.println("MouseArray [i] == "+mouseButtons[i]);
+        }
+
+        mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
+
+        // So we need to get the number of extra buttons on the mouse:  "MouseInfo.getNumberOfButtons() - 3"
+        // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
+        tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
+        Arrays.fill(tmp, 0);
+
+        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
+            tmp[i] = mouseButtonDownMasks[j];
+        }
+        modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
+
+        Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
+        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        }
+        modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
+
+        Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
+        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        }
+        modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
+
+        Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
+        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        }
+        modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
+    }
+
+    public static void main(String []s){
+        if (MouseInfo.getNumberOfButtons() < 4){
+            System.out.println("There are less then 4 buttons on the mouse. The test may not be accomplished. Skipping.");
+            return;
+        }
+        initVars();
+        MouseModifiersUnitTest_Extra frame = new MouseModifiersUnitTest_Extra();
+        frame.initParams(s);
+        frame.init();
+        initAdapters();
+        frame.start();
+    }
+
+}// class
+
+/* A class that invoke appropriate verification
+ * routine with current modifier.
+ */
+class CheckingModifierAdapter extends MouseAdapter{
+    int modifier;
+    public CheckingModifierAdapter(int modifier){
+        this.modifier = modifier;
+    }
+
+    public void mousePressed(MouseEvent e) {
+        System.out.println("PRESSED "+e);
+        if (e.getButton() <= MouseEvent.BUTTON3) {
+            System.out.println("Standard button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Extra.checkPressedModifiersTest(modifier, e);
+        }
+    }
+    public void mouseReleased(MouseEvent e) {
+        System.out.println("RELEASED "+e);
+        if (e.getButton() <= MouseEvent.BUTTON3) {
+            System.out.println("Standard button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Extra.checkReleasedModifiersTest(modifier, e);
+        }
+    }
+    public void mouseClicked(MouseEvent e) {
+        System.out.println("CLICKED "+e);
+        if (e.getButton() <= MouseEvent.BUTTON3) {
+            System.out.println("Standard button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Extra.checkClickedModifiersTest(modifier, e);
+        }
+    }
+}
+//Utility class that could report a message depending on current purpose of the test run
+class MessageLogger{
+    private static boolean debug;
+
+    public static void setDebug(boolean d){
+        debug = d;
+        log("Switch to "+ ((debug)?"debug":"trial") +" mode");
+    }
+
+    public static void log(String message){
+        System.out.println(message);
+    }
+
+    public static void reportError(String message){
+        if (debug){
+            System.out.println(message);
+        } else {
+            throw new RuntimeException(message);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,598 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that modifiers are correct for standard (1, 2, 3, wheel) mouse buttons
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main MouseModifiersUnitTest_Standard
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+//the test verifies:
+// 1) verifies that modifiers are correct for standard (1, 2, 3) mouse buttons
+// TODO: 2) verifies that modifiers are correct for wheel
+// TODO: 3)
+// Case1. the test posts BUTTONx_MASK and verifies that paramString() contains correct modifiers and exModifiers
+// Case2. the test posts BUTTONx_DOWN_MASK and verifies that paramString() contains correct modifiers and exModifiers
+// Case3. the test posts getMaskForButton(n) and verifies that paramString() contains correct modifiers and exModifiers
+// repeat all cases with SHIFT/ALT/CTRL modifiers verify that paramString() contains correct modifiers and exModifiers
+// I'm verifying button, modifiers and extModifiers for now.
+
+public class MouseModifiersUnitTest_Standard {
+    static final int NONE = 0;
+    static final int SHIFT = 1;
+    static final int CTRL = 2;
+    static final int ALT = 3;
+    static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
+    static boolean autorun = false; //use robot or manual run
+    static int testModifier = NONE;
+    //    static String testModifier = "NONE";
+    static CheckingModifierAdapter adapterTest1;
+    static CheckingModifierAdapter adapterTest2;
+    static CheckingModifierAdapter adapterTest3;
+    static CheckingModifierAdapter adapterTest4;
+    static Frame f;
+    final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
+    // BUTTON1, 2, 3 press-release.
+    final static int [] modifiersStandardTestNONE = new int[] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON1_MASK,
+    MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON2_MASK,
+    MouseEvent.BUTTON3_MASK, MouseEvent.BUTTON3_MASK, MouseEvent.BUTTON3_MASK };
+    final static int [] modifiersExStandardTestNONE = new int[] {MouseEvent.BUTTON1_DOWN_MASK, 0, 0,
+    MouseEvent.BUTTON2_DOWN_MASK, 0, 0,
+    MouseEvent.BUTTON3_DOWN_MASK, 0, 0};
+    // BUTTON1, 2, 3 press-release with shift modifier
+    final static int [] modifiersStandardTestSHIFT = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK,
+    MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK,
+    MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK };
+    final static int [] modifiersExStandardTestSHIFT = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK,
+    MouseEvent.BUTTON2_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK,
+    MouseEvent.BUTTON3_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK};
+    // BUTTON1, 2, 3 press-release with CTRL modifier
+    final static int [] modifiersStandardTestCTRL = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK,
+    MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK,
+    MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK };
+    final static int [] modifiersExStandardTestCTRL = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK,
+    MouseEvent.BUTTON2_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK,
+    MouseEvent.BUTTON3_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK};
+
+    // BUTTON1, 2, 3 press-release with ALT modifier
+    final static int [] modifiersStandardTestALT = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK,
+    MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK,
+    MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK };
+    final static int [] modifiersExStandardTestALT = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK,
+    MouseEvent.BUTTON2_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK,
+    MouseEvent.BUTTON3_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK};
+
+    static Robot robot;
+
+    public static void main(String s[]){
+        initParams(s);
+        initAdapters();
+        f = new Frame();
+        final int [] modifiers = {InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK};
+        final String [] modifierNames = {"InputEvent.SHIFT_MASK", "InputEvent.CTRL_MASK"};
+        f.setLayout(new FlowLayout());
+        f.addMouseWheelListener(new MouseWheelListener() {
+            public void mouseWheelMoved(MouseWheelEvent e) {
+                System.out.println("WHEEL "+e);
+            }
+        });
+        f.setSize(300, 300);
+        f.setVisible(true);
+
+        try {
+            robot = new Robot();
+            robot.delay(500);
+            robot.mouseMove(f.getLocationOnScreen().x + f.getWidth()/2, f.getLocationOnScreen().y + f.getHeight()/2);
+            if (autorun) {
+                //testing buttons 1, 2, 3 only
+                testPlainButtons();
+                robot.delay(500);
+
+                //testing buttons 1, 2, 3 with SHIFT, CTRL, ALT keyboard modifiers
+                testButtonsWithShift();
+                robot.delay(500);
+
+                testButtonsWithControl();
+                robot.delay(500);
+
+                testButtonsWithAlt();
+                robot.delay(500);
+            } else {
+                switch (testModifier){
+                    case SHIFT:
+                        f.addMouseListener(adapterTest2);
+                        break;
+                    case CTRL:
+                        f.addMouseListener(adapterTest3);
+                        break;
+                    case ALT:
+                        f.addMouseListener(adapterTest4);
+                        break;
+                    default:  //NONE inclusive
+                        f.addMouseListener(adapterTest1);
+                }
+            }
+        } catch (Exception e){
+            throw new RuntimeException("Test failed.");
+        }
+
+    }
+
+    public static void initAdapters(){
+        adapterTest1 = new CheckingModifierAdapter(NONE);
+        adapterTest2 = new CheckingModifierAdapter(SHIFT);
+        adapterTest3 = new CheckingModifierAdapter(CTRL);
+        adapterTest4 = new CheckingModifierAdapter(ALT);
+    }
+
+    /*======================================================================*/
+    public static void checkPressedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardModifiers = getStandardArray(testModifier);
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 1)*3;
+        //        int index = (button - 4)*3;
+        dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != curStandardModifiers[index]){
+            if (debug){
+                System.out.println("Test failed :  Pressed. modifiers != modifiersStandard");
+            } else {
+                throw new RuntimeException("Test failed :  Pressed. modifiers != modifiersStandard");
+            }
+        }
+
+        if (modifiersEx != curStandardExModifiers[index]){
+//            System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
+            if (debug){
+                System.out.println("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
+            } else {
+                throw new RuntimeException("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
+            }
+        }
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        System.out.println(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        checkExtModifiersOnPress(testModifier, paramStringElements, button);
+    }
+
+    public static void checkButton(HashMap<String, String> h, int button){
+        if (h.get("button") == null) {
+            throw new RuntimeException("Test failed :  Clicked. button is absent in paramString()");
+        }
+        if (Integer.parseInt(h.get("button")) != button) {
+            throw new RuntimeException("Test failed :  Clicked. button in paramString() doesn't equal to button being pressed.");
+        }
+    }
+
+    public static void checkExtModifiersOnPress(int testModifier, HashMap h, int button){
+        String ethalon = "";
+        if (h.get("extModifiers") == null) {
+            System.out.println("Test failed :  Pressed. extModifiers == null");
+            throw new RuntimeException("Test failed :  Pressed. extModifiers == null");
+        }
+        switch (testModifier){
+            case SHIFT:{
+                ethalon = "Shift+";
+                break;
+            }
+            case ALT:{
+                ethalon = "Alt+";
+                break;
+            }
+            case CTRL:{
+                ethalon = "Ctrl+";
+                break;
+            }
+            default: {
+                ethalon = "";
+            }
+            ethalon = ethalon + "Button" +button;
+
+            if (!h.get("extModifiers").equals(ethalon)) {
+                System.out.println("Test failed :  Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
+                throw new RuntimeException("Test failed :  Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
+            }
+        }
+    }
+
+
+
+    public static void checkModifiers(int testModifier, HashMap<String, String> h, int button){
+        // none of modifiers should be null
+        if (h.get("modifiers") == null) {
+            System.out.println("Test failed : modifiers == null");
+            throw new RuntimeException("Test failed :  modifiers == null");
+        }
+        Vector <String> modifierElements = tokenizeModifiers(h.get("modifiers"));
+        //check that ButtonX is there
+        String buttonEthalon = "Button" + button;
+        if (modifierElements.contains(buttonEthalon)){
+            modifierElements.remove(buttonEthalon);
+        } else {
+            System.out.println("Test failed :  modifiers doesn't contain Button "+h.get("modifiers"));
+            throw new RuntimeException("Test failed :  modifiers doesn't contain Button "+h.get("modifiers"));
+        }
+
+
+        //Check all explicitly pressed modifires
+//        boolean altIncluded = false; //don't duplicate Alt when ALT is pressed and BUTTON2_MASK.
+        String excplicitModifier = "";
+        boolean altIncluded = false;
+        switch (testModifier){
+            case SHIFT:{
+                excplicitModifier = "Shift";
+                break;
+            }
+            case ALT:{
+                excplicitModifier = "Alt";
+                altIncluded = true; //there should be only on "Alt" for two modifiers. So check it.
+                break;
+            }
+            case CTRL:{
+                excplicitModifier = "Ctrl";
+                break;
+            }
+        }
+        if (!excplicitModifier.equals("")){
+            if (modifierElements.contains(excplicitModifier)){
+                modifierElements.remove(excplicitModifier);
+            } else {
+                System.out.println("Test failed :  modifiers doesn't contain explicit modifier "+excplicitModifier + " in "+ h.get("modifiers"));
+                throw new RuntimeException("Test failed :  modifiers doesn't contain explicit modifier "+excplicitModifier + " in "+ h.get("modifiers"));
+            }
+        }
+
+        //Button 2 and 3 reports about Alt+Button2 and Meta+Button3 respectively.
+        //Check these values too
+        String extraModifiers = "";
+        String extraModifiersButton3 = "";
+        switch (button){
+            //BUTTON1 with ALT reports about Alt+Button1+Button2.
+            //We should fix this but I would not change this.
+            case 1: {
+                //Alt+Button1+Button2:
+                // 1) we already handled "Alt" in excplicitModifier
+                // 2) we already took "Button1" in buttonEthalon
+                // 3) so "Button2" is only remained.
+                // This should only happen when ALT+Button1 is pressed
+                if (altIncluded){
+                    extraModifiers = "Button2";
+                }
+                break;
+            }
+            case 2: {
+                //Alt+Button2 report about "Alt+Button2".
+                extraModifiers = "Alt";
+                break;
+            }
+            case 3: {
+                //ALT+BUTTON3 reports about "Alt+Meta+Button2+Button3"
+                // This should only happen when ALT+Button3 is pressed
+                extraModifiers = "Meta";
+                if (altIncluded){
+                    extraModifiersButton3 = "Button2";
+                }
+                break;
+            }
+        }//switch
+
+        if (!extraModifiers.equals("")){
+            if (modifierElements.contains(extraModifiers)){
+                modifierElements.remove(extraModifiers);
+            } else {
+                //we may already removed "Alt" when filtered explicit modifiers.
+                //Here is no failure in this case.
+                if (!altIncluded) {
+                    System.out.println("Test failed :  modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiers + " in "+ h.get("modifiers"));
+                    throw new RuntimeException("Test failed :  modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiers + " in "+ h.get("modifiers"));
+                }
+            }
+        }
+
+        if (!extraModifiersButton3.equals("")){
+            if (modifierElements.contains(extraModifiersButton3)){
+                modifierElements.remove(extraModifiersButton3);
+            } else {
+                System.out.println("Test failed :  modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiersButton3 + " in "+ h.get("modifiers"));
+                throw new RuntimeException("Test failed :  modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiersButton3 + " in "+ h.get("modifiers"));
+            }
+        }
+
+        //the length of vector should now be zero
+        if (!modifierElements.isEmpty()){
+            System.out.println("Test failed :  there is some more elements in modifiers that shouldn't be there: "+h.get("modifiers"));
+            throw new RuntimeException("Test failed :  there is some more elements in modifiers that shouldn't be there: "+h.get("modifiers"));
+        }
+    }
+
+    public static void checkExtModifiersOnReleaseClick(int testModifier, HashMap h, int button){
+        String ethalon = "";
+        switch (testModifier){
+            case SHIFT:{
+                ethalon = "Shift+";
+                break;
+            }
+            case ALT:{
+                ethalon = "Alt+";
+                break;
+            }
+            case CTRL:{
+                ethalon = "Ctrl+";
+                break;
+            }
+            default: {
+                if (h.get("extModifiers") != null) {
+                    System.out.println("Test failed :  Released. extModifiers != null but no modifiers keys are pressed");
+                    throw new RuntimeException("Test failed :  Released. extModifiers != null but no modifiers keys are pressed");
+                } else {
+                    //no modifiers
+                    return;
+                }
+            }
+        }
+        if (h.get("extModifiers").equals(ethalon)) {
+            System.out.println("Test failed :  Released. extModifiers = "+ h.get("extModifiers") +" instead of : "+ethalon);
+            throw new RuntimeException("Test failed :  Released. extModifiers = "+ h.get("extModifiers") +" instead of : "+ethalon);
+        }
+    }
+
+    public static void checkReleasedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardModifiers = getStandardArray(testModifier);
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        //        int index = (button - 4)*3 + 1;
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 1)*3 + 1;
+        dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != curStandardModifiers[index]){
+            if (debug){
+                System.out.println("Test failed :  Released. modifiers != modifiersStandard");
+            } else {
+                throw new RuntimeException("Test failed :  Released. modifiers != modifiersStandard");
+            }
+        }
+        if (modifiersEx != curStandardExModifiers[index]){
+            if (debug){
+                System.out.println("Test failed :  Released. modifiersEx != curStandardExModifiers");
+            } else {
+                throw new RuntimeException("Test failed :  Released. modifiersEx != curStandardExModifiers");
+            }
+        }
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        System.out.println(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
+    }
+
+    public static void checkClickedModifiersTest(int testModifier, MouseEvent event){
+        int [] curStandardModifiers = getStandardArray(testModifier);
+        int [] curStandardExModifiers = getStandardExArray(testModifier);
+        //        int index = (button - 4)*3 + 2;
+        int button = event.getButton();
+        int modifiers = event.getModifiers();
+        int modifiersEx = event.getModifiersEx();
+        int index = (button - 1)*3 + 2;
+        dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
+        if (modifiers != curStandardModifiers[index]){
+            if (debug){
+                System.out.println("Test failed :  Clicked. modifiers != modifiersStandard");
+            } else {
+                throw new RuntimeException("Test failed :  Clicked. modifiers != modifiersStandard");
+            }
+        }
+        if (modifiersEx != curStandardExModifiers[index]){
+            if (debug){
+                System.out.println("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
+            } else {
+                throw new RuntimeException("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
+            }
+        }
+        HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
+        checkButton(paramStringElements, button);
+        checkModifiers(testModifier, paramStringElements, button);
+        checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
+    }
+    /*======================================================================*/
+
+    public static HashMap<String, String> tokenizeParamString(String param){
+        HashMap <String, String> params = new HashMap<String, String>();
+        StringTokenizer st = new StringTokenizer(param, ",=");
+        while (st.hasMoreTokens()){
+            String tmp = st.nextToken();
+//            System.out.println("PARSER : "+tmp);
+            if (tmp.equals("button") ||
+                    tmp.equals("modifiers") ||
+                    tmp.equals("extModifiers")) {
+                params.put(tmp, st.nextToken());
+            }
+        }
+        return params;
+    }
+
+    public static Vector<String> tokenizeModifiers(String modifierList){
+        Vector<String> modifiers = new Vector<String>();
+        StringTokenizer st = new StringTokenizer(modifierList, "+");
+        while (st.hasMoreTokens()){
+            String tmp = st.nextToken();
+            modifiers.addElement(tmp);
+            System.out.println("MODIFIER PARSER : "+tmp);
+        }
+        return modifiers;
+    }
+
+
+    //test BUTTON1, 2 and 3 without any modifiers keys
+    public static void  testPlainButtons(){
+        System.out.println("Testing buttons without modifiers.");
+        f.addMouseListener(adapterTest1);
+        for (int button : mouseButtons){
+            robot.mousePress(button);
+            robot.delay(100);
+            robot.mouseRelease(button);
+        }
+        robot.delay(1000);
+        f.removeMouseListener(adapterTest1);
+    }
+
+    //test BUTTON1, 2 and 3 with SHIFT key
+    public static void  testButtonsWithShift(){
+        System.out.println("Testing buttons with SHIFT modifier.");
+        f.addMouseListener(adapterTest2);
+
+        for (int button : mouseButtons){
+            robot.keyPress(KeyEvent.VK_SHIFT);
+            robot.mousePress(button);
+            robot.delay(100);
+            robot.mouseRelease(button);
+            robot.keyRelease(KeyEvent.VK_SHIFT);
+        }
+        robot.delay(1000);
+        f.removeMouseListener(adapterTest2);
+    }
+
+    //test BUTTON1, 2 and 3 with CTRL key
+    public static void  testButtonsWithControl(){
+        System.out.println("Testing buttons with CONTROL modifier.");
+        f.addMouseListener(adapterTest3);
+        for (int button : mouseButtons){
+            robot.keyPress(KeyEvent.VK_CONTROL);
+            robot.mousePress(button);
+            robot.delay(100);
+            robot.mouseRelease(button);
+            robot.keyRelease(KeyEvent.VK_CONTROL);
+        }
+        robot.delay(1000);
+        f.removeMouseListener(adapterTest3);
+    }
+
+    //test BUTTON1, 2 and 3 with ALT key
+    public static void  testButtonsWithAlt(){
+        System.out.println("Testing buttons with ALT modifier.");
+        f.addMouseListener(adapterTest4);
+        for (int button : mouseButtons){
+            robot.keyPress(KeyEvent.VK_ALT);
+            robot.mousePress(button);
+            robot.delay(100);
+            robot.mouseRelease(button);
+            robot.keyRelease(KeyEvent.VK_ALT);
+        }
+        robot.delay(1000);
+        f.removeMouseListener(adapterTest4);
+    }
+
+    public static void initParams(String []s){
+        if (s.length != 3){
+            autorun = true;
+            debug = false;
+            testModifier = NONE;
+        } else {
+            autorun = Boolean.valueOf(s[0]);
+            debug = Boolean.valueOf(s[1]);
+
+            if (s[2].equals("NONE")){
+                testModifier = NONE;
+            }
+            if (s[2].equals("SHIFT")){
+                testModifier = SHIFT;
+            }
+            if (s[2].equals("CTRL")){
+                testModifier = CTRL;
+            }
+            if (s[2].equals("ALT")){
+                testModifier = ALT;
+            }
+        }
+        System.out.println("Autorun : " +autorun);
+        System.out.println("Debug mode : " +debug);
+        System.out.println("Modifier to verify : " + testModifier);
+    }
+
+    public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){
+        System.out.println("Button = "+button + "Modifiers = "+ modifiers + " standard = "+ modifiersStandard);
+        System.out.println("                   ModifiersEx = "+ modifiersEx + " standardEx = "+ modifiersExStandard);
+    }
+
+    private static int[] getStandardExArray(int testModifier) {
+        int [] curStandardExModifiers;
+        switch (testModifier){
+            case SHIFT:
+                curStandardExModifiers = modifiersExStandardTestSHIFT;
+                break;
+            case CTRL:
+                curStandardExModifiers = modifiersExStandardTestCTRL;
+                break;
+            case ALT:
+                curStandardExModifiers = modifiersExStandardTestALT;
+                break;
+            default: //NONE by default
+                curStandardExModifiers = modifiersExStandardTestNONE;
+        }
+        return curStandardExModifiers;
+    }
+
+    private static int[] getStandardArray(int testModifier) {
+        int [] curStandardModifiers;
+        switch (testModifier){
+            case SHIFT:
+                curStandardModifiers = modifiersStandardTestSHIFT;
+                break;
+            case CTRL:
+                curStandardModifiers = modifiersStandardTestCTRL;
+                break;
+            case ALT:
+                curStandardModifiers = modifiersStandardTestALT;
+                break;
+            default: //NONE by default
+                curStandardModifiers = modifiersStandardTestNONE;
+        }
+        return curStandardModifiers;
+    }
+
+}
+
+
+/* A class that invoke appropriate verification
+ * routine with current modifier.
+ */
+class CheckingModifierAdapter extends MouseAdapter{
+    int modifier;
+    public CheckingModifierAdapter(int modifier){
+        this.modifier = modifier;
+    }
+
+    public void mousePressed(MouseEvent e) {
+        System.out.println("PRESSED "+e);
+        if (e.getButton() > MouseEvent.BUTTON3) {
+            System.out.println("Extra button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Standard.checkPressedModifiersTest(modifier, e); // e.getButton(), e.getModifiers(), e.getModifiersEx(),
+        }
+    }
+    public void mouseReleased(MouseEvent e) {
+        System.out.println("RELEASED "+e);
+        if (e.getButton() > MouseEvent.BUTTON3) {
+            System.out.println("Extra button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Standard.checkReleasedModifiersTest(modifier, e); // e.getButton(), e.getModifiers(), e.getModifiersEx()
+        }
+    }
+    public void mouseClicked(MouseEvent e) {
+        System.out.println("CLICKED "+e);
+        if (e.getButton() > MouseEvent.BUTTON3) {
+            System.out.println("Extra button affected. Skip.");
+        } else {
+            MouseModifiersUnitTest_Standard.checkClickedModifiersTest(modifier, e); //e.getButton(), e.getModifiers(), e.getModifiersEx()
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,118 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that Robot is accepting extra mouse buttons
+  @author Andrei Dmitriev : area=awt.mouse
+  @library ../../regtesthelpers
+  @build Util
+  @run main AcceptExtraMouseButtons
+ */
+
+//if we do robot.mousePress(InputEvent.BUTTON1_DOWN_MASK) the test must
+// 1) accept it (i.e. don't throw an IllegalArgumentException
+// 2) actually post a MouseEvent
+// Also, Robot should still accept InputEvent.BUTTONx_MASKs
+
+import java.awt.*;
+import java.awt.event.*;
+import sun.awt.SunToolkit;
+import test.java.awt.regtesthelpers.Util;
+
+public class AcceptExtraMouseButtons extends Frame {
+    static String tk = Toolkit.getDefaultToolkit().getClass().getName();
+    static Robot robot;
+    static int [] standardButtonMasks = {InputEvent.BUTTON1_MASK,
+                                         InputEvent.BUTTON2_MASK,
+                                         InputEvent.BUTTON3_MASK};
+    static int [] buttonsPressed;
+    static int [] buttonsReleased;
+    static int [] buttonsClicked;
+
+    static int buttonsNum = MouseInfo.getNumberOfButtons();
+
+    public static void main(String []s){
+
+        //MouseInfo.getNumberOfButtons() reports two more buttons on XToolkit
+        //as they reserved for wheel (both directions).
+        if (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) {
+            buttonsNum = buttonsNum - 2;
+        }
+        System.out.println("Number Of Buttons = "+ buttonsNum);
+        if (buttonsNum < 3) {
+            System.out.println("Linux and Windows systems should emulate three buttons if even there are only 1 or 2 are phsically available. Setting number of buttons to 3.");
+            buttonsNum = 3;
+        }
+
+        buttonsPressed = new int [buttonsNum];
+        buttonsReleased = new int [buttonsNum];
+        buttonsClicked = new int [buttonsNum];
+
+        AcceptExtraMouseButtons frame = new AcceptExtraMouseButtons();
+
+        MouseAdapter ma1 = new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    buttonsPressed[e.getButton() - 1] += 1;
+                    System.out.println("PRESSED "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    buttonsReleased[e.getButton() - 1] += 1;
+                    System.out.println("RELEASED "+e);
+                }
+                public void mouseClicked(MouseEvent e) {
+                    buttonsClicked[e.getButton() - 1] += 1;
+                    System.out.println("CLICKED "+e);
+                }
+            };
+        frame.addMouseListener(ma1);
+
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+
+        Util.waitForIdle(robot);  //a time to show a Frame
+
+        try {
+            robot = new Robot();
+            robot.delay(1000);
+            robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2,
+                            frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+            //TestCase 1: verify that all BUTTONx_DOWN_MASKs are accepted by the Robot.
+
+            for (int i = 0; i < buttonsNum; i++){
+                int buttonMask = InputEvent.getMaskForButton(i+1);
+                System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMask);
+                robot.mousePress(buttonMask);
+                robot.delay(30);
+                robot.mouseRelease(buttonMask);
+                Util.waitForIdle(robot);
+            }
+            for (int i = 0; i < buttonsNum; i++){
+                if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+                    throw new RuntimeException("TESTCASE 1 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+                }
+            }
+
+            java.util.Arrays.fill(buttonsPressed, 0);
+            java.util.Arrays.fill(buttonsReleased, 0);
+            java.util.Arrays.fill(buttonsClicked, 0);
+            //TestCase 2: verify that all BUTTONx_MASKs are accepted by the Robot.
+            for (int i = 0; i < standardButtonMasks.length; i++){
+                int buttonMask = standardButtonMasks[i];
+                System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMask);
+                robot.mousePress(buttonMask);
+                robot.delay(30);
+                robot.mouseRelease(buttonMask);
+                Util.waitForIdle(robot);
+            }
+            for (int i = 0; i < standardButtonMasks.length; i++){
+                if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+                    throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+                }
+            }
+
+        } catch (Exception e){
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/ManualInstructions/ManualInstructions.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,305 @@
+/*
+  test %W% %E%  %I%, %G%
+  @bug 6315717
+  @summary  manual control over the Robot
+  @author Andrei Dmitriev : area=awt.robot
+  @run applet/manual=yesno ManualInstructions.html
+*/
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class ManualInstructions extends Applet
+{
+    final static long SEND_DELAY = 1000;
+
+    public static void main(String s[]){
+        ManualInstructions mi = new ManualInstructions();
+        mi.init();
+        mi.start();
+    }
+
+    static Robot robot;
+    Point mouseLocation; //where mouse should be pressed each time
+    Panel target = new Panel();
+    Button pressOn = new Button("press on ...");
+    Button releaseOn = new Button("release on ...");
+    Button clickOn = new Button("click on ...");
+    Choice buttonNumber = new Choice();
+
+    public void init()
+    {
+        try {
+            robot = new Robot();
+        } catch (AWTException ex) {
+            ex.printStackTrace();
+            throw new RuntimeException(ex);
+        }
+        this.setLayout (new BorderLayout ());
+
+        target.setBackground(Color.green);
+        target.setName("GreenBox");//for the ease of debug
+        target.setPreferredSize(new Dimension(100, 100));
+        String toolkit = Toolkit.getDefaultToolkit().getClass().getName();
+
+        // on X systems two buttons are reserved for wheel though they are countable by MouseInfo.
+        int buttonsNumber = toolkit.equals("sun.awt.windows.WToolkit")?MouseInfo.getNumberOfButtons():MouseInfo.getNumberOfButtons()-2;
+
+        for (int i = 0; i < 8; i++){
+            buttonNumber.add("BUTTON"+(i+1)+"_MASK");
+        }
+
+        pressOn.addActionListener(new ActionListener(){
+                public void actionPerformed(ActionEvent e){
+                    System.out.println("Now pressing : " + (buttonNumber.getSelectedIndex()+1));
+
+                    Timer timer = new Timer();
+                    TimerTask robotInteraction = new TimerTask(){
+                            public void run(){
+                                robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+                                robot.mousePress(getMask(buttonNumber.getSelectedIndex()+1));
+                            }
+                        };
+                    timer.schedule(robotInteraction, SEND_DELAY);
+                }
+            });
+
+        releaseOn.addActionListener(new ActionListener(){
+            public void actionPerformed(ActionEvent e){
+                System.out.println("Now releasing : " + (buttonNumber.getSelectedIndex()+1));
+                Timer timer = new Timer();
+                TimerTask robotInteraction = new TimerTask(){
+                        public void run(){
+                            robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+                            robot.mouseRelease(getMask(buttonNumber.getSelectedIndex()+1));
+                        }
+                    };
+                timer.schedule(robotInteraction, SEND_DELAY);
+            }
+        });
+
+        clickOn.addActionListener(new ActionListener(){
+            public void actionPerformed(ActionEvent e){
+                System.out.println("Now clicking : " + (buttonNumber.getSelectedIndex()+1));
+                Timer timer = new Timer();
+                TimerTask robotInteraction = new TimerTask(){
+                        public void run(){
+                            robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+                            robot.mousePress(getMask(buttonNumber.getSelectedIndex()+1));
+                            robot.mouseRelease(getMask(buttonNumber.getSelectedIndex()+1));
+                        }
+                    };
+                timer.schedule(robotInteraction, SEND_DELAY);
+            }
+
+        });
+        target.addMouseListener(new MouseAdapter(){
+           public void mousePressed(MouseEvent e){
+                Sysout.println(""+e);
+           }
+           public void mouseReleased(MouseEvent e){
+                Sysout.println(""+e);
+           }
+           public void mouseClicked(MouseEvent e){
+                Sysout.println(""+e);
+           }
+        });
+
+        String[] instructions =
+        {
+            "Do provide an instruction to the robot by",
+            "choosing the button number to act and ",
+            "pressing appropriate java.awt.Button on the left.",
+            "Inspect an output in the TextArea below.",
+            "Please don't generate non-natural sequences like Release-Release, etc.",
+            "If you use keyboard be sure that you released the keyboard shortly.",
+            "If events are generated well press Pass, otherwise Fail."
+        };
+        Sysout.createDialogWithInstructions( instructions );
+
+    }//End  init()
+
+    private int getMask(int button){
+        return InputEvent.getMaskForButton(button);
+
+        /*
+            //this only works for standard buttons and for old JDK builds
+        int mask = 0;
+        switch (button){
+        case 1: {
+            mask = InputEvent.BUTTON1_MASK;
+            break;
+        }
+        case 2: {
+            mask = InputEvent.BUTTON2_MASK;
+            break;
+        }
+        case 3: {
+            mask = InputEvent.BUTTON3_MASK;
+            break;
+        }
+        }
+        return mask;
+        */
+    }
+
+    private Point updateTargetLocation() {
+        return new Point(target.getLocationOnScreen().x + target.getWidth()/2, target.getLocationOnScreen().y + target.getHeight()/2);
+    }
+
+    public void start ()
+    {
+        //Get things going.  Request focus, set size, et cetera
+        setSize (200,200);
+        setVisible(true);
+        validate();
+        Frame f = new Frame ("Set action for Robot here.");
+        f.setLayout(new FlowLayout());
+        f.add(buttonNumber);
+        f.add(pressOn);
+        f.add(releaseOn);
+        f.add(clickOn);
+        f.add(target);
+        f.pack();
+        f.setVisible(true);
+     }// start()
+}// class
+
+/* Place other classes related to the test after this line */
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+{
+    private static TestDialog dialog;
+
+    public static void createDialogWithInstructions( String[] instructions )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        dialog.printInstructions( instructions );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void createDialog( )
+    {
+        dialog = new TestDialog( new Frame(), "Instructions" );
+        String[] defInstr = { "Instructions will appear here. ", "" } ;
+        dialog.printInstructions( defInstr );
+        dialog.setVisible(true);
+        println( "Any messages for the tester will display here." );
+    }
+
+    public static void printInstructions( String[] instructions )
+    {
+        dialog.printInstructions( instructions );
+    }
+
+
+    public static void println( String messageIn )
+    {
+        dialog.displayMessage( messageIn );
+    }
+
+}// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog
+{
+
+    TextArea instructionsText;
+    TextArea messageText;
+    int maxStringLength = 120;
+
+    //DO NOT call this directly, go through Sysout
+    public TestDialog( Frame frame, String name )
+    {
+        super( frame, name );
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+        add( "North", instructionsText );
+
+        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+        add("Center", messageText);
+
+        pack();
+
+        setVisible(true);
+    }// TestDialog()
+
+    //DO NOT call this directly, go through Sysout
+    public void printInstructions( String[] instructions )
+    {
+        //Clear out any current instructions
+        instructionsText.setText( "" );
+
+        //Go down array of instruction strings
+
+        String printStr, remainingStr;
+        for( int i=0; i < instructions.length; i++ )
+        {
+            //chop up each into pieces maxSringLength long
+            remainingStr = instructions[ i ];
+            while( remainingStr.length() > 0 )
+            {
+                //if longer than max then chop off first max chars to print
+                if( remainingStr.length() >= maxStringLength )
+                {
+                    //Try to chop on a word boundary
+                    int posOfSpace = remainingStr.
+                        lastIndexOf( ' ', maxStringLength - 1 );
+
+                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
+                    remainingStr = remainingStr.substring( posOfSpace + 1 );
+                }
+                //else just print
+                else
+                {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+
+                instructionsText.append( printStr + "\n" );
+            }// while
+        }// for
+    }//printInstructions()
+
+    //DO NOT call this directly, go through Sysout
+    public void displayMessage( String messageIn )
+    {
+        messageText.append( messageIn + "\n" );
+        System.out.println(messageIn);
+    }
+
+}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/RobotExtraButton/RobotExtraButton.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,79 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that robot could accept extra buttons
+  @author Andrei Dmitriev : area=awt.mouse
+  @library ../../regtesthelpers
+  @build Util
+  @run main RobotExtraButton
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class RobotExtraButton extends Frame {
+    static Robot robot;
+    public static void main(String []s){
+        RobotExtraButton frame = new RobotExtraButton();
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+        frame.addMouseListener(new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    System.out.println("PRESSED "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    System.out.println("RELEASED "+e);
+                }
+                public void mouseClicked(MouseEvent e) {
+                    System.out.println("CLICKED "+e);
+                }
+            });
+        Util.waitForIdle(robot);
+        int [] buttonMask = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonMask[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("TEST: "+buttonMask[i]);
+        }
+
+        try {
+            robot = new Robot();
+            robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+            /*
+            if (MouseInfo.getNumberOfButtons() <= 3) {
+                System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons() +". Finish!");
+                return;
+                }*/
+
+            System.out.println("TEST: press 1");
+            robot.mousePress(InputEvent.BUTTON1_MASK);
+            robot.delay(50);
+            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            Util.waitForIdle(robot);
+
+            System.out.println("TEST: press 2");
+
+            robot.mousePress(InputEvent.BUTTON2_MASK);
+            robot.delay(50);
+            robot.mouseRelease(InputEvent.BUTTON2_MASK);
+            Util.waitForIdle(robot);
+            System.out.println("TEST: press 3");
+
+            robot.mousePress(InputEvent.BUTTON3_MASK);
+            robot.delay(50);
+            robot.mouseRelease(InputEvent.BUTTON3_MASK);
+            Util.waitForIdle(robot);
+            System.out.println("--------------------------------------------------");
+            for (int i = 0; i < buttonMask.length; i++){
+                System.out.println("button would = " +i + " : value = " +buttonMask[i]);
+                robot.mousePress(buttonMask[i]);
+                robot.delay(50);
+                robot.mouseRelease(buttonMask[i]);
+                Util.waitForIdle(robot);
+            }
+        } catch (Exception e){
+            e.printStackTrace();
+            throw new RuntimeException("Test failed.", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_1.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,36 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that system property sun.awt.enableExtraMouseButtons is true by default
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main SystemPropTest_1
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false initially.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true by default.
+// This must initlizes the Toolkit class.
+//3) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true (default).
+import java.awt.*;
+
+public class SystemPropTest_1 {
+
+    public static void main(String []s){
+        boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        System.out.println("1. System.getProperty = " + propValue);
+        if (propValue){
+            throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns false");
+        }
+
+        System.getProperties().list(System.out);
+        System.out.println("XXXX. System.getProperty = " + System.getProperty("sun.awt.enableExtraMouseButtons"));
+
+        propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        System.out.println("2. System.getProperty = " + propValue);
+        if (!propValue){
+            throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_2.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,25 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to true by the command line
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main/othervm -Dsun.awt.enableExtraMouseButtons=true SystemPropTest_2
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true if set through the command line.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true if the proprty is set through the command line.
+import java.awt.*;
+
+public class SystemPropTest_2 {
+
+    public static void main(String []s){
+        boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        System.out.println("System.getProperty = " + propValue);
+        if (!propValue){
+            throw new RuntimeException("TEST FAILED : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns false");
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_3.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,26 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to false by the command line
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main/othervm -Dsun.awt.enableExtraMouseButtons=false SystemPropTest_3
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false if set through the command line.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false if the proprty is set through the command line.
+import java.awt.*;
+
+public class SystemPropTest_3 {
+
+    public static void main(String []s){
+        boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        System.out.println("Test System.getProperty = " + System.getProperty("sun.awt.enableExtraMouseButtons"));
+        System.out.println("System.getProperty = " + propValue);
+        if (propValue){
+            throw new RuntimeException("TEST FAILED : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns true");
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_4.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,42 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to true by the System class API.
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main SystemPropTest_4
+ */
+//1)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "true")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true.
+//2)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "false")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true still.
+
+import java.awt.*;
+
+public class SystemPropTest_4 {
+    public static void main(String []s){
+        System.out.println("STAGE 1");
+        System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+        boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        if (!propValue){
+            throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED(1) : Toolkit.areExtraMouseButtonsEnabled() returns false");
+        }
+
+        System.out.println("STAGE 2");
+        System.setProperty("sun.awt.enableExtraMouseButtons", "false");
+        propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        if (propValue){
+            throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED(2) : Toolkit.areExtraMouseButtonsEnabled() returns false");
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_5.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,42 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to false by the System class API.
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main SystemPropTest_5
+ */
+//1)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "false")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false.
+//2)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "true")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false still.
+
+import java.awt.*;
+
+public class SystemPropTest_5 {
+    public static void main(String []s){
+        System.out.println("STAGE 1");
+        System.setProperty("sun.awt.enableExtraMouseButtons", "false");
+        boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        if (propValue){
+            throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED(1) : Toolkit.areExtraMouseButtonsEnabled() returns true");
+        }
+
+        System.out.println("STAGE 2");
+        System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+        propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        if (!propValue){
+            throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+            throw new RuntimeException("TEST FAILED(2) : Toolkit.areExtraMouseButtonsEnabled() returns true");
+        }
+        System.out.println("Test passed.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Disable.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,143 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that sun.awt.enableExtraMouseButtons = false consumes extra events
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main/othervm -Dsun.awt.enableExtraMouseButtons=false ToolkitPropertyTest_Disable
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+// Testcase 1: set to FALSE and check
+// Testcase 2: set to FALSE and check that extra events are not coming
+//                              check that standard events are coming
+
+public class ToolkitPropertyTest_Disable extends Frame {
+    static boolean propValue;
+    static Robot robot;
+    static int [] buttonsPressed;
+    static int [] buttonsReleased;
+    static int [] buttonsClicked;
+
+    static boolean lessThenFourButtons;
+
+    public static void main(String []s){
+        propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        buttonsPressed = new int [MouseInfo.getNumberOfButtons()];
+        buttonsReleased = new int [MouseInfo.getNumberOfButtons()];
+        buttonsClicked = new int [MouseInfo.getNumberOfButtons()];
+
+        ToolkitPropertyTest_Disable frame = new ToolkitPropertyTest_Disable();
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+
+        MouseAdapter ma1 = new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    buttonsPressed[e.getButton() - 1] += 1;
+                    System.out.println("PRESSED "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    buttonsReleased[e.getButton() - 1] += 1;
+                    System.out.println("RELEASED "+e);
+                }
+                public void mouseClicked(MouseEvent e) {
+                    buttonsClicked[e.getButton() - 1] += 1;
+                    System.out.println("CLICKED "+e);
+                }
+            };
+
+        try {
+            robot = new Robot();
+            robot.delay(1000);
+            robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+            System.out.println("Property = " + propValue);
+            testCase0();
+
+            testCase1();
+            System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+
+            lessThenFourButtons = (MouseInfo.getNumberOfButtons() <= 3);
+            if ( !lessThenFourButtons ) {
+                frame.addMouseListener(ma1);
+                testCase2();
+            }
+        } catch (Exception e){
+            e.printStackTrace();
+//            throw new RuntimeException(e);
+        } finally {
+//            frame.removeMouseListener(ma1);
+        }
+    }
+
+    public static void testCase0(){
+        if (propValue){
+            throw new RuntimeException("TEST FAILED (0): System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+    }
+
+    public static void testCase1(){
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() == true){
+            throw new RuntimeException("TEST FAILED (1): setting to FALSE. Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() = " + Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled());
+        }
+    }
+
+    public static void testCase2(){
+        emptyArrays();
+        int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonMasks[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("TEST: "+buttonMasks[i]);
+        }
+
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMasks[i]);
+            try {
+                robot.mousePress(buttonMasks[i]);
+                robot.delay(70);
+                robot.mouseRelease(buttonMasks[i]);
+                robot.delay(200);
+                //no exception is thrown
+                if (i >= 3) {
+                    throw new RuntimeException("TESTCASE 2 FAILED : robot accepted the extra button " + (i+1) + " instead of throwing an exception.");
+                }
+            } catch (IllegalArgumentException e){
+                if (i >= 3) {
+                    System.out.println("Passed: an exception caught for extra button.");
+                } else {
+                    throw new RuntimeException("TESTCASE 2 FAILED : exception happen on standard button.", e);
+                }
+            }
+        }
+        robot.delay(2000);
+        if (MouseInfo.getNumberOfButtons() < 3) {
+            for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+                if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+                    throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed.");
+                }
+            }
+        } else {
+            for (int i = 0; i < 3; i++){
+                if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+                    throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed.");
+                }
+            }
+
+            for (int i = 3; i < MouseInfo.getNumberOfButtons(); i++){
+                if (buttonsPressed[i] != 0 || buttonsReleased[i] != 0 || buttonsClicked[i] != 0 ) {
+                    throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " was pressed.");
+                }
+            }
+        }
+    }
+
+    public static void emptyArrays(){
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonsPressed[i] = 0;
+            buttonsReleased[i] = 0;
+            buttonsClicked[i] = 0;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,120 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that sun.awt.enableExtraMouseButtons is working
+  @author Andrei Dmitriev : area=awt.mouse
+  @run main/othervm -Dsun.awt.enableExtraMouseButtons=true ToolkitPropertyTest_Enable
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+// Testcase 1: set to TRUE (via jtreg option)
+// Testcase 2: set to TRUE and check that extra events are coming
+//                             check that standard events are coming
+
+public class ToolkitPropertyTest_Enable extends Frame {
+    static boolean propValue;
+    static Robot robot;
+    static int [] buttonsPressed;
+    static int [] buttonsReleased;
+    static int [] buttonsClicked;
+
+    public static void main(String []s){
+        propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+        buttonsPressed = new int [MouseInfo.getNumberOfButtons()];
+        buttonsReleased = new int [MouseInfo.getNumberOfButtons()];
+        buttonsClicked = new int [MouseInfo.getNumberOfButtons()];
+
+        ToolkitPropertyTest_Enable frame = new ToolkitPropertyTest_Enable();
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+
+        MouseAdapter ma1 = new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    buttonsPressed[e.getButton() - 1] += 1;
+                    System.out.println("PRESSED "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    buttonsReleased[e.getButton() - 1] += 1;
+                    System.out.println("RELEASED "+e);
+                }
+                public void mouseClicked(MouseEvent e) {
+                    buttonsClicked[e.getButton() - 1] += 1;
+                    System.out.println("CLICKED "+e);
+                }
+            };
+        //        frame.addMouseListener(ma1);
+
+        try {
+            robot = new Robot();
+            robot.delay(1000);
+            robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+            System.out.println("Property = " + propValue);
+            testCase0();
+
+            testCase1();
+            System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+
+            boolean lessThenFourButtons = (MouseInfo.getNumberOfButtons() <= 3);
+            if ( !lessThenFourButtons ) {
+                frame.addMouseListener(ma1);
+                testCase2();
+                //                testCase3();
+                //                testCase4();
+                frame.removeMouseListener(ma1);
+            }
+        } catch (Exception e){
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    public static void testCase0(){
+        if (!propValue){
+            throw new RuntimeException("TEST FAILED (0) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+        }
+    }
+
+    public static void testCase1(){
+        if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() == false){
+            throw new RuntimeException("TEST FAILED (1) : setting to TRUE. enabled = " + Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled());
+        }
+    }
+
+    public static void testCase2(){
+        emptyArrays();
+        //we can't post a message from an unexistent button
+        int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonMasks[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("TEST: "+buttonMasks[i]);
+        }
+
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMasks[i]);
+            robot.mousePress(buttonMasks[i]);
+            robot.delay(70);
+            robot.mouseRelease(buttonMasks[i]);
+            robot.delay(200);
+        }
+        robot.delay(1000);
+
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+                throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+            }
+        }
+    }
+
+    public static void emptyArrays(){
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonsPressed[i] = 0;
+            buttonsReleased[i] = 0;
+            buttonsClicked[i] = 0;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,83 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that InputEvents button masks arrays are the same
+  @author Andrei Dmitriev : area=awt.event
+  @run main ButtonArraysEquality
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+// get array InputEvent.BUTTON_MASK via reflection
+// get array InputEvent.BUTTON_DOWN_MASK via reflection
+// compare their lengths and values
+
+public class ButtonArraysEquality {
+    static int [] eventDownMask = new int []{InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK};
+
+    public static void main(String []s){
+        int [] buttonDownMasksAPI = new int [MouseInfo.getNumberOfButtons()];
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonDownMasksAPI[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("TEST: "+buttonDownMasksAPI[i]);
+        }
+
+        // getButtonDownMasks()
+        Object obj = AccessController.doPrivileged(
+                                            new PrivilegedAction() {
+                                                public Object run() {
+                                                    try {
+                                                        Class clazz = Class.forName("java.awt.event.InputEvent");
+                                                        Method method  = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {});
+                                                        if (method != null) {
+                                                            method.setAccessible(true);
+                                                            return method.invoke(null, (Object[])null);
+                                                        }
+                                                    }catch (Exception e){
+                                                        throw new RuntimeException("Test failed. Exception occured:", e);
+                                                    }
+                                                    return null;
+                                                }
+                                            });
+
+        int [] buttonDownMasks = new int [Array.getLength(obj)];
+        checkNullAndPutValuesToArray(buttonDownMasks, obj);
+
+        //check lengths: array shouldn't contain less elements then the number of buttons on a mouse
+        if (buttonDownMasks.length < buttonDownMasksAPI.length){
+            throw new RuntimeException("Test failed. The lengths array is less then the number of buttons");
+        }
+
+        // verify values for first three buttons
+        for (int i = 0; i < 3; i++) {
+            if (eventDownMask[i] != buttonDownMasks[i])
+            {
+                System.out.println("Test : "+ i + " | " + " | " +eventDownMask[i] + " | "+ buttonDownMasks[i]);
+                throw new RuntimeException("Failure: masks are not correct for standard buttons");
+            }
+        }
+
+        // verify values for extra buttons if any
+        for (int i = 3; i < MouseInfo.getNumberOfButtons(); i++) {
+            if (buttonDownMasksAPI[i] != buttonDownMasks[i]) {
+                throw new RuntimeException("Failure: masks are not the same for extra buttons");
+            }
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static void checkNullAndPutValuesToArray(int [] array, Object obj){
+        if (obj == null){
+            throw new RuntimeException("Test failed. The array obtained via reflection is "+obj);
+        }
+
+        for (int i = 0; i < Array.getLength(obj); i++){
+            System.out.println("Test (Reflection): "+ Array.getInt(obj, i));
+            array[i] = Array.getInt(obj, i);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/AcceptExtraButton/AcceptExtraButton.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,53 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that MouseEvent CTOR accepts extra mouse button numbers
+  @author Andrei Dmitriev : area=awt.event
+  @run main AcceptExtraButton
+ */
+
+//package acceptextrabutton;
+
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+
+public class AcceptExtraButton extends Frame {
+    static int [] eventID = new int []{MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, MouseEvent.MOUSE_CLICKED};
+
+    public static void main(String []s){
+        AcceptExtraButton f = new AcceptExtraButton();
+        f.setSize(300, 300);
+        f.setVisible(true);
+
+        for (int buttonId = 0; buttonId<eventID.length; buttonId++) {
+            for (int button = 0; button <= MouseInfo.getNumberOfButtons(); button++){
+                System.out.println("button == "+button);
+                MouseEvent me = new MouseEvent(f,
+                                               eventID[buttonId],
+                                               System.currentTimeMillis(),
+                                               0, //MouseEvent.BUTTON1_DOWN_MASK, modifiers
+                                               100, 100, // x, y
+                                               150, 150, // x, y on screen
+                                               1,        //clickCount
+                                               false,              //popupTrigger
+                                               button );// MouseEvent.NOBUTTON : button
+
+                System.out.println("dispatching >>>"+me);
+                f.dispatchEvent( ( AWTEvent )me );
+            }
+        }
+        MouseAdapter ma1 = new MouseAdapter() {
+                public void mousePressed(MouseEvent e) {
+                    System.out.println("PRESSED "+e);
+                }
+                public void mouseReleased(MouseEvent e) {
+                    System.out.println("RELEASED "+e);
+                }
+                public void mouseClicked(MouseEvent e) {
+                    System.out.println("CLICKED "+e);
+                }
+            };
+        f.addMouseListener(ma1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,89 @@
+/*
+  test %I% %E%
+  @bug 6315717
+  @summary verifies that MouseEvent could be constructed correctly for mouse extra buttons in regard to sun.awt.enableExtraMouseButtons property
+  @author Andrei Dmitriev : area=awt.event
+  @run main CTORRestrictions
+ */
+
+/*
+ * verify that user can create the MouseEvent? with button1|2|3|4|5|... when property "sun.awt.enableExtraMouseButtons" is true by default
+ */
+import java.awt.*;
+import java.awt.event.*;
+
+public class CTORRestrictions{
+    static Frame frame = new Frame("MouseEvent Test Frame");
+    static Point mousePosition;
+    static Point mousePositionOnScreen;
+
+    public static void main(String []s){
+        Robot robot = null;
+        try {
+            robot = new Robot();
+        } catch (AWTException ex) {
+            throw new RuntimeException("Test Failed", ex);
+        }
+        frame.setSize (200,200);
+        frame.setLocation (300, 400);
+        frame.setVisible(true);
+        robot.delay(1000);
+        System.out.println("sun.awt.enableExtraMouseButtons = "+Toolkit.getDefaultToolkit().getDesktopProperty("sun.awt.enableExtraMouseButtons"));
+        mousePosition = new Point(100, 100);
+        mousePositionOnScreen = new  Point(frame.getLocationOnScreen().x + mousePosition.x,
+                                                 frame.getLocationOnScreen().y + mousePosition.y);
+
+        /*
+         * On Linux the native system count a wheel (both directions) as two more buttons on a mouse.
+         * So, MouseInfo.getNumberOfButtons() would report 5 buttons on a three-button mouse.
+         * On Windows it would still report that MouseInfo.getNumberOfButtons() == 3.
+         * We should handle XToolkit case and iterate through the buttons
+         * up to (MouseInfo.getNumberOfButtons() - 2) value.
+         */
+        int numberOfButtons;
+        if (Toolkit.getDefaultToolkit().getClass().getName().equals("sun.awt.windows.WToolkit")){
+            numberOfButtons = MouseInfo.getNumberOfButtons();
+        } else {
+            numberOfButtons = MouseInfo.getNumberOfButtons() - 2;
+        }
+        System.out.println("Stage 1. Number of buttons = "+ numberOfButtons);
+
+        for (int buttonId = 1; buttonId <= numberOfButtons; buttonId++){
+            postMouseEventNewCtor(buttonId);
+        }
+
+        System.out.println("Stage 2. Number of buttons = "+ numberOfButtons);
+        for (int buttonId = 1; buttonId <= numberOfButtons; buttonId++){
+            postMouseEventOldCtor(buttonId);
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static void postMouseEventNewCtor(int buttonId)    {
+        MouseEvent me = new MouseEvent(frame,
+                                       MouseEvent.MOUSE_PRESSED,
+                                       System.currentTimeMillis(),
+                                       MouseEvent.BUTTON1_DOWN_MASK,
+                                       mousePosition.x, mousePosition.y,
+                                       mousePositionOnScreen.x,
+                                       mousePositionOnScreen.y,
+                                       1,
+                                       false,              //popupTrigger
+                                       buttonId            //button
+                                       );
+        frame.dispatchEvent( ( AWTEvent )me );
+    }
+
+    public static void postMouseEventOldCtor(int buttonId)    {
+        MouseEvent meOld = new MouseEvent(frame,
+                                          MouseEvent.MOUSE_PRESSED,
+                                          System.currentTimeMillis(),
+                                          MouseEvent.BUTTON1_DOWN_MASK,
+                                          mousePosition.x, mousePosition.y,
+                                          1,
+                                          false,              //popupTrigger
+                                          buttonId //button
+                                          );
+        frame.dispatchEvent( ( AWTEvent )meOld );
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions_Disable.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,101 @@
+/*
+  test %I% %E%
+  @bug 6315717
+  @summary verifies that MouseEvent could be constructed correctly for mouse extra buttons in regard to sun.awt.enableExtraMouseButtons property
+  @author Andrei Dmitriev : area=awt.event
+  @run main/othervm -Dsun.awt.enableExtraMouseButtons=false CTORRestrictions_Disable
+ */
+
+/*
+ * verify that user can't create the MouseEvent? with button4|5|... when property "sun.awt.enableExtraMouseButtons"=false
+ * verify that user can create the MouseEvent? with button1|2|3 when property "sun.awt.enableExtraMouseButtons"=false
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CTORRestrictions_Disable {
+    static Frame frame = new Frame("MouseEvent Test Frame");
+    static Point mousePosition;
+    static Point mousePositionOnScreen;
+
+    public static void main(String []s){
+        Robot robot = null;
+        try {
+            robot = new Robot();
+        } catch (AWTException ex) {
+            throw new RuntimeException("Test Failed", ex);
+        }
+        frame.setSize (200,200);
+        frame.setLocation (300, 400);
+        frame.setVisible(true);
+        robot.delay(1000);
+        System.out.println(Toolkit.getDefaultToolkit().getDesktopProperty("sun.awt.enableExtraMouseButtons"));
+        mousePosition = new Point(100, 100);
+        mousePositionOnScreen = new  Point(frame.getLocationOnScreen().x + mousePosition.x,
+                                                 frame.getLocationOnScreen().y + mousePosition.y);
+
+        System.out.println("Stage 1");
+        for (int buttonId = 1; buttonId <= MouseInfo.getNumberOfButtons(); buttonId++){
+           try {
+               postMouseEventNewCtor(buttonId);
+               if (buttonId > 3) {
+                   throw new RuntimeException("Stage 1 FAILED: MouseEvent CTOR accepted the extra button " + (buttonId+1) + " instead of throwing an exception.");
+               }
+           } catch (IllegalArgumentException e){
+                if (buttonId > 3) {
+                    System.out.println("Passed: an exception caught for extra button.");
+                } else {
+                    throw new RuntimeException("Stage 1 FAILED : exception happen on standard button.", e);
+                }
+            }
+        }
+
+        System.out.println("Stage 2");
+        for (int buttonId = 1; buttonId <= MouseInfo.getNumberOfButtons(); buttonId++){
+           try {
+               postMouseEventOldCtor(buttonId);
+               if (buttonId > 3) {
+                   throw new RuntimeException("Stage 2 FAILED: MouseEvent CTOR accepted the extra button " + (buttonId+1) + " instead of throwing an exception.");
+               }
+           } catch (IllegalArgumentException e){
+                if (buttonId > 3) {
+                    System.out.println("Passed: an exception caught for extra button.");
+                } else {
+                    throw new RuntimeException("Stage 2 FAILED : exception happen on standard button.", e);
+                }
+            }
+        }
+        System.out.println("Test passed.");
+    }
+
+    public static void postMouseEventNewCtor(int buttonId)    {
+        MouseEvent me = new MouseEvent(frame,
+                                       MouseEvent.MOUSE_PRESSED,
+                                       System.currentTimeMillis(),
+                                       MouseEvent.BUTTON1_DOWN_MASK,
+                                       mousePosition.x, mousePosition.y,
+                                       mousePositionOnScreen.x,
+                                       mousePositionOnScreen.y,
+                                       1,
+                                       false,              //popupTrigger
+                                       buttonId            //button
+                                       );
+        frame.dispatchEvent( ( AWTEvent )me );
+    }
+
+    public static void postMouseEventOldCtor(int buttonId)    {
+        MouseEvent meOld = new MouseEvent(frame,
+                                          MouseEvent.MOUSE_PRESSED,
+                                          System.currentTimeMillis(),
+                                          MouseEvent.BUTTON1_DOWN_MASK,
+                                          mousePosition.x, mousePosition.y,
+                                          1,
+                                          false,              //popupTrigger
+                                          buttonId //button
+                                          );
+        frame.dispatchEvent( ( AWTEvent )meOld );
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java	Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,65 @@
+/*
+  @test %I% %E%
+  @bug 6315717
+  @summary verifies that InputEvent.getMaskForButton() returns the same values as in InputEvent.BUTTON_DOWN_MASK
+  @author Andrei Dmitriev : area=awt.event
+  @run main CheckGetMaskForButton
+*/
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class CheckGetMaskForButton{
+    static Robot robot;
+
+    public static void main(String []s){
+        System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+        CheckGetMaskForButton f = new CheckGetMaskForButton();
+        int [] buttonMasksViaAPI = new int[MouseInfo.getNumberOfButtons()];
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            buttonMasksViaAPI[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("Test (API): "+ buttonMasksViaAPI[i]);
+        }
+
+        //get same array via reflection
+        Object obj = AccessController.doPrivileged(
+                new PrivilegedAction() {
+            public Object run() {
+                try {
+                    Class clazz = Class.forName("java.awt.event.InputEvent");
+                    Method method  = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {});
+                    if (method != null) {
+                        method.setAccessible(true);
+                        return method.invoke(null, (Object[])null);
+                    }
+                }catch (Exception e){
+                    throw new RuntimeException("Test failed. Exception occured:", e);
+                }
+                return null;
+            }
+        });
+
+        if (obj == null){
+            throw new RuntimeException("Test failed. The value obtained via reflection is "+obj);
+        }
+
+        int [] buttonDownMasksViaReflection = new int [Array.getLength(obj)];
+        //check that length of API array greater or equals then Reflect array.
+        if (Array.getLength(obj) < buttonMasksViaAPI.length){
+            throw new RuntimeException("Test failed. The length of API array greater or equals then the length of  Reflect array.");
+        }
+
+        //Check that the values obtained via reflection from InputEvent.BUTTON_DOWN_MASK are the
+        // same as for standard API.
+        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+            System.out.println("Test (Reflection): "+ Array.getInt(obj, i));
+            if (buttonMasksViaAPI[i] != Array.getInt(obj, i)){
+                throw new RuntimeException("Test failed. Values of InputEvent array are different for API and Reflection invocations");
+            }
+        }
+        System.out.println("Test passed.");
+    }
+}