Introduce widget parameter for handle methods

Providing the additional widget as a typed parameter makes the handle
methods clearer.

Introduce 

* handleSet( widget, properties )
* handleCall( widget, properties )
diff --git a/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/ControlOperationHandler.java b/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/ControlOperationHandler.java
index ca7be02..789c068 100644
--- a/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/ControlOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/ControlOperationHandler.java
@@ -36,15 +36,15 @@
   /*
    * PROTOCOL NOTIFY FocusIn
    */
-  public void handleNotifyFocusIn( JsonObject properties ) {
-    widget.notifyListeners( SWT.FocusIn, new Event() );
+  public void handleNotifyFocusIn( T control, JsonObject properties ) {
+    control.notifyListeners( SWT.FocusIn, new Event() );
   }
 
   /*
    * PROTOCOL NOTIFY FocusOut
    */
-  public void handleNotifyFocusOut( JsonObject properties ) {
-    widget.notifyListeners( SWT.FocusOut, new Event() );
+  public void handleNotifyFocusOut( T control, JsonObject properties ) {
+    control.notifyListeners( SWT.FocusOut, new Event() );
   }
 
   /*
@@ -58,8 +58,8 @@
    * @param y (int) the y coordinate of the pointer
    * @param time (int) the time when the event occurred
    */
-  public void handleNotifyMouseDown( JsonObject properties ) {
-    processMouseEvent( SWT.MouseDown, widget, properties );
+  public void handleNotifyMouseDown( T control, JsonObject properties ) {
+    processMouseEvent( SWT.MouseDown, control, properties );
   }
 
   /*
@@ -73,8 +73,8 @@
    * @param y (int) the y coordinate of the pointer
    * @param time (int) the time when the event occurred
    */
-  public void handleNotifyMouseDoubleClick( JsonObject properties ) {
-    processMouseEvent( SWT.MouseDoubleClick, widget, properties );
+  public void handleNotifyMouseDoubleClick( T control, JsonObject properties ) {
+    processMouseEvent( SWT.MouseDoubleClick, control, properties );
   }
 
   /*
@@ -88,8 +88,8 @@
    * @param y (int) the y coordinate of the pointer
    * @param time (int) the time when the event occurred
    */
-  public void handleNotifyMouseUp( JsonObject properties ) {
-    processMouseEvent( SWT.MouseUp, widget, properties );
+  public void handleNotifyMouseUp( T control, JsonObject properties ) {
+    processMouseEvent( SWT.MouseUp, control, properties );
   }
 
   /*
@@ -101,8 +101,8 @@
    * @param keyCode (int) the key code of the key that was typed
    * @param charCode (int) the char code of the key that was typed
    */
-  public void handleNotifyTraverse( JsonObject properties ) {
-    processTraverseEvent( widget, properties );
+  public void handleNotifyTraverse( T control, JsonObject properties ) {
+    processTraverseEvent( control, properties );
   }
 
   /*
@@ -114,9 +114,9 @@
    * @param keyCode (int) the key code of the key that was typed
    * @param charCode (int) the char code of the key that was typed
    */
-  public void handleNotifyKeyDown( JsonObject properties ) {
-    widget.notifyListeners( SWT.KeyDown, createKeyEvent( properties ) );
-    widget.notifyListeners( SWT.KeyUp, createKeyEvent( properties ) );
+  public void handleNotifyKeyDown( T control, JsonObject properties ) {
+    control.notifyListeners( SWT.KeyDown, createKeyEvent( properties ) );
+    control.notifyListeners( SWT.KeyUp, createKeyEvent( properties ) );
   }
 
   /*
@@ -125,8 +125,8 @@
    * @param x (int) the x coordinate of the pointer
    * @param y (int) the y coordinate of the pointer
    */
-  public void handleNotifyMenuDetect( JsonObject properties ) {
-    widget.notifyListeners( SWT.MenuDetect, createMenuDetectEvent( properties ) );
+  public void handleNotifyMenuDetect( T control, JsonObject properties ) {
+    control.notifyListeners( SWT.MenuDetect, createMenuDetectEvent( properties ) );
   }
 
   static void processMouseEvent( int eventType, Control control, JsonObject properties ) {
diff --git a/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler.java b/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler.java
index 84fb852..766a872 100644
--- a/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler.java
@@ -30,7 +30,7 @@
 
 public abstract class WidgetOperationHandler<T extends Widget> extends AbstractOperationHandler {
 
-  protected final T widget;
+  private final T widget;
 
   public WidgetOperationHandler( T widget ) {
     this.widget = widget;
@@ -39,14 +39,14 @@
   @Override
   public void handleNotify( String eventName, JsonObject properties ) {
     try {
-      String name = "handleNotify" + eventName;
-      Method method = getClass().getMethod( name, JsonObject.class );
-      method.invoke( this, properties );
+      Method method = findNotifyMethod( eventName );
+      if( method == null ) {
+        String message = eventName + " notify operation not supported by this handler";
+        throw new UnsupportedOperationException( message );
+      }
+      method.invoke( this, widget, properties );
     } catch( SecurityException exception ) {
       throw new RuntimeException( exception );
-    } catch( NoSuchMethodException e ) {
-      String message = eventName + " notify operation not supported by this handler";
-      throw new UnsupportedOperationException( message );
     } catch( IllegalArgumentException exception ) {
       throw new RuntimeException( exception );
     } catch( IllegalAccessException exception ) {
@@ -56,6 +56,24 @@
     }
   }
 
+  @Override
+  public void handleSet( JsonObject properties ) {
+    handleSet( widget, properties );
+  }
+
+  @Override
+  public void handleCall( String method, JsonObject parameters ) {
+    handleCall( widget, method, parameters );
+  }
+
+  public void handleSet( T widget, JsonObject properties ) {
+    throw new UnsupportedOperationException( "set operations not supported by this handler" );
+  }
+
+  public void handleCall( T widget, String method, JsonObject parameters ) {
+    throw new UnsupportedOperationException( "call operations not supported by this handler" );
+  }
+
   /*
    * PROTOCOL NOTIFY Selection
    *
@@ -63,7 +81,7 @@
    * @param ctrlKey (boolean) true if the CTRL key was pressed
    * @param shiftKey (boolean) true if the SHIFT key was pressed
    */
-  public void handleNotifySelection( JsonObject properties ) {
+  public void handleNotifySelection( T widget, JsonObject properties ) {
     Event event = createSelectionEvent( SWT.Selection, properties );
     widget.notifyListeners( SWT.Selection, event );
   }
@@ -75,7 +93,7 @@
    * @param ctrlKey (boolean) true if the CTRL key was pressed
    * @param shiftKey (boolean) true if the SHIFT key was pressed
    */
-  public void handleNotifyDefaultSelection( JsonObject properties ) {
+  public void handleNotifyDefaultSelection( T widget, JsonObject properties ) {
     Event event = createSelectionEvent( SWT.DefaultSelection, properties );
     widget.notifyListeners( SWT.DefaultSelection, event );
   }
@@ -83,10 +101,27 @@
   /*
    * PROTOCOL NOTIFY Help
    */
-  public void handleNotifyHelp( JsonObject properties ) {
+  public void handleNotifyHelp( T widget, JsonObject properties ) {
     widget.notifyListeners( SWT.Help, new Event() );
   }
 
+  private Method findNotifyMethod( String eventName ) {
+    String name = "handleNotify" + eventName;
+    Method[] methods = getClass().getMethods();
+    for( Method method : methods ) {
+      if( name.equals( method.getName() ) ) {
+        Class<?>[] parameterTypes = method.getParameterTypes();
+        if( parameterTypes.length > 1
+            && parameterTypes[ 0 ].isAssignableFrom( widget.getClass() )
+            && parameterTypes[ 1 ] == JsonObject.class )
+        {
+          return method;
+        }
+      }
+    }
+    return null;
+  }
+
   protected static Event createSelectionEvent( int eventType, JsonObject properties ) {
     Event event = new Event();
     event.type = eventType;
diff --git a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/buttonkit/ButtonOperationHandler.java b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/buttonkit/ButtonOperationHandler.java
index 8aaea0e..99a7d4f 100644
--- a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/buttonkit/ButtonOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/buttonkit/ButtonOperationHandler.java
@@ -26,6 +26,11 @@
     super( button );
   }
 
+  @Override
+  public void handleSet( Button button, JsonObject properties ) {
+    handleSetSelection( button, properties );
+  }
+
   /*
    * PROTOCOL NOTIFY Selection
    *
@@ -34,8 +39,7 @@
    * @param shiftKey (boolean) true if the SHIFT key was pressed
    */
   @Override
-  public void handleNotifySelection( JsonObject properties ) {
-    Button button = widget;
+  public void handleNotifySelection( Button button, JsonObject properties ) {
     Event event = createSelectionEvent( SWT.Selection, properties );
     if( ( button.getStyle() & SWT.RADIO ) != 0 && !button.getSelection() ) {
       event.time = -1;
@@ -43,18 +47,12 @@
     button.notifyListeners( SWT.Selection, event );
   }
 
-  @Override
-  public void handleSet( JsonObject properties ) {
-    handleSetSelection( properties );
-  }
-
   /*
    * PROTOCOL SET selection
    *
    * @param selection (boolean) true if the button was selected, otherwise false
    */
-  private void handleSetSelection( JsonObject properties ) {
-    Button button = widget;
+  public void handleSetSelection( Button button, JsonObject properties ) {
     JsonValue selection = properties.get( PROP_SELECTION );
     if( selection != null ) {
       button.setSelection( selection.asBoolean() );
diff --git a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/combokit/ComboOperationHandler.java b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/combokit/ComboOperationHandler.java
index 0d40f71..111abc8 100644
--- a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/combokit/ComboOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/combokit/ComboOperationHandler.java
@@ -34,19 +34,19 @@
     super( combo );
   }
 
+  @Override
+  public void handleSet( Combo combo, JsonObject properties ) {
+    handleSetSelectionIndex( combo, properties );
+    handleSetListVisible( combo, properties );
+    handleSetText( combo, properties );
+    handleSetSelection( combo, properties );
+  }
+
   /*
    * PROTOCOL NOTIFY Modify
    * ignored, Modify event is fired when set text
    */
-  public void handleNotifyModify( JsonObject properties ) {
-  }
-
-  @Override
-  public void handleSet( JsonObject properties ) {
-    handleSetSelectionIndex( properties );
-    handleSetListVisible( properties );
-    handleSetText( properties );
-    handleSetSelection( properties );
+  public void handleNotifyModify( Combo control, JsonObject properties ) {
   }
 
   /*
@@ -54,8 +54,7 @@
    *
    * @param selectionIndex (int) the index of the item to select
    */
-  private void handleSetSelectionIndex( JsonObject properties ) {
-    Combo combo = widget;
+  public void handleSetSelectionIndex( Combo combo, JsonObject properties ) {
     JsonValue selectionIndex = properties.get( PROP_SELECTION_INDEX );
     if( selectionIndex != null ) {
       combo.select( selectionIndex.asInt() );
@@ -67,8 +66,7 @@
    *
    * @param listVisible (boolean) the visibility state of the list
    */
-  private void handleSetListVisible( JsonObject properties ) {
-    Combo combo = widget;
+  public void handleSetListVisible( Combo combo, JsonObject properties ) {
     JsonValue listVisible = properties.get( PROP_LIST_VISIBLE );
     if( listVisible != null ) {
       combo.setListVisible( listVisible.asBoolean() );
@@ -80,8 +78,7 @@
    *
    * @param text (string) the text
    */
-  private void handleSetText( JsonObject properties ) {
-    final Combo combo = widget;
+  public void handleSetText( final Combo combo, JsonObject properties ) {
     final JsonValue value = properties.get( PROP_TEXT );
     if( value != null ) {
       final String text = value.asString();
@@ -108,8 +105,7 @@
    * @param selectionStart (int) the text selection start
    * @param selectionLength (int) the text selection length
    */
-  private void handleSetSelection( JsonObject properties ) {
-    Combo combo = widget;
+  public void handleSetSelection( Combo combo, JsonObject properties ) {
     JsonValue selectionStart = properties.get( PROP_SELECTION_START );
     JsonValue selectionLength = properties.get( PROP_SELECTION_LENGTH );
     if( selectionStart != null || selectionLength != null ) {
diff --git a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treecolumnkit/TreeColumnOperationHandler.java b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treecolumnkit/TreeColumnOperationHandler.java
index 6ce4fc1..bfc78f9 100644
--- a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treecolumnkit/TreeColumnOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treecolumnkit/TreeColumnOperationHandler.java
@@ -34,11 +34,11 @@
   }
 
   @Override
-  public void handleCall( String method, JsonObject properties ) {
+  public void handleCall( TreeColumn column, String method, JsonObject properties ) {
     if( method.equals( METHOD_MOVE ) ) {
-      handleCallMove( properties );
+      handleCallMove( column, properties );
     } else if( method.equals( METHOD_RESIZE ) ) {
-      handleCallResize( properties );
+      handleCallResize( column, properties );
     }
   }
 
@@ -47,8 +47,7 @@
    *
    * @left (int) the left position of the column
    */
-  private void handleCallMove( JsonObject properties ) {
-    final TreeColumn column = widget;
+  public void handleCallMove( final TreeColumn column, JsonObject properties ) {
     final int newLeft = properties.get( PROP_LEFT ).asInt();
     ProcessActionRunner.add( new Runnable() {
       public void run() {
@@ -62,8 +61,7 @@
    *
    * @width (int) the width of the column
    */
-  private void handleCallResize( JsonObject properties ) {
-    final TreeColumn column = widget;
+  public void handleCallResize( final TreeColumn column, JsonObject properties ) {
     final int width = properties.get( PROP_WIDTH ).asInt();
     ProcessActionRunner.add( new Runnable() {
       public void run() {
diff --git a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treeitemkit/TreeItemOperationHandler.java b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treeitemkit/TreeItemOperationHandler.java
index 94de47f..6304d01 100644
--- a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treeitemkit/TreeItemOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treeitemkit/TreeItemOperationHandler.java
@@ -29,9 +29,9 @@
   }
 
   @Override
-  public void handleSet( JsonObject properties ) {
-    handleSetChecked( properties );
-    handleSetExpanded( properties );
+  public void handleSet( TreeItem item, JsonObject properties ) {
+    handleSetChecked( item, properties );
+    handleSetExpanded( item, properties );
   }
 
   /*
@@ -39,8 +39,7 @@
    *
    * @param checked (boolean) true if the item was checked, false otherwise
    */
-  private void handleSetChecked( JsonObject properties ) {
-    TreeItem item = widget;
+  public void handleSetChecked( TreeItem item, JsonObject properties ) {
     JsonValue checked = properties.get( PROP_CHECKED );
     if( checked != null ) {
       item.setChecked( checked.asBoolean() );
@@ -52,8 +51,7 @@
    *
    * @param expanded (boolean) true if the item was expanded, false otherwise
    */
-  private void handleSetExpanded( JsonObject properties ) {
-    final TreeItem item = widget;
+  public void handleSetExpanded( final TreeItem item, JsonObject properties ) {
     final JsonValue expanded = properties.get( PROP_EXPANDED );
     if( expanded != null ) {
       ProcessActionRunner.add( new Runnable() {
diff --git a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treekit/TreeOperationHandler.java b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treekit/TreeOperationHandler.java
index 4fc01b6..e78db4b 100644
--- a/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treekit/TreeOperationHandler.java
+++ b/bundles/org.eclipse.rap.rwt/widgetkits/org/eclipse/swt/internal/widgets/treekit/TreeOperationHandler.java
@@ -41,6 +41,20 @@
     super( tree );
   }
 
+  @Override
+  public void handleSet( Tree tree, JsonObject properties ) {
+    handleSetSelection( tree, properties );
+    handleSetScrollLeft( tree, properties );
+    handleSetTopItemIndex( tree, properties );
+  }
+
+  @Override
+  public void handleCall( Tree tree, String method, JsonObject properties ) {
+    if( method.equals( METHOD_RENDER_TOOLTIP_TEXT ) ) {
+      handleCallRenderToolTipText( tree, properties );
+    }
+  }
+
   /*
    * PROTOCOL NOTIFY Selection
    *
@@ -51,10 +65,10 @@
    * @item item (string) id of selected item
    */
   @Override
-  public void handleNotifySelection( JsonObject properties ) {
+  public void handleNotifySelection( Tree tree, JsonObject properties ) {
     Event event = createSelectionEvent( SWT.Selection, properties );
-    event.item = getItem( properties.get( EVENT_PARAM_ITEM ).asString() );
-    widget.notifyListeners( SWT.Selection, event );
+    event.item = getItem( tree, properties.get( EVENT_PARAM_ITEM ).asString() );
+    tree.notifyListeners( SWT.Selection, event );
   }
 
   /*
@@ -67,10 +81,10 @@
    * @item item (string) id of selected item
    */
   @Override
-  public void handleNotifyDefaultSelection( JsonObject properties ) {
+  public void handleNotifyDefaultSelection( Tree tree, JsonObject properties ) {
     Event event = createSelectionEvent( SWT.DefaultSelection, properties );
-    event.item = getItem( properties.get( EVENT_PARAM_ITEM ).asString() );
-    widget.notifyListeners( SWT.DefaultSelection, event );
+    event.item = getItem( tree, properties.get( EVENT_PARAM_ITEM ).asString() );
+    tree.notifyListeners( SWT.DefaultSelection, event );
   }
 
   /*
@@ -78,10 +92,10 @@
    *
    * @item item (string) id of expanded item
    */
-  public void handleNotifyExpand( JsonObject properties ) {
+  public void handleNotifyExpand( Tree tree, JsonObject properties ) {
     Event event = new Event();
-    event.item = getItem( properties.get( EVENT_PARAM_ITEM ).asString() );
-    widget.notifyListeners( SWT.Expand, event );
+    event.item = getItem( tree, properties.get( EVENT_PARAM_ITEM ).asString() );
+    tree.notifyListeners( SWT.Expand, event );
   }
 
   /*
@@ -89,44 +103,10 @@
    *
    * @item item (string) id of collapsed item
    */
-  public void handleNotifyCollapse( JsonObject properties ) {
+  public void handleNotifyCollapse( Tree tree, JsonObject properties ) {
     Event event = new Event();
-    event.item = getItem( properties.get( EVENT_PARAM_ITEM ).asString() );
-    widget.notifyListeners( SWT.Collapse, event );
-  }
-
-  @Override
-  public void handleCall( String method, JsonObject properties ) {
-    if( method.equals( METHOD_RENDER_TOOLTIP_TEXT ) ) {
-      handleCallRenderToolTipText( properties );
-    }
-  }
-
-  /*
-   * PROTOCOL CALL renderToolTipText
-   *
-   * @item (string) id of the hovered item
-   * @column (int) column index of the hovered cell
-   */
-  private void handleCallRenderToolTipText( JsonObject properties ) {
-    Tree tree = widget;
-    ICellToolTipAdapter adapter = CellToolTipUtil.getAdapter( tree );
-    adapter.setCellToolTipText( null );
-    ICellToolTipProvider provider = adapter.getCellToolTipProvider();
-    if( provider != null ) {
-      TreeItem item = getItem( properties.get( "item" ).asString() );
-      int columnIndex = properties.get( "column" ).asInt();
-      if( item != null && ( columnIndex == 0 || columnIndex < tree.getColumnCount() ) ) {
-        provider.getToolTipText( item, columnIndex );
-      }
-    }
-  }
-
-  @Override
-  public void handleSet( JsonObject properties ) {
-    handleSetSelection( properties );
-    handleSetScrollLeft( properties );
-    handleSetTopItemIndex( properties );
+    event.item = getItem( tree, properties.get( EVENT_PARAM_ITEM ).asString() );
+    tree.notifyListeners( SWT.Collapse, event );
   }
 
   /*
@@ -134,15 +114,14 @@
    *
    * @param selection ([string]) array with ids of selected items
    */
-  private void handleSetSelection( JsonObject properties ) {
-    Tree tree = widget;
+  public void handleSetSelection( Tree tree, JsonObject properties ) {
     JsonValue values = properties.get( PROP_SELECTION );
     if( values != null ) {
       JsonArray itemIds = values.asArray();
       TreeItem[] selectedItems = new TreeItem[ itemIds.size() ];
       boolean validItemFound = false;
       for( int i = 0; i < itemIds.size(); i++ ) {
-        selectedItems[ i ] = getItem( itemIds.get( i ).asString() );
+        selectedItems[ i ] = getItem( tree, itemIds.get( i ).asString() );
         if( selectedItems[ i ] != null ) {
           validItemFound = true;
         }
@@ -159,8 +138,7 @@
    *
    * @param scrollLeft (int) left scroll offset in pixels
    */
-  private void handleSetScrollLeft( JsonObject properties ) {
-    Tree tree = widget;
+  public void handleSetScrollLeft( Tree tree, JsonObject properties ) {
     JsonValue value = properties.get( PROP_SCROLL_LEFT );
     if( value != null ) {
       int scrollLeft = value.asInt();
@@ -174,8 +152,7 @@
    *
    * @param topItemIndex (int) visual index of the item, which is on the top of the tree
    */
-  private void handleSetTopItemIndex( JsonObject properties ) {
-    Tree tree = widget;
+  public void handleSetTopItemIndex( Tree tree, JsonObject properties ) {
     JsonValue value = properties.get( PROP_TOP_ITEM_INDEX );
     if( value != null ) {
       int topItemIndex = value.asInt();
@@ -185,8 +162,26 @@
     }
   }
 
-  private TreeItem getItem( String itemId ) {
-    Tree tree = widget;
+  /*
+   * PROTOCOL CALL renderToolTipText
+   *
+   * @item (string) id of the hovered item
+   * @column (int) column index of the hovered cell
+   */
+  public void handleCallRenderToolTipText( Tree tree, JsonObject properties ) {
+    ICellToolTipAdapter adapter = CellToolTipUtil.getAdapter( tree );
+    adapter.setCellToolTipText( null );
+    ICellToolTipProvider provider = adapter.getCellToolTipProvider();
+    if( provider != null ) {
+      TreeItem item = getItem( tree, properties.get( "item" ).asString() );
+      int columnIndex = properties.get( "column" ).asInt();
+      if( item != null && ( columnIndex == 0 || columnIndex < tree.getColumnCount() ) ) {
+        provider.getToolTipText( item, columnIndex );
+      }
+    }
+  }
+
+  private TreeItem getItem( Tree tree, String itemId ) {
     TreeItem item = null;
     String[] idParts = itemId.split( "#" );
     if( idParts.length == 2 ) {
diff --git a/tests/org.eclipse.rap.rwt.test/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler_Test.java b/tests/org.eclipse.rap.rwt.test/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler_Test.java
new file mode 100644
index 0000000..f8f1017
--- /dev/null
+++ b/tests/org.eclipse.rap.rwt.test/src/org/eclipse/rap/rwt/internal/protocol/WidgetOperationHandler_Test.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2013 EclipseSource and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    EclipseSource - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.rap.rwt.internal.protocol;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import org.eclipse.rap.json.JsonObject;
+import org.eclipse.swt.widgets.Widget;
+import org.junit.Test;
+
+
+public class WidgetOperationHandler_Test {
+
+  @Test
+  public void testHandleSet_delegatesToHandleSetWithWidget() {
+    Widget widget = mock( Widget.class );
+    JsonObject properties = new JsonObject();
+    WidgetOperationHandler<Widget> handler = spy( new TestWidgetOperationHandler( widget ) );
+
+    handler.handleSet( properties );
+
+    verify( handler ).handleSet( widget, properties );
+  }
+
+  @Test( expected = UnsupportedOperationException.class )
+  public void testHandleSet_throwsExceptionIfNotSupported() {
+    Widget widget = mock( Widget.class );
+    JsonObject properties = new JsonObject();
+    WidgetOperationHandler<Widget> handler = spy( new WidgetOperationHandler<Widget>( widget ) {} );
+
+    handler.handleSet( properties );
+  }
+
+  @Test
+  public void testHandleCall_delegatesToHandleCallWithWidget() {
+    Widget widget = mock( Widget.class );
+    JsonObject properties = new JsonObject();
+    WidgetOperationHandler<Widget> handler = spy( new TestWidgetOperationHandler( widget ) );
+
+    handler.handleCall( "foo", properties );
+
+    verify( handler ).handleCall( widget, "foo", properties );
+  }
+
+  @Test( expected = UnsupportedOperationException.class )
+  public void testHandleCall_throwsExceptionIfNotSupported() {
+    Widget widget = mock( Widget.class );
+    JsonObject properties = new JsonObject();
+    WidgetOperationHandler<Widget> handler = spy( new WidgetOperationHandler<Widget>( widget ) {} );
+
+    handler.handleCall( "foo", properties );
+  }
+
+  private static class TestWidgetOperationHandler extends WidgetOperationHandler<Widget> {
+
+    private TestWidgetOperationHandler( Widget widget ) {
+      super( widget );
+    }
+
+    @Override
+    public void handleSet( Widget widget, JsonObject properties ) {
+    }
+
+    @Override
+    public void handleCall( Widget widget, String method, JsonObject parameters ) {
+    }
+
+  }
+
+}