changeset 57:7844f43c4834

Menu work. Check the sample.
author Alexandre (Shura) Iline <alexandre.iline@sun.com>
date Mon, 16 Jul 2012 20:11:41 +0400
parents cffb592b0930
children c86f0c7ecdc4 ae097e5bfc13
files tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuApp.java tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuSample.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/AbstractNodeHierarchy.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeHierarchy.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeParentImpl.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeWrapper.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/SceneNodeHierarchy.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowList.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowWrapper.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/Windows.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/AbstractMenuItemsParent.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/CheckBoxWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/CheckMenuItemWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/ContextMenuWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuBarWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuButtonWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuItemParent.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuItemWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuTreeSelectorImpl.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/RadioMenuItemWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/StringMenuOwnerImpl.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TabNodeHierarchy.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TableCellItemWrap.java tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TreeItemWrap.java tools/Jemmy/JemmyFX/test/org/jemmy/fx/control/TreeItemTest.java
diffstat 27 files changed, 1217 insertions(+), 394 deletions(-) [+]
line wrap: on
line diff
--- a/tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuApp.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuApp.java	Mon Jul 16 20:11:41 2012 +0400
@@ -53,10 +53,12 @@
         enabled.setSelected(true);
         
         RadioMenuItem option1 = new RadioMenuItem("Option _1");
+        option1.setId("option1");
         RadioMenuItem option2 = new RadioMenuItem("Option _2");
         option2.setId("option2");
         option2.setOnAction(new PrintAction("Option 2 is pushed"));
         RadioMenuItem option3 = new RadioMenuItem("Option _3");
+        option3.setId("option3");
         
         ToggleGroup options = new ToggleGroup();
         option1.setToggleGroup(options);
@@ -82,17 +84,27 @@
         
         Menu action = new Menu("A_ction");
         action.getItems().setAll(runItem);
+        action.setId("action");
         
         MenuBar menuBar = new MenuBar();
         menuBar.getMenus().setAll(fileMenu, action);
         
-        ContextMenu contextMenu = new ContextMenu(new MenuItem("_My menu item 1"), new MenuItem("My menu item _2"));
+        MenuItem cSubMenu = new MenuItem("sub-item");
+        
+        Menu cMenu = new Menu("item _1");
+        cMenu.getItems().add(cSubMenu);
+        ContextMenu contextMenu = new ContextMenu(cMenu, new MenuItem("item _2"));
         
         ScrollPane scrollPane = new ScrollPane();
         scrollPane.setContextMenu(contextMenu);
         
+        MenuItem eleven = new MenuItem("_Eleven");
+        
+        Menu one = new Menu("_One");
+        one.getItems().add(eleven);
+        
         MenuButton menuButton = new MenuButton("_Menu Button");
-        menuButton.getItems().setAll(new MenuItem("_One"), new MenuItem("_Two"), new MenuItem("T_hree"));
+        menuButton.getItems().setAll(one, new MenuItem("_Two"), new MenuItem("T_hree"));
         
         BorderPane borderPane = new BorderPane();
         borderPane.setTop(menuBar);
--- a/tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuSample.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/samples/org/jemmy/samples/menu/MenuSample.java	Mon Jul 16 20:11:41 2012 +0400
@@ -25,29 +25,25 @@
 package org.jemmy.samples.menu;
 
 
-import javafx.scene.Scene;
-import javafx.scene.control.MenuButton;
-import javafx.scene.control.MenuItem;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javafx.scene.control.ScrollPane;
-import javafx.stage.Popup;
-import org.jemmy.fx.ByText;
-import org.jemmy.fx.ByWindowType;
 import org.jemmy.fx.NodeDock;
 import org.jemmy.fx.SceneDock;
 import org.jemmy.fx.control.*;
-import org.jemmy.input.StringMenuOwner;
-import org.jemmy.interfaces.Keyboard;
 import org.jemmy.interfaces.Mouse.MouseButtons;
-import org.jemmy.lookup.Lookup;
 import org.jemmy.resources.StringComparePolicy;
 import org.jemmy.samples.SampleBase;
+import org.junit.After;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
- * 
- * @author KAM
+ * This sample shows how to use JavaFX menu. There are two generic ways to do so:
+ * through <code>MenuOwner</code> interface, when only basic menu operations are 
+ * needed, and performing lookup and more complicated steps through <code>MenuItemDock</code>
+ * class.
+ * @author KAM, shura
  */
 public class MenuSample extends SampleBase {
     private static SceneDock scene;
@@ -61,117 +57,95 @@
         // Obtaining a Dock for scene
         scene = new SceneDock();
 
-        /**
-        * Looking up for MenuBar. There is just one MenuBar in the scene so
-        * no criteria is specified.
-        */
+        //Looking up for MenuBar. There is just one MenuBar in the scene so
+        //no criteria is specified.
         menuBar = new MenuBarDock(scene.asParent());
     }
 
     /**
-     * Pushing menu item in menuBar.
+     * Push a menu.
      */ 
     @Test
     public void pushMenu() {
         
-        // Pressing Action > Run menu item. Items are looked up by text which
-        // also includes mnemonics so it is better to use ids as in pushMenuOption
-        menuBar.menu().push(
-                new ByTextMenuItem("A_ction", StringComparePolicy.EXACT), 
-                new ByTextMenuItem("Run", StringComparePolicy.SUBSTRING));
+        //it is possible to push menu hierarchycally. 
+        //Underscores in the item names mark mnemonics
+        menuBar.asMenuOwner().push("A_ction", "_Run");
+        
+        //it is also possible to find the menu item first
+        //and then click it with mouse.
+        //it will itself expand the path to become visible
+        new MenuItemDock(menuBar.asMenuParent(), "Option _1", StringComparePolicy.EXACT).mouse().click();
     }
     
     /**
-     * Pushing menu to change selected radio option.
+     * Push a menu while identifying items by ids.
      */
     @Test
-    public void pushMenuOption() {
-        
-        // Pressing File > Options > Option 2 menu item. Items are looked up by 
-        // ids which is the best approach.
+    public void pushMenuById() {        
+        //you could find menu components by id
         menuBar.menu().push(
                 new ByIdMenuItem("file"), 
                 new ByIdMenuItem("options"),
-                new ByIdMenuItem("option2"));
+                new ByIdMenuItem("option1"));
+        
+        //or using MenuItemDock
+        new MenuItemDock(menuBar.asMenuParent(), "action").mouse().click();
     }
     
     /**
-     * Checking whether menu item is checked.
-     * http://javafx-jira.kenai.com/browse/JMY-177
+     * Select a <code>CheckMenuItem</code>.
      */
     @Test
-    public void getCheckedMenuItem() {
+    public void checkMenuItem() {
         
-        // Calling Menu.select() method to open parent menu so that 
-        // necessary menu item is visible
-        MenuItemDock options = new MenuItemDock(menuBar.menu().select(
-                new ByIdMenuItem("file"), new ByIdMenuItem("options")));
+        //find a CheckMenuItem with text "Enabled"
+        CheckMenuItemDock checkMenuItem = new CheckMenuItemDock(menuBar.asMenuParent(), 
+                "Enabled", StringComparePolicy.SUBSTRING);
         
-        // Looking up for necessary menu item by text
-        MenuItemDock menuItem = new MenuItemDock(options.asMenuParent(), 
-                new ByTextMenuItem("Enabled", StringComparePolicy.SUBSTRING));
+        //you could do a siple mouse click to select the checkbox, 
+        //but of course you would want
+        //to verify what the current selection is and so on.
+        //instead just do this
+        checkMenuItem.asSelectable().selector().select(false);
         
-        // Getting selected property of menu item
-        Boolean selected = menuItem.wrap().getProperty(Boolean.class, "isSelected");
-        System.out.println("Enabled menu item is selected = " + selected);
-        
-        // Closing a menu via several ESC key presses
-        // http://javafx-jira.kenai.com/browse/JMY-181
-        menuItem.keyboard().pushKey(Keyboard.KeyboardButtons.ESCAPE);
-        menuItem.keyboard().pushKey(Keyboard.KeyboardButtons.ESCAPE);
+        //you could check if the item is selected
+        Boolean selected = checkMenuItem.isSelected();
+
     }
     
     /**
-     * Checking what menu option is selected.
-     * http://javafx-jira.kenai.com/browse/JMY-177
+     * Select a <code>RadioMenuItem</code>.
      */
     @Test
-    public void getSelectedRadioMenuItem() {
+    public void radioMenuItem() {
         
-        // Calling Menu.select() method to open parent menu so that 
-        // necessary menu item is visible
-        MenuItemDock options = new MenuItemDock(menuBar.menu().select(
-                new ByIdMenuItem("file"), new ByIdMenuItem("options")));
+        //for radio button, same approach as above would work, but click also works
+        //as you do not need to ckech the value - whether it selected or not
+        new RadioMenuItemDock(menuBar.asMenuParent(), "Option _2", StringComparePolicy.EXACT).mouse().click();
         
-        // Geting all the option menu items
-        Lookup<MenuItem> lookup = options.asMenuParent().lookup(new ByTextMenuItem<MenuItem>("Option", StringComparePolicy.SUBSTRING));
-        System.out.println("Found " + lookup.size() + " option menu items.");
-        MenuItemDock selectedMenuItem = null;
-        for (int i = 0; i < lookup.size(); i++) {
-            MenuItemDock menuItem = new MenuItemDock(lookup.wrap(i));
-            Boolean selected = menuItem.wrap().getProperty(Boolean.class, "isSelected");
-            if (selected) {
-                selectedMenuItem = menuItem;
-            }
-            System.out.println(menuItem.wrap().getProperty("getText") + " menu item is selected = " + selected);
-        }
-        
-        // Selecting checked item to close the menu
-        selectedMenuItem.mouse().click();
     }
     
     /**
-     * Push ContextMenuItem
+     * Work with context menu.
      * 
-     * TODO: Doesn't seem to be possible in current JemmyFX version
-     * http://javafx-jira.kenai.com/browse/JMY-180
      */
-    @Test @Ignore // TODO: Fix this sample one the issue is fixed
+    @Test 
     public void pushContextMenuItem() {
-        
-        // Obtaining a nodeDock for the ScrollPane which has a context menu
         NodeDock scrollPane = new NodeDock(scene.asParent(), ScrollPane.class);
-        
-        // Clicking right mouse button once
+                
+        //right click to call the popup
         // http://javafx-jira.kenai.com/browse/JMY-179
         scrollPane.mouse().click(1, scrollPane.wrap().getClickPoint(), MouseButtons.BUTTON3);
         
-        // Obtaining a popup scene
-        SceneDock popupScene = new SceneDock(new ByWindowType<Scene>(Popup.class));
+        //pushing a context menu is just like pushing main menu
+        new ContextMenuDock().asMenuOwner().push("item _2");
         
-//        scene2.asParent().lookup().dump(System.out);
-//        MenuDock menu = new MenuDock(scene2.asParent());
-//        menu.menu().push(new ByTextMenuItem("My Menu Item", StringComparePolicy.EXACT));
+
+        scrollPane.mouse().click(1, scrollPane.wrap().getClickPoint(), MouseButtons.BUTTON3);
+
+        //or
+        new MenuItemDock(new ContextMenuDock().asMenuParent(), "sub-", StringComparePolicy.SUBSTRING).mouse().click();
     }
     
     /**
@@ -180,14 +154,31 @@
     @Test
     public void pushMenuButtonMenuItem() {
         
-        // Obtaining MenuButtonDock by its text.
-        MenuButtonDock menuButton = new MenuButtonDock(scene.asParent(), new ByText<MenuButton>("_Menu Button"));
+        MenuButtonDock menuButton = new MenuButtonDock(scene.asParent(), "_Menu Button", StringComparePolicy.EXACT);
         
-        // JemmyDock API is not sufficient in this area so we're switching to plain old wrap stuff
-        // http://javafx-jira.kenai.com/browse/JMY-178
-        StringMenuOwner button_menu_owner = menuButton.wrap().as(StringMenuOwner.class, MenuItem.class);
+        //same as other menus
+        new MenuItemDock(menuButton.asMenuParent(), "_Eleven", StringComparePolicy.EXACT).mouse().click();
         
-        // Pushing menu item by text
-        button_menu_owner.push("_Two");
+        //or
+        menuButton.asMenuOwner().push("_Two");
+    }
+    
+    /**
+     * Finally, how to collapse
+     */
+    @Test
+    public void collapse() {
+        //expand
+        new MenuItemDock(menuBar.asMenuParent(), "option1").mouse().move();
+        
+        //and collapse
+        menuBar.asCollapsible().collapse();
+    }
+
+    @After
+    public void after() {
+        //wait for everything to be totally collapsed after every test
+        new MenuDock(menuBar.asMenuParent(), 0).wrap().waitProperty("isShowing", false);
+        new MenuDock(menuBar.asMenuParent(), 1).wrap().waitProperty("isShowing", false);        
     }
 }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/AbstractNodeHierarchy.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/AbstractNodeHierarchy.java	Mon Jul 16 20:11:41 2012 +0400
@@ -39,11 +39,9 @@
  */
 public abstract class AbstractNodeHierarchy implements ControlHierarchy {
 
-    protected javafx.scene.Parent root;
     protected Environment env;
 
-    public AbstractNodeHierarchy(Parent root, Environment env) {
-        this.root = root;
+    public AbstractNodeHierarchy(Environment env) {
         this.env = env;
     }
    
@@ -85,21 +83,4 @@
         return childAction.getResult();
     }
 
-    public List<?> getControls() {
-        GetAction<List<?>> controls = new GetAction<List<?>>() {
-            @Override
-            public void run(Object... parameters) {                
-                if (root != null) {
-                    setResult(root.getChildrenUnmodifiable());
-                } else {
-                    List root = new ArrayList();
-                    root.add(getRoot());
-                    setResult(root);
-                }
-            }
-        };
-        env.getExecutor().execute(env, true, controls);
-        return controls.getResult();
-    }
-    protected abstract Node getRoot();
 }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeHierarchy.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeHierarchy.java	Mon Jul 16 20:11:41 2012 +0400
@@ -24,6 +24,7 @@
  */
 package org.jemmy.fx;
 
+import java.util.List;
 import javafx.scene.Node;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
@@ -32,20 +33,21 @@
 class NodeHierarchy extends AbstractNodeHierarchy {
 
     private Scene scene;
+    private final Parent root;
 
     public NodeHierarchy(Parent root, Environment env) {
-        super(root, env);
+        super(env);
+        this.root = root;
     }
 
     @Deprecated
     public NodeHierarchy(Scene scene, Environment env) {
-        super(null, env);
+        super(env);
         this.scene = scene;
-
+        root = scene.getRoot();
     }
 
-    @Override
-    protected Node getRoot() {
-        return root;
+    public List<?> getControls() {
+        return getChildren(root);
     }
 }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeParentImpl.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeParentImpl.java	Mon Jul 16 20:11:41 2012 +0400
@@ -33,7 +33,7 @@
 import org.jemmy.lookup.LookupCriteria;
 
 public class NodeParentImpl extends AbstractParent<Node> {
-
+    
     private Environment env;
     private AbstractNodeHierarchy nodeHierarchy;
 
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeWrapper.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/NodeWrapper.java	Mon Jul 16 20:11:41 2012 +0400
@@ -45,7 +45,7 @@
 public class NodeWrapper extends DefaultWrapper {
 
     private static final List<Class<? extends Wrap>> OPERATORS = new ArrayList<Class<? extends Wrap>>();
-    
+
     static {
         OPERATORS.add(NodeWrap.class);
         OPERATORS.add(TextWrap.class);
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/SceneNodeHierarchy.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/SceneNodeHierarchy.java	Mon Jul 16 20:11:41 2012 +0400
@@ -24,25 +24,27 @@
  */
 package org.jemmy.fx;
 
-import javafx.scene.Node;
+import java.util.ArrayList;
+import java.util.List;
 import javafx.scene.Scene;
 import org.jemmy.env.Environment;
 
 /**
  *
- * @author andrey
+ * @author andrey, shura
  */
 class SceneNodeHierarchy extends AbstractNodeHierarchy {
 
     protected Scene scene;
 
     public SceneNodeHierarchy(Scene scene, Environment env) {
-        super(null, env);
+        super(env);
         this.scene = scene;
     }
 
-    @Override
-    protected Node getRoot() {
-        return scene.getRoot();
+    public List<?> getControls() {
+        ArrayList<Object> res = new ArrayList<Object>(1);
+        res.add(scene.getRoot());
+        return res;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowList.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javafx.stage.Window;
+import org.jemmy.action.GetAction;
+import org.jemmy.lookup.ControlList;
+
+
+/**
+ * Allows to search among windows.
+ * @author shura
+ */
+class WindowList implements ControlList {
+
+    @Override
+    public List<?> getControls() {
+        GetAction<List<?>> scenes = new GetAction<List<?>>() {
+
+            @Override
+            public void run(Object... parameters) {
+                LinkedList<Window> res = new LinkedList<Window>();
+                Iterator<Window> windows = Window.impl_getWindows();
+                while(windows.hasNext()) {
+                    res.add(windows.next());
+                }
+                setResult(res);
+            }
+        };
+        try {
+            Root.ROOT.getEnvironment().getExecutor().execute(Root.ROOT.getEnvironment(), true, scenes);
+            return scenes.getResult();
+        } catch (Throwable th) {
+            th.printStackTrace(System.err);
+            return new ArrayList();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx;
+
+import javafx.stage.Window;
+import org.jemmy.Rectangle;
+import org.jemmy.action.GetAction;
+import org.jemmy.control.ControlType;
+import org.jemmy.control.Wrap;
+import org.jemmy.dock.DefaultParent;
+import org.jemmy.env.Environment;
+import org.jemmy.interfaces.Parent;
+
+/**
+ * Window could be used as a target for mouse events.
+ * @author shura
+ */
+@ControlType(Window.class)
+public class WindowWrap<T extends Window> extends Wrap<T> {
+    
+    @DefaultParent("all scenes")
+    public static <CONTROL extends Window> Parent<? super Window> getRoot(Class<CONTROL> controlType) {
+        return Windows.WINDOWS;
+    }
+    
+    public WindowWrap(Environment env, T node) {
+        super(env, node);
+    }
+
+    @Override
+    public Rectangle getScreenBounds() {
+        return new GetAction<Rectangle>() {
+
+            @Override
+            public void run(Object... os) throws Exception {
+                Rectangle res = new Rectangle();
+                res.setLocation((int)getControl().getX(), (int)getControl().getY());
+                res.setSize((int)getControl().getWidth(), (int)getControl().getHeight());
+                setResult(res);
+            }
+        }.dispatch(getEnvironment());
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/WindowWrapper.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jemmy.control.DefaultWrapper;
+import org.jemmy.control.Wrap;
+import org.jemmy.env.Environment;
+import org.jemmy.fx.control.ContextMenuWrap;
+
+class WindowWrapper extends DefaultWrapper {
+
+    private static final List<Class<? extends Wrap>> OPERATORS = new ArrayList<Class<? extends Wrap>>();
+    
+    static {
+        OPERATORS.add(WindowWrap.class);
+        OPERATORS.add(ContextMenuWrap.class);
+    }
+
+    WindowWrapper(Environment env) {
+        super(env, OPERATORS.toArray(new Class[0]));
+    }
+
+    @Override
+    public <T> Wrap<? extends T> wrap(Class<T> controlClass, T control) {
+        return super.wrap(controlClass, control);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/Windows.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx;
+
+import javafx.stage.Window;
+import org.jemmy.env.Environment;
+import org.jemmy.lookup.AbstractParent;
+import org.jemmy.lookup.Lookup;
+import org.jemmy.lookup.LookupCriteria;
+import org.jemmy.lookup.PlainLookup;
+
+class Windows extends AbstractParent<Window> {
+    
+    public static final Windows WINDOWS = new Windows();
+    
+    private final WindowWrapper wrapper;
+    private final WindowList list;
+    private final Environment env;
+
+    private Windows() {
+        wrapper = new WindowWrapper(Root.ROOT.getEnvironment());
+        list = new WindowList();
+        env = new Environment(Root.ROOT.getEnvironment());
+    }
+    
+
+    public <ST extends Window> Lookup<ST> lookup(Class<ST> type, LookupCriteria<ST> lc) {
+        return new PlainLookup<ST>(env, list, wrapper, type, lc);
+    }
+
+    public Lookup<Window> lookup(LookupCriteria<Window> lc) {
+        return new PlainLookup<Window>(env, list, wrapper, Window.class, lc);
+    }
+
+    public Class<Window> getType() {
+        return Window.class;
+    }
+    
+}
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/AbstractMenuItemsParent.java	Tue Jul 10 14:39:14 2012 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.jemmy.fx.control;
-
-import javafx.scene.control.Menu;
-import javafx.scene.control.MenuItem;
-import org.jemmy.JemmyException;
-import org.jemmy.control.Wrap;
-import org.jemmy.control.Wrapper;
-
-public abstract class AbstractMenuItemsParent<ITEM extends MenuItem> extends AbstractItemsParent<ITEM> {
-
-    public AbstractMenuItemsParent(Wrap wrap, Class<ITEM> itemClass) {
-        super(wrap, new ItemWrapper(wrap), itemClass);
-    }
-
-    protected static class ItemWrapper<ITEM extends MenuItem> implements Wrapper {
-        protected Wrap wrap;
-
-        public ItemWrapper(Wrap wrap) {
-            this.wrap = wrap;
-        }
-
-        @Override
-        public <T> Wrap<? extends T> wrap(Class<T> controlClass, T control) {
-            if (MenuItem.class.isAssignableFrom(controlClass)) {
-                if (Menu.class.isAssignableFrom(control.getClass())) {
-                    return (Wrap<? extends T>) new MenuWrap<Menu>((Menu)control, wrap);
-                }
-                return (Wrap<? extends T>) new MenuItemWrap<ITEM>((ITEM)control, wrap);
-            }
-            throw new JemmyException("Unexpected control class is used: " + controlClass);
-        }
-    }
-}
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/CheckBoxWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/CheckBoxWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -34,10 +34,8 @@
 import org.jemmy.fx.ByText;
 import org.jemmy.fx.NodeParent;
 import org.jemmy.fx.Root;
-import org.jemmy.interfaces.ControlInterface;
 import org.jemmy.interfaces.Selectable;
 import org.jemmy.interfaces.Selector;
-import org.jemmy.interfaces.TypeControlInterface;
 import org.jemmy.lookup.LookupCriteria;
 import org.jemmy.resources.StringComparePolicy;
 
@@ -98,7 +96,7 @@
          */
         UNDEFINED
     };
-    private final static List<Boolean> booleanStates;
+    final static List<Boolean> booleanStates;
     private final static List<State> twoStates;
     private final static List<State> triStates;
     private Selector<State> stateSelector = new SelectorImpl<CheckBox, State>(this, this);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/CheckMenuItemWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx.control;
+
+import javafx.scene.control.CheckMenuItem;
+import org.jemmy.control.As;
+import org.jemmy.control.ControlInterfaces;
+import org.jemmy.control.ControlType;
+import org.jemmy.control.MethodProperties;
+import org.jemmy.env.Environment;
+import org.jemmy.interfaces.Selectable;
+
+/**
+ * This is a menu item and so could be found within the menu hierarchy. It could 
+ * also be selected/unselected.
+ * Please consult <a href="../../samples/menu">samples</a> for more info.
+ * @see MenuBarWrap
+ * @author shura
+ */
+@ControlType(CheckMenuItem.class)
+@MethodProperties("isSelected")
+@ControlInterfaces(value=Selectable.class, encapsulates=Boolean.class)
+public class CheckMenuItemWrap<T extends CheckMenuItem>  extends MenuItemWrap<T> {
+
+    private final SelectableImpl selectable = new SelectableImpl();
+    
+     public CheckMenuItemWrap(Environment env, T item) {
+        super(env, item);
+    }
+    
+    @As(Boolean.class)
+    public Selectable<Boolean> asSelectable() {
+        return selectable;
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/ContextMenuWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx.control;
+
+import java.util.List;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
+import org.jemmy.action.GetAction;
+import org.jemmy.control.As;
+import org.jemmy.control.ControlInterfaces;
+import org.jemmy.control.ControlType;
+import org.jemmy.env.Environment;
+import org.jemmy.fx.WindowWrap;
+import org.jemmy.input.StringMenuOwner;
+import org.jemmy.interfaces.Parent;
+
+/**
+ * Context menu is supported in the very same way as menu bar.
+ * Please consult <a href="../../samples/menu">samples</a> for more info.
+ * @see MenuBarWrap
+ * @see ContextMenuDock
+ * @author shura
+ */
+@ControlType(ContextMenu.class)
+@ControlInterfaces(value = {Parent.class, StringMenuOwner.class},
+encapsulates = {MenuItem.class, MenuItem.class}, name = {"asMenuParent", "asMenuOwner"})
+public class ContextMenuWrap<T extends ContextMenu> extends WindowWrap<T> {
+
+    private StringMenuOwnerImpl menuOwner = null;
+    private Parent<MenuItem> parent = null;
+
+    public ContextMenuWrap(Environment env, T window) {
+        super(env, window);
+    }
+
+    /**
+     * @see MenuBarWrap#asMenuParent() 
+     * @return 
+     */
+    @As(MenuItem.class)
+    public Parent<MenuItem> asMenuParent() {
+        if (parent == null) {
+            parent = new MenuItemParent(this) {
+
+                @Override
+                protected List getControls() {
+                    return new GetAction<List<?>>() {
+
+                        @Override
+                        public void run(Object... os) throws Exception {
+                            setResult(getControl().getItems());
+                        }
+                    }.dispatch(getEnvironment());
+                }
+            };
+        }
+        return parent;
+    }
+
+    /**
+     * @see MenuBarWrap#asMenuOwner() 
+     * @return 
+     */
+    @As(MenuItem.class)
+    public StringMenuOwner<MenuItem> asMenuOwner() {
+        if (menuOwner == null) {
+            menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class));
+        }
+        return menuOwner;
+    }
+
+}
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuBarWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuBarWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -28,24 +28,41 @@
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuBar;
 import javafx.scene.control.MenuItem;
+import org.jemmy.action.Action;
+import org.jemmy.action.GetAction;
+import org.jemmy.control.As;
 import org.jemmy.control.ControlInterfaces;
 import org.jemmy.control.ControlType;
 import org.jemmy.env.Environment;
 import org.jemmy.fx.NodeWrap;
 import org.jemmy.fx.Root;
+import org.jemmy.input.StringMenuOwner;
+import org.jemmy.interfaces.Collapsible;
 import org.jemmy.interfaces.Focus;
 import org.jemmy.interfaces.MenuOwner;
 import org.jemmy.interfaces.Parent;
-import org.jemmy.interfaces.TypeControlInterface;
 
+/**
+ * Menu is supported in two different form.<br/>
+ * One is by using <code>MenuOwner</code> control interface. There you could
+ * perform basic menu pushing or selecting. Select operation returns a wrap, 
+ * which you could pass into a constructor of a dock or use directly.<br/>
+ * The other approach is to use MenuItemDock which allows advanced lookup and
+ * more input operations.<br/>
+ * Please consult <a href="../../samples/menu">samples</a> for more info.
+ * @see MenuItemWrap
+ * @see StringMenuOwner
+ * @see MenuBarDock
+ * @author shura
+ * @param <CONTROL> 
+ */
 @ControlType({MenuBar.class})
-@ControlInterfaces(value = {Parent.class, MenuOwner.class},
-encapsulates = {MenuItem.class, MenuItem.class},name={"asMenuParent"})
-
+@ControlInterfaces(value = {Parent.class, StringMenuOwner.class, Collapsible.class},
+encapsulates = {MenuItem.class, MenuItem.class}, name = {"asMenuParent", "asMenuOwner"})
 public class MenuBarWrap<CONTROL extends MenuBar> extends NodeWrap<CONTROL> {
 
-    private StringMenuOwnerImpl menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class));
-    
+    private StringMenuOwnerImpl menuOwner = null;
+    private Parent<MenuItem> parent = null;
     private Focus focus = Root.ROOT.getThemeFactory().menuBarFocuser(this);
 
     /**
@@ -59,36 +76,74 @@
         super(env, nd);
     }
 
-    @Override
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> boolean is(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.isAssignableFrom(interfaceClass)) {
-                return true;
-            }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return true;
-            }
+    /**
+     * Turns into a parent which you could use to look for menu items within. <br/>
+     * Notice that the lookup is performed through the whole hierarchy. You only 
+     * need to specify criteria for a single menu item no matter how deep in the 
+     * hierarchy it resides. <br/>
+     * Notice also that menus are sometimes dynamic - that is, 
+     * sub-items are only loaded when a parent is expanded. If a node is not loaded,
+     * this lookup would not find it. You need to find a parent node in question, 
+     * expand it, and use it as a root for further search.
+     * @see MenuWrap#asMenuParent() 
+     * @return 
+     */
+    @As(MenuItem.class)
+    public Parent<MenuItem> asMenuParent() {
+        if (parent == null) {
+            parent = new MenuItemParent(this) {
+
+                @Override
+                protected List getControls() {
+                    return new GetAction<List<?>>() {
+
+                        @Override
+                        public void run(Object... os) throws Exception {
+                            setResult(getControl().getMenus());
+                        }
+                    }.dispatch(getEnvironment());
+                }
+            };
         }
-        return super.is(interfaceClass, type);
+        return parent;
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.equals(interfaceClass)) {
-                return (INTERFACE) new AbstractMenuItemsParent(this, type) {
-                    @Override
-                    protected List getControls() {
-                        return getControl().getMenus();
-                    }
-                };
-            }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return (INTERFACE) menuOwner;
-            }
+    /**
+     * Allows to perform simple push and selection operations on the menu.
+     * @return 
+     */
+    @As(MenuItem.class)
+    public StringMenuOwner<MenuItem> asMenuOwner() {
+        if (menuOwner == null) {
+            menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class));
         }
-        return super.as(interfaceClass, type);
+        return menuOwner;
+    }
+    private Collapsible collapsible = null;
+
+    /**
+     * Collapses ass the sub-menus.
+     * @return 
+     */
+    @As
+    public Collapsible asCollapsible() {
+        if (collapsible == null) {
+            collapsible = new Collapsible() {
+
+                public void collapse() {
+                    getEnvironment().getExecutor().execute(getEnvironment(), true, new Action() {
+
+                        @Override
+                        public void run(Object... os) throws Exception {
+                            for (Menu m : getControl().getMenus()) {
+                                m.hide();
+                            }
+                        }
+                    });
+                }
+            };
+        }
+        return collapsible;
     }
 
     @Override
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuButtonWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuButtonWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -25,26 +25,36 @@
 package org.jemmy.fx.control;
 
 import java.util.List;
-import javafx.scene.Scene;
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuButton;
 import javafx.scene.control.MenuItem;
+import org.jemmy.action.GetAction;
+import org.jemmy.control.As;
 import org.jemmy.control.ControlInterfaces;
 import org.jemmy.control.ControlType;
+import org.jemmy.control.Property;
 import org.jemmy.env.Environment;
 import org.jemmy.input.StringMenuOwner;
-import org.jemmy.interfaces.MenuOwner;
+import org.jemmy.interfaces.Collapsible;
+import org.jemmy.interfaces.Expandable;
 import org.jemmy.interfaces.Parent;
-import org.jemmy.interfaces.Tree;
-import org.jemmy.interfaces.TypeControlInterface;
+import org.jemmy.timing.State;
 
+/**
+ * Menu button is supported in the very same way as menu bar.
+ * Please consult <a href="../../samples/menu">samples</a> for more info.
+ * @see MenuBarWrap
+ * @see MenuButtonDock
+ * @author shura
+ * @param <CONTROL> 
+ */
 @ControlType({MenuButton.class})
-//@ControlInterfaces(value = {Parent.class, StringMenuOwner.class},
-//encapsulates = {Menu.class, Menu.class, MenuItem.class})
-
+@ControlInterfaces(value = {Parent.class, StringMenuOwner.class, Expandable.class, Collapsible.class},
+encapsulates = {MenuItem.class, MenuItem.class}, name = {"asMenuParent", "asMenuOwner"})
 public class MenuButtonWrap<CONTROL extends MenuButton> extends TextControlWrap<CONTROL> {
 
-    private StringMenuOwnerImpl menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, MenuItem.class));
+    private StringMenuOwnerImpl menuOwner = null;
+    private Parent<MenuItem> parent = null;
 
     /**
      *
@@ -57,39 +67,114 @@
         super(env, nd);
     }
 
-    @Override
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> boolean is(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.equals(interfaceClass)) {
-                return true;
+    @Property("isShowing")
+    public boolean isShowing() {
+        return new GetAction<Boolean>() {
+
+            @Override
+            public void run(Object... os) throws Exception {
+                setResult(getControl().isShowing());
             }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return true;
-            }
-            if (Tree.class.isAssignableFrom(interfaceClass)) {
-                return true;
-            }
-        }
-        return super.is(interfaceClass, type);
+        }.dispatch(getEnvironment());
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>>
-           INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.equals(interfaceClass)) {
-                return (INTERFACE) new AbstractMenuItemsParent(this, type) {
-                    @Override
-                    protected List getControls() {
-                        return getControl().getItems();
+    /**
+     * @see MenuBarWrap#asMenuParent() 
+     * @return 
+     */
+    @As(MenuItem.class)
+    public Parent<MenuItem> asMenuParent() {
+        if (parent == null) {
+            parent = new MenuItemParent(this) {
+
+                @Override
+                protected List getControls() {
+                    return new GetAction<List<?>>() {
+
+                        @Override
+                        public void run(Object... os) throws Exception {
+                            setResult(getControl().getItems());
+                        }
+                    }.dispatch(getEnvironment());
+                }
+            };
+        }
+        return parent;
+    }
+
+    /**
+     * @see MenuBarWrap#asMenuOwner()  
+     * @return 
+     */
+    @As(MenuItem.class)
+    public StringMenuOwner<MenuItem> asMenuOwner() {
+        if (menuOwner == null) {
+            menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class)) {
+
+                @Override
+                protected void prepare() {
+                    if (!isShowing()) {
+                        mouse().click();
+                        getEnvironment().getWaiter(WAIT_STATE_TIMEOUT).ensureValue(true,
+                                new State<Boolean>() {
+
+                                    public Boolean reached() {
+                                        return isShowing();
+                                    }
+                                });
                     }
-                };
-            }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return (INTERFACE) menuOwner;
-            }
+                }
+            };
         }
-        return super.as(interfaceClass, type);
+        return menuOwner;
+    }
+    
+    private Expandable expandable = null;
+    private State<Boolean> showingState = new State<Boolean>() {
+        boolean expected = true;
+        
+        public Boolean reached() {
+            return isShowing();
+        }
+    };
+
+    /**
+     * Clicks on the button if the menu is not visible.
+     * @return 
+     */
+    @As
+    public Expandable asExpandable() {
+        if (expandable == null) {
+            expandable = new Expandable() {
+
+                public void expand() {
+                    if(!isShowing())
+                        mouse().click();
+                    waitState(showingState, true);
+                }
+            };
+        }
+        return expandable;
+    }
+    private Collapsible collapsible = null;
+
+    /**
+     * Clicks on the button if the menu is visible.
+     * @return 
+     */
+    @As
+    public Collapsible asCollapsible() {
+        if (collapsible == null) {
+            collapsible = new Collapsible() {
+
+                public void collapse() {
+                    if(isShowing())
+                        mouse().click();
+                    waitState(showingState, false);
+                }
+            };
+            
+        }
+        return collapsible;
     }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuItemParent.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx.control;
+
+import java.util.Collections;
+import java.util.List;
+import javafx.scene.control.CheckMenuItem;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.RadioMenuItem;
+import org.jemmy.JemmyException;
+import org.jemmy.control.Wrap;
+import org.jemmy.control.Wrapper;
+import org.jemmy.lookup.*;
+
+abstract class MenuItemParent extends AbstractParent<MenuItem> {
+
+    private final Wrap wrap;
+    private final Wrapper itemWrapper;
+    private final ControlHierarchy items;
+    
+    protected MenuItemParent(Wrap wrap) {
+        this.wrap = wrap;
+        itemWrapper = new ItemWrapper(wrap);
+        items = new MenuHierarchy();
+    }
+
+    public <ST extends MenuItem> Lookup<ST> lookup(Class<ST> type, LookupCriteria<ST> lc) {
+        return new HierarchyLookup<ST>(wrap.getEnvironment(), items, itemWrapper, type, lc);
+    }
+
+    public Lookup<MenuItem> lookup(LookupCriteria<MenuItem> lc) {
+        return lookup(MenuItem.class, lc);
+    }
+
+    public Class<MenuItem> getType() {
+        return MenuItem.class;
+    }
+
+    protected abstract List<?> getControls();
+
+    private static class ItemWrapper implements Wrapper {
+
+        protected Wrap wrap;
+
+        public ItemWrapper(Wrap wrap) {
+            this.wrap = wrap;
+        }
+
+        @Override
+        public <T> Wrap<? extends T> wrap(Class<T> controlClass, T control) {
+            if (MenuItem.class.isInstance(control)) {
+                if (Menu.class.isInstance(control)) {
+                    return (Wrap<? extends T>) 
+                            new MenuWrap<Menu>(wrap.getEnvironment(), Menu.class.cast(control));
+                } else if (RadioMenuItem.class.isInstance(control)) {
+                    return (Wrap<? extends T>) 
+                            new RadioMenuItemWrap<RadioMenuItem>(wrap.getEnvironment(), RadioMenuItem.class.cast(control));
+                } else if (CheckMenuItem.class.isInstance(control)) {
+                    return (Wrap<? extends T>) 
+                            new CheckMenuItemWrap<CheckMenuItem>(wrap.getEnvironment(), CheckMenuItem.class.cast(control));
+                } else {
+                    return (Wrap<? extends T>) new MenuItemWrap(wrap.getEnvironment(), MenuItem.class.cast(control));
+                }
+            }
+            throw new JemmyException("Unexpected control class is used: " + controlClass);
+        }
+    }
+    
+    private class MenuHierarchy implements ControlHierarchy {
+
+        public List<?> getChildren(Object o) {
+            if(o instanceof Menu) {
+                return Menu.class.cast(o).getItems();
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        public Object getParent(Object o) {
+            return MenuItem.class.cast(o).getParentMenu();
+        }
+
+        public List<?> getControls() {
+            return MenuItemParent.this.getControls();
+        }
+
+    }
+}
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuItemWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuItemWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -24,108 +24,228 @@
  */
 package org.jemmy.fx.control;
 
+import java.util.List;
 import javafx.scene.Node;
 import javafx.scene.Scene;
-import javafx.scene.control.ContextMenu;
+import javafx.scene.control.*;
+import javafx.scene.control.Menu;
+import javafx.scene.text.Text;
 import org.jemmy.Rectangle;
-import javafx.scene.control.Menu;
-import javafx.scene.control.MenuBar;
-import javafx.scene.control.MenuButton;
-import javafx.scene.control.MenuItem;
-import javafx.scene.control.SplitMenuButton;
 import org.jemmy.action.GetAction;
-import org.jemmy.control.ControlInterfaces;
-import org.jemmy.control.ControlType;
-import org.jemmy.control.Wrap;
-import org.jemmy.fx.ByStyleClass;
-import org.jemmy.fx.Root;
-import org.jemmy.fx.SceneWrap;
-import org.jemmy.interfaces.Parent;
+import org.jemmy.control.*;
+import org.jemmy.dock.ObjectLookup;
+import org.jemmy.env.Environment;
+import org.jemmy.env.Timeout;
+import org.jemmy.fx.*;
+import org.jemmy.interfaces.*;
+import org.jemmy.lookup.ControlHierarchy;
 import org.jemmy.lookup.LookupCriteria;
+import org.jemmy.resources.StringComparePolicy;
 
-@ControlType({MenuItem.class})
-@ControlInterfaces(value = {Parent.class},
-        encapsulates = {MenuItem.class}, name={"asMenuParent"})
-
+/**
+ * This represents a single menu item within menu hierarchy. It could be looked 
+ * up starting from a menu bar, a menu button or a context menu.
+ * @see MenuBarWrap
+ * @author shura
+ * @param <ITEM> 
+ */
+@ControlType(MenuItem.class)
+@MethodProperties({"getId", "getStyle", "getText", "getUserData"})
 public class MenuItemWrap<ITEM extends MenuItem> extends Wrap<ITEM> {
 
-    protected Wrap menuWrap;
+    /**
+     * First mouse is moved into a menu component. If node is not activated 
+     * during this timeout, click is performed.
+     */
+    public static final Timeout BEFORE_CLICK_TO_EXPAND_SLEEP = new Timeout("menu.before.click.to.expand", 100);
+    
+    /**
+     * 
+     */
+    public static final String IS_SELECTED_PROP_NAME = "isSelected";
+
+    static {
+        Environment.getEnvironment().initTimeout(BEFORE_CLICK_TO_EXPAND_SLEEP);
+    }
+
+    /**
+     * Converts a text sample and a text comparison logic to lookup criteria.
+     * Looking for a MenuItem by text content is the most logical approach.
+     *
+     * @param <B>
+     * @param tp Text subclass
+     * @param text a text sample
+     * @param policy defines how to compare
+     * @return
+     */
+    @ObjectLookup("text and comparison policy")
+    public static <B extends MenuItem> LookupCriteria<B> textLookup(Class<B> tp, String text,
+            StringComparePolicy policy) {
+        return new ByText<B>(text, policy);
+    }
+
+    /**
+     * Constructs lookup criteria by an id value. By-id lookup is the most basic
+     * and the most reliable approach.
+     *
+     * @param <B>
+     * @param tp Node type
+     * @param id expected node id
+     * @return
+     * @see ByID
+     */
+    @ObjectLookup("id")
+    public static <B extends MenuItem> LookupCriteria<B> idLookup(Class<B> tp, String id) {
+        return new ByID<B>(id);
+    }
+    
+    private Wrap<?> placeholder = null;
+    private MenuShowable menuShowable = new MenuShowable();
+    private final NodeWrapper wrapper;
 
     /**
      *
      * @param env
      * @param item
-     * @param parentMenuWrap
+     * @param parentWrap
      */
-    public MenuItemWrap(ITEM item, Wrap parentMenuWrap) {
-        super(parentMenuWrap.getEnvironment(), item);
-        this.menuWrap = parentMenuWrap;
+    public MenuItemWrap(Environment env, ITEM item) {
+        super(env, item);
+        wrapper = new NodeWrapper(env);
     }
 
     @Override
     public Rectangle getScreenBounds() {
-        return getPlaceholder().getScreenBounds();
+        show();
+        return placeholder.getScreenBounds();
     }
 
-    private Wrap<Node> getPlaceholder() {
-        if (MenuBar.class.isAssignableFrom(menuWrap.getControl().getClass())) {
-            return ((Parent)menuWrap.as(Parent.class, Node.class)).lookup(Node.class, new LookupCriteria<Node>() {
-                public boolean check(Node node) {
-                    if (node.getProperties().get(MenuItem.class) == getControl()) {
-                        return true;
+    public Menu getParentMenu() {
+        return getParentMenu(getControl());
+    }
+
+    /**
+     * While a node been shown, all parent items are expanded so that the node 
+     * is visible and represented by a node.
+     * @return 
+     */
+    @As
+    public Showable asShowable() {
+        return menuShowable;
+    }
+
+    private void show() {
+        Menu parent = getControl().getParentMenu();
+        if (parent != null) {
+            expand(parent);
+        }
+        placeholder = findWrap(getControl());
+    }
+
+    private Menu getParentMenu(final MenuItem item) {
+        return new GetAction<Menu>() {
+
+            @Override
+            public void run(Object... os) throws Exception {
+                setResult(item.getParentMenu());
+            }
+        }.dispatch(getEnvironment());
+    }
+
+    private Wrap<? extends Node> findWrap(final MenuItem item) {
+        final Node[] menuControl = new Node[1];
+        final Menu parent = getParentMenu(item);
+        Root.ROOT.lookup(new LookupCriteria<Scene>() {
+
+            public boolean check(Node node, ControlHierarchy hierarchy) {
+                if (node.getProperties().get(Menu.class) != null) {
+                    System.out.println(node.toString());
+                    System.out.println(((MenuItem) node.getProperties().get(Menu.class)).getText());
+                }
+                if (node instanceof MenuButton && parent == null) {
+                    MenuButton mb = ((MenuButton) node);
+                    //menu button could be in menu bar or by itself
+                    if (item instanceof Menu) {
+                        //if in menu bar, it contains the same item
+                        //the item is not exposed, however, so, I have to compare 
+                        //first child
+                        if (mb.getItems().size() > 0
+                                && mb.getItems().get(0) == ((Menu) item).getItems().get(0)) {
+                            menuControl[0] = node;
+                            return true;
+                        }
                     }
-                    if (MenuButton.class.isAssignableFrom(node.getClass()) && ((MenuButton) node).getItems().containsAll(((Menu)getControl()).getItems())) {
-                        return true;
+                    //else, if the menu item is on it's own, it does not have 
+                    //a menu associated. Hence a top-level menu item
+                    //would be within its items
+                    for (MenuItem mi : ((MenuButton) node).getItems()) {
+                        if (mi == item) {
+                            //if so, expanf the menu button and keep loking
+                            new MenuButtonWrap<MenuButton>(getEnvironment(), mb).asExpandable().expand();
+                        }
                     }
+                } else if (node.getProperties().get(MenuItem.class) == item) {
+                    menuControl[0] = node;
+                    return true;
+                }
+                return check(hierarchy.getChildren(node), hierarchy);
+            }
+
+            public boolean check(List<?> nodes, ControlHierarchy hierarchy) {
+                if (nodes != null) {
+                    for (Object n : nodes) {
+                        if (check((Node) n, hierarchy)) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            }
+
+            public boolean check(final Scene cntrl) {
+                if (parent != null && !(cntrl.getWindow() instanceof ContextMenu)) {
                     return false;
                 }
-            }).wrap();
+                AbstractNodeHierarchy hierarchy = new AbstractNodeHierarchy(getEnvironment()) {
+
+                    public List<?> getControls() {
+                        return getChildren(cntrl.getRoot());
+                    }
+                };
+                System.out.println("checking scene " + cntrl.getWindow());
+                return check(hierarchy.getControls(), hierarchy);
+            }
+
+            @Override
+            public String toString() {
+                return "scene containing a node which has Menu.class property equal to " + item.getText() + " menu";
+            }
+        }).wait(1);
+        return wrapper.wrap(Node.class, menuControl[0]);
+    }
+
+    private void expand(final Menu menu) {
+        if (!MenuWrap.isShowing(menu, getEnvironment())) {
+            Menu parent = getParentMenu(menu);
+            if (parent != null) {
+                expand(parent);
+            }
+            Wrap<? extends Node> mWrap = findWrap(menu);
+            if (mWrap.getControl() instanceof MenuButton) {
+                mWrap.mouse().move();
+                getEnvironment().getTimeout(BEFORE_CLICK_TO_EXPAND_SLEEP).sleep();
+                if (!MenuWrap.isShowing(menu, getEnvironment())) {
+                    mWrap.mouse().click();
+                }
             } else {
-            if (MenuButton.class.isAssignableFrom(menuWrap.getControl().getClass())) {
-                if (new GetAction<Boolean>() {
-                    @Override
-                    public void run(Object... parameters) {
-                        setResult(!((MenuButton)menuWrap.getControl()).isShowing());
-                    }
-                }.dispatch(getEnvironment())) {
-                if (SplitMenuButton.class.isAssignableFrom(menuWrap.getControl().getClass())) {
-                    Parent parent = (Parent) menuWrap.as(Parent.class, Node.class);
-                    parent.lookup(Node.class, new ByStyleClass<Node>("arrow-button")).wrap().mouse().click();
-                } else {
-                    menuWrap.mouse().click();
-                }
+                mWrap.mouse().move();
             }
         }
+    }
 
-        Wrap<? extends Scene> popup_scene_wrap = Root.ROOT.lookup(new LookupCriteria<Scene>() {
-            public boolean check(Scene scene) {
-                if (!(scene.getWindow() instanceof ContextMenu)) {
-                    return false;
-                }
-                Wrap<Scene> scene_wrap = new SceneWrap(getEnvironment(), scene);
-                Parent<Node> parent = scene_wrap.as(Parent.class, Node.class);
-                return parent.lookup(Node.class, new LookupCriteria<Node>() {
-                    public boolean check(Node node) {
-                        if (node.getProperties().get(Menu.class) == getControl().getParentMenu()) {
-                            return true;
-                        }
-                        return false;
-                    }
-                }).size() > 0;
-            }
-        }).wrap();
-
-        return popup_scene_wrap.as(Parent.class, Node.class).lookup(Node.class, new LookupCriteria<Node>() {
-                public boolean check(Node node) {
-                    if (node.getProperties().get(MenuItem.class) == getControl()) {
-                        return true;
-                    }
-                    return false;
-                }
-            }).wrap();
-    }
-                }
-
+    /**
+     * @deprecated  Use docks
+     */
     public static class MenuByText implements LookupCriteria<MenuItem> {
 
         String str = null;
@@ -139,4 +259,44 @@
             return item.getText() != null && item.getText().contentEquals(str);
         }
     }
+
+    protected class SelectableImpl implements Selectable<Boolean>, Selector<Boolean> {
+
+        public List<Boolean> getStates() {
+            return CheckBoxWrap.booleanStates;
+        }
+
+        public Boolean getState() {
+            return getProperty(Boolean.class, IS_SELECTED_PROP_NAME);
+        }
+
+        public Selector<Boolean> selector() {
+            return this;
+        }
+
+        public Class<Boolean> getType() {
+            return Boolean.class;
+        }
+
+        public void select(Boolean state) {
+            if (!state.equals(getState())) {
+                mouse().click();
+                waitProperty(IS_SELECTED_PROP_NAME, state);
+            }
+        }
+    }
+
+    private class MenuShowable implements Showable, Show {
+
+        public MenuShowable() {
+        }
+
+        public Show shower() {
+            return this;
+        }
+
+        public void show() {
+            MenuItemWrap.this.show();
+        }
+    }
 }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuTreeSelectorImpl.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuTreeSelectorImpl.java	Mon Jul 16 20:11:41 2012 +0400
@@ -34,7 +34,7 @@
 class MenuTreeSelectorImpl implements TreeSelector {
     protected Parent<Menu> parent;
 
-    public MenuTreeSelectorImpl(Parent<Menu> parent) {
+    public MenuTreeSelectorImpl(Parent<Menu> parent/*, Environment env*/) {
         this.parent = parent;
     }
 
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/MenuWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -27,22 +27,24 @@
 import java.util.List;
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuItem;
+import org.jemmy.action.GetAction;
+import org.jemmy.control.As;
 import org.jemmy.control.ControlInterfaces;
 import org.jemmy.control.ControlType;
+import org.jemmy.control.MethodProperties;
+import org.jemmy.control.Property;
 import org.jemmy.control.Wrap;
+import org.jemmy.env.Environment;
 import org.jemmy.input.StringMenuOwner;
-import org.jemmy.interfaces.ControlInterface;
-import org.jemmy.interfaces.MenuOwner;
 import org.jemmy.interfaces.Parent;
-import org.jemmy.interfaces.TypeControlInterface;
 
 @ControlType({Menu.class})
 @ControlInterfaces(value = {Parent.class, StringMenuOwner.class},
         encapsulates = {MenuItem.class, MenuItem.class}, name={"asMenuParent"})
-
 public class MenuWrap<ITEM extends Menu> extends MenuItemWrap<ITEM> {
 
-    private StringMenuOwnerImpl menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class));
+    private StringMenuOwnerImpl menuOwner = null;
+    private Parent<MenuItem> parent = null;
 
     /**
      *
@@ -51,46 +53,50 @@
      * @param nd
      */
     @SuppressWarnings("unchecked")
-    public MenuWrap(ITEM item, Wrap parentMenuWrap) {
-        super(item, parentMenuWrap);
+    public MenuWrap(Environment env, ITEM item) {
+        super(env, item);
     }
 
-    @Override
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> boolean is(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.equals(interfaceClass)) {
-                return true;
-            }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return true;
-            }
+    @As(MenuItem.class)
+    public Parent<MenuItem> asMenuParent() {
+        if (parent == null) {
+            parent = new MenuItemParent(this) {
+
+                @Override
+                protected List getControls() {
+                    return new GetAction<List<?>>() {
+
+                        @Override
+                        public void run(Object... os) throws Exception {
+                            setResult(getControl().getItems());
+                        }
+                    }.dispatch(getEnvironment());
+                }
+            };
         }
-        return super.is(interfaceClass, type);
+        return parent;
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <INTERFACE extends ControlInterface> INTERFACE as(Class<INTERFACE> interfaceClass) {
-        // Default Parent is Parent<Node> which is super
-        return super.as(interfaceClass);
+    @As(MenuItem.class)
+    public StringMenuOwner<MenuItem> asMenuOwner() {
+        if(menuOwner == null) {
+             menuOwner = new StringMenuOwnerImpl(this, this.as(Parent.class, Menu.class));
+        }
+        return menuOwner;
     }
+    
+    @Property("isShowing")
+    public boolean isShowing() {
+        return isShowing(getControl(), getEnvironment());
+    }
+    
+    static boolean isShowing(final Menu menu, Environment env) {
+        return new GetAction<Boolean>() {
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public <TYPE, INTERFACE extends TypeControlInterface<TYPE>> INTERFACE as(Class<INTERFACE> interfaceClass, Class<TYPE> type) {
-        if (MenuItem.class.isAssignableFrom(type)) {
-            if (Parent.class.equals(interfaceClass)) {
-                return (INTERFACE) new AbstractMenuItemsParent(this, type) {
-                    @Override
-                    protected List getControls() {
-                        return getControl().getItems();
-                    }
-                };
+            @Override
+            public void run(Object... os) throws Exception {
+                setResult(menu.isShowing());
             }
-            if (MenuOwner.class.isAssignableFrom(interfaceClass)) {
-                return (INTERFACE) menuOwner;
-            }
-        }
-        return super.as(interfaceClass, type);
+        }.dispatch(env);
     }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/RadioMenuItemWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jemmy.fx.control;
+
+import javafx.scene.control.RadioMenuItem;
+import org.jemmy.control.*;
+import org.jemmy.env.Environment;
+import org.jemmy.interfaces.Selectable;
+
+/**
+ * This is a menu item and so could be found within the menu hierarchy. It could 
+ * also be selected/unselected.
+ * Please consult <a href="../../samples/menu">samples</a> for more info.
+ * @see MenuBarWrap
+ * @author shura
+ */
+@ControlType(RadioMenuItem.class)
+@MethodProperties(MenuItemWrap.IS_SELECTED_PROP_NAME)
+@ControlInterfaces(value=Selectable.class, encapsulates=Boolean.class)
+public class RadioMenuItemWrap<T extends RadioMenuItem>  extends MenuItemWrap<T> {
+    private final SelectableImpl selectable = new SelectableImpl();
+    
+    public RadioMenuItemWrap(Environment env, T item) {
+        super(env, item);
+    }
+    
+    @As(Boolean.class)
+    public Selectable<Boolean> asSelectable() {
+        return selectable;
+    }    
+}
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/StringMenuOwnerImpl.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/StringMenuOwnerImpl.java	Mon Jul 16 20:11:41 2012 +0400
@@ -38,7 +38,7 @@
  */
 class StringMenuOwnerImpl extends StringMenuOwner<MenuItem> {
 
-    Parent<Menu> parent;
+    private final Parent<Menu> parent;
     public StringMenuOwnerImpl(Wrap<?> wrap, Parent<Menu> parent) {
         super(wrap);
         this.parent = parent;
@@ -56,6 +56,9 @@
     public org.jemmy.interfaces.Menu menu() {
         return new MenuImpl(parent);
     }
+    
+    protected void prepare() {
+    }
 
     class MenuImpl extends MenuTreeSelectorImpl implements org.jemmy.interfaces.Menu {
         public MenuImpl(Parent<Menu> parent) {
@@ -63,6 +66,7 @@
         }
 
         public void push(LookupCriteria... criteria) {
+            prepare();
             select(criteria).mouse().click();
         }
     }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TabNodeHierarchy.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TabNodeHierarchy.java	Mon Jul 16 20:11:41 2012 +0400
@@ -24,6 +24,8 @@
  */
 package org.jemmy.fx.control;
 
+import java.util.ArrayList;
+import java.util.List;
 import javafx.scene.Node;
 import javafx.scene.control.Tab;
 import org.jemmy.env.Environment;
@@ -38,12 +40,13 @@
     protected Tab tab;
 
     public TabNodeHierarchy(Tab tab, Environment env) {
-        super(null, env);
+        super(env);
         this.tab = tab;
     }
 
-    @Override
-    protected Node getRoot() {
-        return tab.getContent();
+    public List<?> getControls() {
+        ArrayList<Object> res = new ArrayList<Object>();
+        res.add(tab.getContent());
+        return res;
     }
 }
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TableCellItemWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TableCellItemWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -54,7 +54,7 @@
 @ControlType(Object.class)
 @ControlInterfaces(value={WindowElement.class, EditableCell.class, Showable.class}, 
         encapsulates={TableView.class})
-@DockInfo(name="org.jemmy.fx.control.TableCellItemDock", multipleCriteria=false)
+@DockInfo(name="org.jemmy.fx.control.TableCellItemDock", generateSubtypeLookups=true, multipleCriteria=false)
 public class TableCellItemWrap<DATA extends Object> extends ItemWrap<DATA> implements Showable {
 
     @ObjectLookup("cell coordinates")
--- a/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TreeItemWrap.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/src/org/jemmy/fx/control/TreeItemWrap.java	Mon Jul 16 20:11:41 2012 +0400
@@ -70,7 +70,7 @@
      * @param path starting with a pattern for root ending with a pattern for the node
      * @return 
      */
-    @ObjectLookup("comparison policy and a toString of elements of the tree path")
+    //better to disable these for now @ObjectLookup("comparison policy and a toString of elements of the tree path")
     public static <T> LookupCriteria<T> byPathToString(Class<T> type, final StringComparePolicy policy,
             final String... path) {
         return new TreePathCriteria<T, String>(path) {
@@ -93,7 +93,7 @@
      * @param path starting with a value for root ending with a value for the node
      * @return 
      */
-    @ObjectLookup("elements of the tree path")
+    //better to disable these for now @ObjectLookup("elements of the tree path")
     public static <T> LookupCriteria<T> byPathValues(Class<T> type,
             final Object... path) {
         return new TreePathCriteria<T, Object>(path) {
@@ -116,7 +116,7 @@
      * @param path starting with a criteria for root ending with a criteria for the node
      * @return 
      */
-    @ObjectLookup("criteria for elements of the tree path")
+    //better to disable these for now @ObjectLookup("criteria for elements of the tree path")
     public static <T> LookupCriteria<T> byPathCriteria(final Class<T> type,
             final LookupCriteria<T>... path) {
         return new TreePathCriteria<T, LookupCriteria<T>>(path) {
--- a/tools/Jemmy/JemmyFX/test/org/jemmy/fx/control/TreeItemTest.java	Tue Jul 10 14:39:14 2012 +0400
+++ b/tools/Jemmy/JemmyFX/test/org/jemmy/fx/control/TreeItemTest.java	Mon Jul 16 20:11:41 2012 +0400
@@ -1,6 +1,26 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 package org.jemmy.fx.control;
 
@@ -64,23 +84,24 @@
                 "23", StringComparePolicy.SUBSTRING).asEditableCell().select();
     }
 
-    @Test
-    public void byToStringPath() {
-        new TreeItemDock(tree.asItemParent(), StringComparePolicy.EXACT, "0", "02", "023").asEditableCell().select();
-    }
-
-    @Test
-    public void byPath() {
-        new TreeItemDock(tree.asItemParent(), "0", "02", "024").asEditableCell().select();
-    }
-
-    @Test
-    public void byCriteriaPath() {
-        new TreeItemDock(tree.asItemParent(),
-                new EqualsLookup<Object>("0"),
-                new EqualsLookup<Object>("02"),
-                new EqualsLookup<Object>("025")).asEditableCell().select();
-    }
+    
+//    @Test
+//    public void byToStringPath() {
+//        new TreeItemDock(tree.asItemParent(), StringComparePolicy.EXACT, "0", "02", "023").asEditableCell().select();
+//    }
+//
+//    @Test
+//    public void byPath() {
+//        new TreeItemDock(tree.asItemParent(), "0", "02", "024").asEditableCell().select();
+//    }
+//
+//    @Test
+//    public void byCriteriaPath() {
+//        new TreeItemDock(tree.asItemParent(),
+//                new EqualsLookup<Object>("0"),
+//                new EqualsLookup<Object>("02"),
+//                new EqualsLookup<Object>("025")).asEditableCell().select();
+//    }
 
     @Test
     public void autoExpand() {