bug 252628, bug 251488:
- Actions converted to command handlers
- Document and context menu contributed via "org.eclipse.ui.menus" (see bug 251488)
- Enablement/visibility declaratively managed by "org.eclipse.ui.services"
- Naming and placing of menu items aligned with Eclipse UI convention (e.g. in contrast to documents/files which are created with 'New...' and deleted with 'Delete' smaller parts are "Add"ed and "Remove"d; Document and context menu rearranged)
- Refactoring to avoid duplicated code (e.g. by introducing some abstract handlers)
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/META-INF/MANIFEST.MF b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/META-INF/MANIFEST.MF
index 467baaf..37fda95 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/META-INF/MANIFEST.MF
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/META-INF/MANIFEST.MF
@@ -1,9 +1,9 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin.name
+Bundle-Name: %pluginName
 Bundle-Version: 0.5.0.qualifier
 Bundle-Activator: org.eclipse.wst.xml.vex.ui.internal.VexPlugin
-Bundle-Vendor: %Bundle-Vendor.0
+Bundle-Vendor: %providerName
 Bundle-SymbolicName: org.eclipse.wst.xml.vex.ui;singleton:=true
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.ui;bundle-version="[3.4.0,4.0.0)",
@@ -21,10 +21,10 @@
  org.eclipse.wst.xml.ui;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.emf.ecore;bundle-version="[2.4.1,3.0.0)"
 Export-Package: org.eclipse.wst.xml.vex.ui.internal;x-internal:=true,
- org.eclipse.wst.xml.vex.ui.internal.action;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.config;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.contentassist;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.editor;x-internal:=true,
+ org.eclipse.wst.xml.vex.ui.internal.handlers;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.outline;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.perspective;x-internal:=true,
  org.eclipse.wst.xml.vex.ui.internal.property;x-internal:=true,
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.properties b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.properties
index be27ce7..781a525 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.properties
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.properties
@@ -2,7 +2,8 @@
 # Language-specific strings in plugin.xml
 #
 
-plugin.name=Vex XML Editor
+pluginName= Vex XML Editor
+providerName= Eclipse Web Tools Platform (WTP) Incubator Project
 
 BuildProblemDecorator.name=Vex Plug-in Build Problem Decorator
 ConfigurationView.name=Vex Configuration
@@ -20,54 +21,60 @@
 StylePropertyPage.name=Vex Style
 VexCommandCategory.name=Vex XML Editor
 VexEditor.name=Vex XML Editor
-VexEditor.multipage.name=VEX Multipage XML Editor
+VexEditor.multipage.name=Vex Multipage XML Editor
 VexEditorContext.name=Editing XML Documents
 VexViewCategory.name=Vex
 
 extensionPoint.doctypes=Vex Document Types
 extensionPoint.styles=Vex Styles
 
-documentActions.label=XML Editing Actions
+command.category.name= Vex - Visual Editor for XML 
+command.addElement.name= Add Element...
+command.duplicateSelection.name= &Duplicate Selection
+command.convertElement.name= Convert Element To...
+# dynamic names for 'Remove Tag' see org.eclipse.wst.xml.vex.ui.internal.editor.messages.properties
+command.removeTag.name= Remove Tag
+# dynamic names for 'Remove Tag' see org.eclipse.wst.xml.vex.ui.internal.editor.messages.properties
+command.addRowAbove.name= Add Row Above
+command.addRowBelow.name= Add Row Below
+command.moveRowUp.name= Move Row Up
+command.moveRowDown.name= Move Row Down
+command.removeRow.name= Remove Row
+command.addColumnLeft.name= Add Column to the Left
+command.addColumnRight.name= Add Column to the Right
+command.moveColumnLeft.name= Move Column Left
+command.moveColumnRight.name= Move Column Right
+command.removeColumn.name= Remove Column
+command.previousTableCell.name= Previous Table Cell
+command.nextTableCell.name= Next Table Cell
+command.splitBlockElement.name= Split Block Element
+command.splitItem.name= Split Item
 
-documentMenu.label=&Document
-insertMenu.label=&Insert
-rowMenu.label=&Row
-columnMenu.label=&Column
-
-#
-# Actions
-#
-# NOTE: THESE MUST BE KEPT IN SYNC WITH THE SAME BLOCK IN 
-#       src/net/sf/vex/editor/messages.properties
-#
-# Note: when there are multiple labels for an action, the one named
-# Xxx.label is the command listed in the key bindings preference page.
-#
-ChangeElementAction.label=Change Element
-ChangeElementAction.menu.label=&Change Element...
-DeleteColumnAction.label=Delete Column
-DeleteRowAction.label=Delete Row
-DuplicateSelectionAction.label=&Duplicate Selection
-InsertColumnAfterAction.label=Insert Column After
-InsertColumnBeforeAction.label=Insert Column Before
-InsertElementAction.label=Insert Element
-InsertElementAction.mainmenu.label=&Element...
-InsertRowAboveAction.label=Insert Row Above
-InsertRowBelowAction.label=Insert Row Below
-MoveColumnLeftAction.label=Move Column Left
-MoveColumnRightAction.label=Move Column Right
-MoveRowDownAction.label=Move Row Down
-MoveRowUpAction.label=Move Row Up
-NextTableCellAction.label=Next Table Cell
-PasteTextAction.label=Paste Text
-PreviousTableCellAction.label=Previous Table Cell
-RemoveElementAction.label=Remove Element
-RestoreLastSelectionAction.label=Restore Last Selection
-SplitAction.label=Split Block Element
-SplitItemAction.label=Split Item
-
-#
-# End of Actions
-#
-
-Bundle-Vendor.0 = vex.sf.net
\ No newline at end of file
+menu.Document.name= &Document
+menu.Add.name= &Add
+menu.Add.Element.name= &Element...
+menu.Add.RowAbove.name= Row &Above
+menu.Add.RowBelow.name= Row &Below
+menu.Add.ColumnLeft.name= Column to the &Left
+menu.Add.ColumnRight.name= Column to the &Right
+menu.Move.name= &Move
+menu.Move.RowUp= Row &Up
+menu.Move.RowDown= Row &Down
+menu.Move.ColumnLeft= Column &Left
+menu.Move.ColumnRight= Column &Right
+menu.Remove.name= &Remove
+menu.Remove.Row.name= &Row
+menu.Remove.Column.name= &Column
+menu.Row.name= Row
+menu.Row.AddAbove.name= Add Above
+menu.Row.AddBelow.name= Add Below
+menu.Row.MoveUp.name= Move Up
+menu.Row.MoveDown.name= Move Down
+menu.Row.Remove.name= Remove
+menu.Column.name= Column
+menu.Column.AddLeft.name= Add to the Left
+menu.Column.AddRight.name= Add to the Right
+menu.Column.MoveLeft.name= Move Left
+menu.Column.MoveRight.name= Move Right
+menu.Column.Remove.name= Remove
+menu.Style.name= Style
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.xml b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.xml
index cd3a3ec..faa535d 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.xml
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin.xml
@@ -5,123 +5,6 @@
    <extension-point id="doctypes" name="%extensionPoint.doctypes" schema="schema/doctype.exsd"/>
    <extension-point id="styles" name="%extensionPoint.styles" schema="schema/style.exsd"/>
 
-   <extension
-         point="org.eclipse.ui.actionSets">
-      <actionSet id="org.eclipse.wst.xml.vex.ui.documentActions"
-            label="%documentActions.label"
-            visible="true">
-         <menu id="org.eclipse.wst.xml.vex.ui.documentMenu"
-               label="%documentMenu.label"
-               path="additions">
-            <separator name="insert"/>
-            <separator name="modify"/>
-            <separator name="table"/>
-         </menu>
-         <menu id="org.eclipse.wst.xml.vex.ui.insertMenu"
-               label="%insertMenu.label"
-               path="org.eclipse.wst.xml.vex.ui.documentMenu/insert">
-            <separator name="items"/>
-         </menu>
-         <menu id="org.eclipse.wst.xml.vex.ui.columnMenu"
-               label="%columnMenu.label"
-               path="org.eclipse.wst.xml.vex.ui.documentMenu/table">
-            <separator name="items"/>
-         </menu>
-         <menu id="org.eclipse.wst.xml.vex.ui.rowMenu"
-               label="%rowMenu.label"
-               path="org.eclipse.wst.xml.vex.ui.documentMenu/table">
-            <separator name="items"/>
-         </menu>
-               
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.PasteTextAction"
-                 label="%PasteTextAction.label"
-                 menubarPath="edit/cut.ext"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.RestoreLastSelectionAction"
-                 label="%RestoreLastSelectionAction.label"
-                 menubarPath="edit/editEnd"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.InsertElementAction"
-                 label="%InsertElementAction.mainmenu.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.insertMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.DuplicateSelectionAction"
-                 label="%DuplicateSelectionAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/modify"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate"
-                 definitionId="org.eclipse.wst.xml.vex.ui.action.DuplicateSelectionAction">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.RemoveElementAction"
-                 label="%RemoveElementAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/modify"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate"
-                 definitionId="org.eclipse.wst.xml.vex.ui.action.RemoveElementAction">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.ChangeElementAction"
-                 label="%ChangeElementAction.menu.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/modify"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.MoveRowDownAction"
-                 label="%MoveRowDownAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.rowMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.MoveRowUpAction"
-                 label="%MoveRowUpAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.rowMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.DeleteRowAction"
-                 label="%DeleteRowAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.rowMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.InsertRowBelowAction"
-                 label="%InsertRowBelowAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.rowMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.InsertRowAboveAction"
-                 label="%InsertRowAboveAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.rowMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnRightAction"
-                 label="%MoveColumnRightAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.columnMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnLeftAction"
-                 label="%MoveColumnLeftAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.columnMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.DeleteColumnAction"
-                 label="%DeleteColumnAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.columnMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnAfterAction"
-                 label="%InsertColumnAfterAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.columnMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-         <action id="org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnBeforeAction"
-                 label="%InsertColumnBeforeAction.label"
-                 menubarPath="org.eclipse.wst.xml.vex.ui.documentMenu/org.eclipse.wst.xml.vex.ui.columnMenu/items"
-                 class="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionDelegate">
-         </action>
-
-      </actionSet>
-   </extension>
  
    <extension
          point="org.eclipse.ui.editors">
@@ -133,23 +16,19 @@
             contributorClass="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionBarContributor"
             id="org.eclipse.wst.xml.vex.ui.VexEditor">
       </editor>
+      <editor
+            class="org.eclipse.wst.xml.vex.ui.internal.editor.VEXMultiPageEditorPart"
+            contributorClass="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionBarContributor"
+            icon="$nl$/vex16.gif"
+            id="org.eclipse.wst.xml.vex.ui.VexEditorMultiPage"
+            name="%VexEditor.multipage.name"
+            symbolicFontName="org.eclipse.wst.sse.ui.textfont">
+         <contentTypeBinding
+               contentTypeId="org.eclipse.core.runtime.xml">
+         </contentTypeBinding>
+      </editor>
    </extension>
 
-   	<extension point="org.eclipse.ui.editors">
-		<editor
-			name="%VexEditor.multipage.name"
-			icon="$nl$/vex16.gif"
-			contributorClass="org.eclipse.wst.xml.vex.ui.internal.editor.VexActionBarContributor"
-			class="org.eclipse.wst.xml.vex.ui.internal.editor.VEXMultiPageEditorPart"
-			symbolicFontName="org.eclipse.wst.sse.ui.textfont"
-			id="org.eclipse.wst.xml.vex.ui.VexEditorMultiPage">
-			<contentTypeBinding
-				contentTypeId="org.eclipse.core.runtime.xml" />
-<!--			<contentTypeBinding
-				contentTypeId="org.eclipse.wst.xml.core.xmlsource" />
--->				
-		</editor>
-	</extension>
     
    <extension
          point="org.eclipse.ui.newWizards">
@@ -186,112 +65,378 @@
    <extension
          point="org.eclipse.ui.commands">
       <category
-            name="%VexCommandCategory.name"
-            id="org.eclipse.wst.xml.vex.ui.VexCommandCategory">
+            id="org.eclipse.wst.xml.vex.ui.commands.category"
+            name="%command.category.name">
       </category>
       <command
-            name="%ChangeElementAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.ChangeElementAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.AddElementCommand"
+            name="%command.addElement.name">
       </command>
       <command
-            name="%DeleteColumnAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.DeleteColumnAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.DuplicateSelectionCommand"
+            name="%command.duplicateSelection.name">
       </command>
       <command
-            name="%DeleteRowAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.DeleteRowAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.ConvertElementCommand"
+            name="%command.convertElement.name">
       </command>
       <command
-            name="%DuplicateSelectionAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.DuplicateSelectionAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.RemoveTagCommand"
+            name="%command.removeTag.name">
       </command>
       <command
-            name="%InsertColumnAfterAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.InsertColumnAfterAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.AddRowAboveCommand"
+            name="%command.addRowAbove.name">
       </command>
       <command
-            name="%InsertColumnBeforeAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.InsertColumnBeforeAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.AddRowBelowCommand"
+            name="%command.addRowBelow.name">
       </command>
       <command
-            name="%InsertElementAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.InsertElementAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.MoveRowUpCommand"
+            name="%command.moveRowUp.name">
       </command>
       <command
-            name="%InsertRowAboveAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.InsertRowAboveAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.MoveRowDownCommand"
+            name="%command.moveRowDown.name">
       </command>
       <command
-            name="%InsertRowBelowAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.InsertRowBelowAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.RemoveRowCommand"
+            name="%command.removeRow.name">
       </command>
       <command
-            name="%MoveColumnLeftAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.MoveColumnLeftAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.AddColumnLeftCommand"
+            name="%command.addColumnLeft.name">
       </command>
       <command
-            name="%MoveColumnRightAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.MoveColumnRightAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.AddColumnRightCommand"
+            name="%command.addColumnRight.name">
       </command>
       <command
-            name="%MoveRowDownAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.MoveRowDownAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.MoveColumnLeftCommand"
+            name="%command.moveColumnLeft.name">
       </command>
       <command
-            name="%MoveRowUpAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.MoveRowUpAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.MoveColumnRightCommand"
+            name="%command.moveColumnRight.name">
       </command>
       <command
-            name="%NextTableCellAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.NextTableCellAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.RemoveColumnCommand"
+            name="%command.removeColumn.name">
       </command>
       <command
-            name="%PasteTextAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.PasteTextAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.PreviousTableCellCommand"
+            name="%command.previousTableCell.name">
       </command>
       <command
-            name="%PreviousTableCellAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.PreviousTableCellAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.NextTableCellCommand"
+            name="%command.nextTableCell.name">
       </command>
       <command
-            name="%RemoveElementAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.RemoveElementAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.SplitBlockElementCommand"
+            name="%command.splitBlockElement.name">
       </command>
       <command
-            name="%RestoreLastSelectionAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.RestoreLastSelectionAction">
-      </command>
-      <command
-            name="%SplitAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.SplitAction">
-      </command>
-      <command
-            name="%SplitItemAction.label"
-            categoryId="org.eclipse.wst.xml.vex.ui.VexCommandCategory"
-            id="org.eclipse.wst.xml.vex.ui.action.SplitItemAction">
+            categoryId="org.eclipse.wst.xml.vex.ui.commands.category"
+            id="org.eclipse.wst.xml.vex.ui.SplitItemCommand"
+            name="%command.splitItem.name">
       </command>
       
    </extension>
    <extension
+         point="org.eclipse.ui.bindings">
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.AddElementCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="M1+SPACE">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.DuplicateSelectionCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="M1+M3+ARROW_DOWN"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+         
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.ConvertElementCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="M1+M3+SPACE"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.NextTableCellCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="TAB"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.PreviousTableCellCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="M2+TAB"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.RemoveTagCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="M2+DEL"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.SplitBlockElementCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="RETURN"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>
+      <key
+            commandId="org.eclipse.wst.xml.vex.ui.SplitItemCommand"
+            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
+            sequence="M2+RETURN"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </key>key>
+
+   </extension>
+   <extension
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.AddElementHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.AddElementCommand">
+         <activeWhen>
+            <reference
+                  definitionId="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+            </reference>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.DuplicateSelectionHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.DuplicateSelectionCommand">
+         <activeWhen>
+            <reference
+                  definitionId="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+            </reference>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.ConvertElementHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.ConvertElementCommand">
+         <activeWhen>
+            <reference
+                  definitionId="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+            </reference>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.RemoveTagHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.RemoveTagCommand">
+         <activeWhen>
+            <reference
+                  definitionId="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+            </reference>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.AddRowAboveHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.AddRowAboveCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isRow">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.AddRowBelowHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.AddRowBelowCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isRow">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.MoveRowUpHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.MoveRowUpCommand">
+         <enabledWhen>
+            <and>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isRow">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isFirstRow">
+                  <equals
+                        value="false">
+                  </equals>
+               </with>
+            </and>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.MoveRowDownHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.MoveRowDownCommand">
+         <enabledWhen>
+            <and>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isRow">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isLastRow">
+                  <equals
+                        value="false">
+                  </equals>
+               </with>
+            </and>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.RemoveRowHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.RemoveRowCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isRow">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.AddColumnLeftHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.AddColumnLeftCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isColumn">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.AddColumnRightHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.AddColumnRightCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isColumn">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.MoveColumnLeftHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.MoveColumnLeftCommand">
+         <enabledWhen>
+            <and>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isColumn">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isFirstColumn">
+                  <equals
+                        value="false">
+                  </equals>
+               </with>
+            </and>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.MoveColumnRightHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.MoveColumnRightCommand">
+         <enabledWhen>
+            <and>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isColumn">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isLastColumn">
+                  <equals
+                        value="false">
+                  </equals>
+               </with>
+            </and>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.RemoveColumnHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.RemoveColumnCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isColumn">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.NextTableCellHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.NextTableCellCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isRow">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.PreviousTableCellHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.PreviousTableCellCommand">
+         <enabledWhen>
+            <with
+                  variable="org.eclipse.wst.xml.vex.ui.isRow">
+               <equals
+                     value="true">
+               </equals>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.SplitBlockElementHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.SplitBlockElementCommand">
+      </handler>
+      <handler
+            class="org.eclipse.wst.xml.vex.ui.internal.handlers.SplitItemHandler"
+            commandId="org.eclipse.wst.xml.vex.ui.SplitItemCommand">
+      </handler>
+   </extension>
+   <extension
          point="org.eclipse.ui.views">
       <category
             name="%VexViewCategory.name"
@@ -304,15 +449,12 @@
             class="org.eclipse.wst.xml.vex.ui.internal.views.DebugView"
             id="org.eclipse.wst.xml.vex.ui.views.debug">
       </view>
-   </extension>
-   <extension
-         point="org.eclipse.ui.views">
       <view
-            name="%ConfigurationView.name"
-            icon="$nl$/vex16.gif"
             category="org.eclipse.wst.xml.vex.ui.views.VexViewCategory"
             class="org.eclipse.wst.xml.vex.ui.internal.config.ConfigurationView"
-            id="org.eclipse.wst.xml.vex.ui.views.configuration">
+            icon="$nl$/vex16.gif"
+            id="org.eclipse.wst.xml.vex.ui.views.configuration"
+            name="%ConfigurationView.name">
       </view>
    </extension>
    <extension
@@ -361,15 +503,12 @@
             </objectClass>
          </enablement>
       </decorator>
-   </extension>
-   <extension
-         point="org.eclipse.ui.decorators">
       <decorator
-            lightweight="true"
-            label="%BuildProblemDecorator.name"
-            state="true"
             class="org.eclipse.wst.xml.vex.ui.internal.config.BuildProblemDecorator"
-            id="org.eclipse.wst.xml.vex.ui.config.buildProblemDecorator">
+            id="org.eclipse.wst.xml.vex.ui.config.buildProblemDecorator"
+            label="%BuildProblemDecorator.name"
+            lightweight="true"
+            state="true">
          <enablement>
             <objectClass
                   name="org.eclipse.core.resources.IResource">
@@ -390,15 +529,12 @@
                value="org.eclipse.wst.xml.vex.ui.pluginNature">
          </filter>
       </page>
-   </extension>
-   <extension
-         point="org.eclipse.ui.propertyPages">
       <page
-            objectClass="org.eclipse.core.resources.IFile"
-            name="%StylePropertyPage.name"
             class="org.eclipse.wst.xml.vex.ui.internal.config.StylePropertyPage"
+            id="org.eclipse.wst.xml.vex.ui.config.StylePropertyPage"
+            name="%StylePropertyPage.name"
             nameFilter="*.css"
-            id="org.eclipse.wst.xml.vex.ui.config.StylePropertyPage">
+            objectClass="org.eclipse.core.resources.IFile">
          <filter
                name="projectNature"
                value="org.eclipse.wst.xml.vex.ui.pluginNature">
@@ -406,57 +542,288 @@
       </page>
    </extension>
    <extension
-         point="org.eclipse.ui.bindings">
-         
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.ChangeElementAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Ctrl+Alt+Space"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.DuplicateSelectionAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Ctrl+D"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.InsertElementAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Insert"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.NextTableCellAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Tab"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.PreviousTableCellAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Shift+Tab"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.RemoveElementAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Ctrl+U"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.SplitItemAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Shift+Enter"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-      <key
-            commandId="org.eclipse.wst.xml.vex.ui.action.SplitAction"
-            contextId="org.eclipse.wst.xml.vex.ui.VexEditorContext"
-            sequence="Enter"
-            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
-      </key>
-
+         point="org.eclipse.core.expressions.definitions">
+      <definition
+            id="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+         <or>
+            <with
+                  variable="activeEditorId">
+               <equals
+                     value="org.eclipse.wst.xml.vex.ui.VexEditor">
+               </equals>
+            </with>
+            <with
+                  variable="activeEditorId">
+               <equals
+                     value="org.eclipse.wst.xml.vex.ui.VexEditorMultiPage">
+               </equals>
+            </with>
+         </or>
+      </definition>
+      <definition
+            id="org.eclipse.wst.xml.vex.ui.focusedVexEditor">
+         <or>
+            <with
+                  variable="activePartId">
+               <equals
+                     value="org.eclipse.wst.xml.vex.ui.VexEditor">
+               </equals>
+            </with>
+            <with
+                  variable="activePartId">
+               <equals
+                     value="org.eclipse.wst.xml.vex.ui.VexEditorMultiPage">
+               </equals>
+            </with>
+         </or>
+      </definition>
+   </extension>
+   <extension
+         point="org.eclipse.ui.services">
+      <sourceProvider
+            provider="org.eclipse.wst.xml.vex.ui.internal.editor.DocumentContextSourceProvider">
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isColumn"
+               priorityLevel="workbench">
+         </variable>
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isFirstColumn"
+               priorityLevel="workbench">
+         </variable>
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isLastColumn"
+               priorityLevel="workbench">
+         </variable>
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isRow"
+               priorityLevel="workbench">
+         </variable>
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isFirstRow"
+               priorityLevel="workbench">
+         </variable>
+         <variable
+               name="org.eclipse.wst.xml.vex.ui.isLastRow"
+               priorityLevel="workbench">
+         </variable>
+      </sourceProvider>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:org.eclipse.ui.main.menu?after=edit">
+         <menu
+               label="%menu.Document.name">
+            <visibleWhen>
+               <reference
+                     definitionId="org.eclipse.wst.xml.vex.ui.activeVexEditor">
+               </reference>
+            </visibleWhen>
+            <menu
+                  label="%menu.Add.name">
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.AddElementCommand"
+                     label="%menu.Add.Element.name">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.AddRowAboveCommand"
+                     label="%menu.Add.RowAbove.name">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.AddRowBelowCommand"
+                     label="%menu.Add.RowBelow.name">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.AddColumnLeftCommand"
+                     label="%menu.Add.ColumnLeft.name">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.AddColumnRightCommand"
+                     label="%menu.Add.ColumnRight.name">
+               </command>
+            </menu>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.DuplicateSelectionCommand">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.ConvertElementCommand">
+            </command>
+            <menu
+                  label="%menu.Move.name">
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.MoveRowUpCommand"
+                     label="%menu.Move.RowUp">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.MoveRowDownCommand"
+                     label="%menu.Move.RowDown">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.MoveColumnLeftCommand"
+                     label="%menu.Move.ColumnLeft">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.MoveColumnRightCommand"
+                     label="%menu.Move.ColumnRight">
+               </command>
+            </menu>
+            <menu
+                  label="%menu.Remove.name">
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.RemoveTagCommand">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.RemoveRowCommand"
+                     label="%menu.Remove.Row.name">
+               </command>
+               <command
+                     commandId="org.eclipse.wst.xml.vex.ui.RemoveColumnCommand"
+                     label="%menu.Remove.Column.name">
+               </command>
+            </menu>
+            <separator
+                  name="org.eclipse.wst.xml.vex.ui.popup.style"
+                  visible="true">
+            </separator>
+            <menu
+                  label="%menu.Style.name">
+               <dynamic
+                     class="org.eclipse.wst.xml.vex.ui.internal.handlers.StyleMenu"
+                     id="org.eclipse.wst.xml.vex.ui.StyleMenu">
+               </dynamic>
+            </menu>
+         </menu>
+      </menuContribution>
+      <menuContribution
+            locationURI="popup:org.eclipse.wst.xml.vex.ui.popup">
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.undoRevertSave"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.ui.edit.undo">
+         </command>
+         <command
+               commandId="org.eclipse.ui.file.revert">
+         </command>
+         <command
+               commandId="org.eclipse.ui.file.save">
+         </command>
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.vexCommands"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.wst.xml.vex.ui.AddElementCommand">
+         </command>
+         <command
+               commandId="org.eclipse.wst.xml.vex.ui.DuplicateSelectionCommand">
+         </command>
+         <command
+               commandId="org.eclipse.wst.xml.vex.ui.ConvertElementCommand"
+               label="org.eclipse.wst.xml.vex.ui.popupmenu.ConvertElement">
+         </command>
+         <command
+               commandId="org.eclipse.wst.xml.vex.ui.RemoveTagCommand">
+         </command>
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.vexTableItems"
+               visible="true">
+         </separator>
+         <menu
+               label="%menu.Row.name">
+            <visibleWhen>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isRow">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+            </visibleWhen>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.AddRowAboveCommand"
+                  label="%menu.Row.AddAbove.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.AddRowBelowCommand"
+                  label="%menu.Row.AddBelow.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.MoveRowUpCommand"
+                  label="%menu.Row.MoveUp.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.MoveRowDownCommand"
+                  label="%menu.Row.MoveDown.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.RemoveRowCommand"
+                  label="%menu.Row.Remove.name">
+            </command>
+         </menu>
+         <menu
+               label="%menu.Column.name">
+            <visibleWhen>
+               <with
+                     variable="org.eclipse.wst.xml.vex.ui.isRow">
+                  <equals
+                        value="true">
+                  </equals>
+               </with>
+            </visibleWhen>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.AddColumnLeftCommand"
+                  label="%menu.Column.AddLeft.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.AddColumnRightCommand"
+                  label="%menu.Column.AddRight.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.MoveColumnLeftCommand"
+                  label="%menu.Column.MoveLeft.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.MoveColumnRightCommand"
+                  label="%menu.Column.MoveRight.name">
+            </command>
+            <command
+                  commandId="org.eclipse.wst.xml.vex.ui.RemoveColumnCommand"
+                  label="%menu.Column.Remove.name">
+            </command>
+         </menu>
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.cutCopyPaste"
+               visible="true">
+         </separator>
+         <command
+               commandId="org.eclipse.ui.edit.cut">
+         </command>
+         <command
+               commandId="org.eclipse.ui.edit.copy">
+         </command>
+         <command
+               commandId="org.eclipse.ui.edit.paste">
+         </command>
+         <command
+               commandId="org.eclipse.ui.edit.delete">
+         </command>
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.style"
+               visible="true">
+         </separator>
+         <menu
+               label="%menu.Style.name">
+            <dynamic
+                  class="org.eclipse.wst.xml.vex.ui.internal.handlers.StyleMenu"
+                  id="org.eclipse.wst.xml.vex.ui.StyleMenu">
+            </dynamic>
+         </menu>
+         <separator
+               name="org.eclipse.wst.xml.vex.ui.popup.any"
+               visible="true">
+         </separator>
+      </menuContribution>
    </extension>
 
 </plugin>
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin_fr.properties b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin_fr.properties
index 4c0a97f..f075d26 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin_fr.properties
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/plugin_fr.properties
@@ -1,73 +1,27 @@
-#

-# Language-specific strings in plugin.xml

-#

-

-plugin.name=Editeur XML Vex

-

-BuildProblemDecorator.name=Problème avec le décorateur du Plug-in Vex

-ConfigurationView.name=Configuration de Vex

-DebugView.name=Debogage de Vex

-DoctypePropertyPage.name=Vex Document Type

-DocumentPerspective.name=Document

-NewDocumentWizard.name=Document

-NewDocumentWizard.desc=Créer un document XML avec l'éditeur Vex

-NewPluginProjectWizard.name=Projet du plug-in Vex

-NewPluginProjectWizard.desc=Créer un nouveau projet du Vex Plug-in

-NewWizardCategory.name=Vex

-PluginProjectBuilder.name=Compilateur du plug-in Vex

-PluginProjectDecorator.name=Décorateur du projet Vex

-PluginProjectNature.name=Nature du projet Vex

-StylePropertyPage.name=Style Vex

-VexCommandCategory.name=Editeur XML Vex

-VexEditor.name=Editeur XML Vex

-VexEditorContext.name=Editer les documents XML

-VexViewCategory.name=Vex

-

-extensionPoint.doctypes=Document Types Vex

-extensionPoint.styles=Styles Vex

-

-documentActions.label=Actions d'édition de Vex

-

-documentMenu.label=&Document

-insertMenu.label=&Insérer

-tableMenu.label=&Table

-

-

-#

-# Actions

-#

-# NOTE: THESE MUST BE KEPT IN SYNC WITH THE SAME BLOCK IN 

-#       src/net/sf/vex/editor/messages.properties

-#

-# Note: when there are multiple labels for an action, the one named

-# Xxx.label is the command listed in the key bindings preference page.

-#

-ChangeElementAction.label=Changer Element

-ChangeElementAction.dynamic.label=&Changer <{0}> en...

-ChangeElementAction.menu.label=&Changer Element...

-DeleteColumnAction.label=Détruire la colonne

-DeleteRowAction.label=Détruire la ligne

-DuplicateSelectionAction.label=&Dupliquer la selection

-InsertColumnAfterAction.label=Insérer une colonne après

-InsertColumnBeforeAction.label=Insérer une colonne avant

-InsertElementAction.label=Insérer un élement

-InsertElementAction.contextmenu.label=Insérer un élément...

-InsertElementAction.mainmenu.label=&Element...

-InsertRowAboveAction.label=Insérer ligne au dessus

-InsertRowBelowAction.label=Insérer ligne en dessous

-MoveColumnLeftAction.label=Déplacer une colonne à gauche

-MoveColumnRightAction.label=Déplacer une colonne à droite

-MoveRowDownAction.label=Déplacer la ligne vers le bas

-MoveRowUpAction.label=Déplacer la ligne vers le haut

-NextTableCellAction.label=Prochaine Cellule de la table

-PasteTextAction.label=Coller le texte

-PreviousTableCellAction.label=Cellule précédente de la table

-RemoveElementAction.label=Supprimer l'élement

-RemoveElementAction.dynamic.label=Supprimer <{0}>

-RestoreLastSelectionAction.label=Restaurer la dernière selection

-SplitAction.label=Couper le bloc

-SplitItemAction.label=Couper l'item

-

-#

-# End of Actions

-#

+#
+# Language-specific strings in plugin.xml
+#
+
+pluginName= Editeur XML Vex
+
+BuildProblemDecorator.name=Problème avec le décorateur du Plug-in Vex
+ConfigurationView.name=Configuration de Vex
+DebugView.name=Debogage de Vex
+DoctypePropertyPage.name=Vex Document Type
+DocumentPerspective.name=Document
+NewDocumentWizard.name=Document
+NewDocumentWizard.desc=Créer un document XML avec l'éditeur Vex
+NewPluginProjectWizard.name=Projet du plug-in Vex
+NewPluginProjectWizard.desc=Créer un nouveau projet du Vex Plug-in
+NewWizardCategory.name=Vex
+PluginProjectBuilder.name=Compilateur du plug-in Vex
+PluginProjectDecorator.name=Décorateur du projet Vex
+PluginProjectNature.name=Nature du projet Vex
+StylePropertyPage.name=Style Vex
+VexCommandCategory.name=Editeur XML Vex
+VexEditor.name=Editeur XML Vex
+VexEditorContext.name=Editer les documents XML
+VexViewCategory.name=Vex
+
+extensionPoint.doctypes=Document Types Vex
+extensionPoint.styles=Styles Vex
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/AbstractVexAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/AbstractVexAction.java
deleted file mode 100644
index 61d968e..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/AbstractVexAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Abstract Vex action. This class provides default implementations for all
- * methods in IVexAction except for <code>run</code>.
- */
-public abstract class AbstractVexAction implements IVexAction {
-
-	/**
-	 * Class constructor.
-	 */
-	public AbstractVexAction() {
-	}
-
-	/**
-	 * Returns <code>true</code>.
-	 */
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return true;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ActionUtils.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ActionUtils.java
deleted file mode 100644
index ee0045e..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ActionUtils.java
+++ /dev/null
@@ -1,562 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.css.CSS;
-import org.eclipse.wst.xml.vex.core.internal.css.StyleSheet;
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.layout.BlockBox;
-import org.eclipse.wst.xml.vex.core.internal.layout.Box;
-import org.eclipse.wst.xml.vex.core.internal.layout.ElementOrRangeCallback;
-import org.eclipse.wst.xml.vex.core.internal.layout.LayoutUtils;
-import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXNode;
-import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Static helper methods used across actions.
- */
-public class ActionUtils {
-
-	public static class RowColumnInfo {
-		public Object row;
-		public Object cell;
-		public int rowIndex;
-		public int cellIndex;
-		public int rowCount;
-		public int columnCount;
-		public int maxColumnCount;
-	}
-
-	/**
-	 * Clone the table cells from the given TableRowBox to the current offset in
-	 * vexWidget.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget to modify.
-	 * @param tr
-	 *            TableRowBox whose cells are to be cloned.
-	 * @param moveToFirstCell
-	 *            TODO
-	 */
-	public static void cloneTableCells(final IVexWidget vexWidget,
-			final TableRowBox tr, final boolean moveToFirstCell) {
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				int offset = vexWidget.getCaretOffset();
-
-				boolean firstCellIsAnonymous = false;
-				Box[] cells = tr.getChildren();
-				for (int i = 0; i < cells.length; i++) {
-					if (cells[i].isAnonymous()) {
-						vexWidget.insertText(" ");
-						if (i == 0) {
-							firstCellIsAnonymous = true;
-						}
-					} else {
-						vexWidget.insertElement((Element) cells[i].getElement()
-								.clone());
-						vexWidget.moveBy(+1);
-					}
-				}
-
-				if (moveToFirstCell) {
-					vexWidget.moveTo(offset + 1);
-					if (firstCellIsAnonymous) {
-						vexWidget.moveBy(-1, true);
-					}
-				}
-			}
-		});
-	}
-
-	/**
-	 * Duplicate the given table row, inserting a new empty one below it. The
-	 * new row contains empty children corresponding to the given row's
-	 * children.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget with which we're working
-	 * @param tr
-	 *            TableRowBox to be duplicated.
-	 */
-	public static void duplicateTableRow(final IVexWidget vexWidget,
-			final TableRowBox tr) {
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				vexWidget.moveTo(tr.getEndOffset());
-
-				if (!tr.isAnonymous()) {
-					vexWidget.moveBy(+1); // Move past sentinel in current row
-					vexWidget.insertElement((Element) tr.getElement().clone());
-				}
-
-				cloneTableCells(vexWidget, tr, true);
-			}
-		});
-	}
-
-	/**
-	 * Returns true if the given element or range is at least partially
-	 * selected.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget being tested.
-	 * @param elementOrRange
-	 *            Element or IntRange being tested.
-	 */
-	public static boolean elementOrRangeIsPartiallySelected(
-			IVexWidget vexWidget, Object elementOrRange) {
-		IntRange range = getInnerRange(elementOrRange);
-		return range.getEnd() >= vexWidget.getSelectionStart()
-				&& range.getStart() <= vexWidget.getSelectionEnd();
-	}
-
-	/**
-	 * Returns the zero-based index of the table column containing the current
-	 * offset. Returns -1 if we are not inside a table.
-	 */
-	public static int getCurrentColumnIndex(IVexWidget vexWidget) {
-
-		VEXElement row = getCurrentTableRow(vexWidget);
-
-		if (row == null) {
-			return -1;
-		}
-
-		final int offset = vexWidget.getCaretOffset();
-		final int[] column = new int[] { -1 };
-		LayoutUtils.iterateTableCells(vexWidget.getStyleSheet(), row,
-				new ElementOrRangeCallback() {
-					private int i = 0;
-
-					public void onElement(Element child, String displayStyle) {
-						if (offset > child.getStartOffset()
-								&& offset <= child.getEndOffset()) {
-							column[0] = i;
-						}
-						i++;
-					}
-
-					public void onRange(VEXElement parent, int startOffset,
-							int endOffset) {
-						i++;
-					}
-				});
-
-		return column[0];
-	}
-
-	/**
-	 * Returns the innermost Element with style table-row containing the caret,
-	 * or null if no such element exists.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget to use.
-	 */
-	public static VEXElement getCurrentTableRow(IVexWidget vexWidget) {
-
-		StyleSheet ss = vexWidget.getStyleSheet();
-		VEXElement element = vexWidget.getCurrentElement();
-
-		while (element != null) {
-			if (ss.getStyles(element).getDisplay().equals(CSS.TABLE_ROW)) {
-				return element;
-			}
-			element = element.getParent();
-		}
-
-		return null;
-	}
-
-	/**
-	 * Returns the start offset of the next sibling of the parent element.
-	 * Returns -1 if there is no previous sibling in the parent.
-	 * 
-	 * @param vexWidget
-	 *            VexWidget to use.
-	 */
-	public static int getPreviousSiblingStart(IVexWidget vexWidget) {
-		int startOffset;
-
-		if (vexWidget.hasSelection()) {
-			startOffset = vexWidget.getSelectionStart();
-		} else {
-			Box box = vexWidget.findInnermostBox(new IBoxFilter() {
-				public boolean matches(Box box) {
-					return box instanceof BlockBox && box.getElement() != null;
-				}
-			});
-
-			if (box.getElement() == vexWidget.getDocument().getRootElement()) {
-				return -1;
-			}
-
-			startOffset = box.getElement().getStartOffset();
-		}
- 
-		int previousSiblingStart = -1;
-		VEXElement parent = vexWidget.getDocument().getElementAt(startOffset);
-		List<VEXNode> children = parent.getChildNodes();
-		for (int i = 0; i < children.size(); i++) {
-			VEXNode child = children.get(i);
-			if (startOffset == child.getStartOffset()) {
-				break;
-			}
-			previousSiblingStart = child.getStartOffset();
-		}
-		return previousSiblingStart;
-	}
-
-	/**
-	 * Returns an array of the selected block boxes. Text nodes between boxes
-	 * are not returned. If the selection does not enclose any block boxes,
-	 * returns an empty array.
-	 * 
-	 * @param vexWidget
-	 *            VexWidget to use.
-	 */
-	public static BlockBox[] getSelectedBlockBoxes(final IVexWidget vexWidget) {
-
-		if (!vexWidget.hasSelection()) {
-			return new BlockBox[0];
-		}
-
-		Box parent = vexWidget.findInnermostBox(new IBoxFilter() {
-			public boolean matches(Box box) {
-				System.out.println("Matching " + box);
-				return box instanceof BlockBox
-						&& box.getStartOffset() <= vexWidget
-								.getSelectionStart()
-						&& box.getEndOffset() >= vexWidget.getSelectionEnd();
-			}
-		});
-
-		System.out.println("Matched " + parent);
-
-		List blockList = new ArrayList();
-
-		Box[] children = parent.getChildren();
-		System.out.println("Parent has " + children.length + " children");
-		for (int i = 0; i < children.length; i++) {
-			Box child = children[i];
-			if (child instanceof BlockBox
-					&& child.getStartOffset() >= vexWidget.getSelectionStart()
-					&& child.getEndOffset() <= vexWidget.getSelectionEnd()) {
-				System.out.println("  adding " + child);
-				blockList.add(child);
-			} else {
-				System.out.println("  skipping " + child);
-			}
-
-		}
-
-		return (BlockBox[]) blockList.toArray(new BlockBox[blockList.size()]);
-	}
-
-	/**
-	 * Returns the currently selected table rows, or the current row if ther is
-	 * no selection. If no row can be found, returns an empty array.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget to use.
-	 */
-	public static SelectedRows getSelectedTableRows(final IVexWidget vexWidget) {
-
-		final SelectedRows selected = new SelectedRows();
-
-		ActionUtils.iterateTableCells(vexWidget, new TableCellCallback() {
-			public void startRow(Object row, int rowIndex) {
-				if (ActionUtils.elementOrRangeIsPartiallySelected(vexWidget,
-						row)) {
-					if (selected.rows == null) {
-						selected.rows = new ArrayList();
-					}
-					selected.rows.add(row);
-				} else {
-					if (selected.rows == null) {
-						selected.rowBefore = row;
-					} else {
-						if (selected.rowAfter == null) {
-							selected.rowAfter = row;
-						}
-					}
-				}
-			}
-
-			public void onCell(Object row, Object cell, int rowIndex,
-					int cellIndex) {
-			}
-
-			public void endRow(Object row, int rowIndex) {
-			}
-		});
-
-		return selected;
-	}
-
-	public static void iterateTableCells(IVexWidget vexWidget,
-			final TableCellCallback callback) {
-
-		final StyleSheet ss = vexWidget.getStyleSheet();
-
-		iterateTableRows(vexWidget, new ElementOrRangeCallback() {
-
-			final private int[] rowIndex = { 0 };
-
-			public void onElement(final Element row, String displayStyle) {
-
-				callback.startRow(row, rowIndex[0]);
-
-				LayoutUtils.iterateTableCells(ss, row,
-						new ElementOrRangeCallback() {
-							private int cellIndex = 0;
-
-							public void onElement(Element cell,
-									String displayStyle) {
-								callback.onCell(row, cell, rowIndex[0],
-										cellIndex);
-								cellIndex++;
-							}
-
-							public void onRange(VEXElement parent,
-									int startOffset, int endOffset) {
-								callback.onCell(row, new IntRange(startOffset,
-										endOffset), rowIndex[0], cellIndex);
-								cellIndex++;
-							}
-						});
-
-				callback.endRow(row, rowIndex[0]);
-
-				rowIndex[0]++;
-			}
-
-			public void onRange(VEXElement parent, final int startOffset,
-					final int endOffset) {
-
-				final IntRange row = new IntRange(startOffset, endOffset);
-				callback.startRow(row, rowIndex[0]);
-
-				LayoutUtils.iterateTableCells(ss, parent, startOffset,
-						endOffset, new ElementOrRangeCallback() {
-							private int cellIndex = 0;
-
-							public void onElement(Element cell,
-									String displayStyle) {
-								callback.onCell(row, cell, rowIndex[0],
-										cellIndex);
-								cellIndex++;
-							}
-
-							public void onRange(VEXElement parent,
-									int startOffset, int endOffset) {
-								callback.onCell(row, new IntRange(startOffset,
-										endOffset), rowIndex[0], cellIndex);
-								cellIndex++;
-							}
-						});
-
-				callback.endRow(row, rowIndex[0]);
-
-				rowIndex[0]++;
-			}
-		});
-	}
-
-	/**
-	 * Returns a RowColumnInfo structure containing information about the table
-	 * containing the caret. Returns null if the caret is not currently inside a
-	 * table.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget to inspect.
-	 */
-	public static RowColumnInfo getRowColumnInfo(IVexWidget vexWidget) {
-
-		final boolean[] found = new boolean[1];
-		final RowColumnInfo[] rcInfo = new RowColumnInfo[] { new RowColumnInfo() };
-		final int offset = vexWidget.getCaretOffset();
-
-		rcInfo[0].cellIndex = -1;
-		rcInfo[0].rowIndex = -1;
-
-		iterateTableCells(vexWidget, new TableCellCallback() {
-
-			int rowColumnCount;
-
-			public void startRow(Object row, int rowIndex) {
-				rowColumnCount = 0;
-			}
-
-			public void onCell(Object row, Object cell, int rowIndex,
-					int cellIndex) {
-				found[0] = true;
-				if (LayoutUtils.elementOrRangeContains(row, offset)) {
-					rcInfo[0].row = row;
-					rcInfo[0].rowIndex = rowIndex;
-					rcInfo[0].columnCount++;
-
-					if (LayoutUtils.elementOrRangeContains(cell, offset)) {
-						rcInfo[0].cell = cell;
-						rcInfo[0].cellIndex = cellIndex;
-					}
-				}
-
-				rowColumnCount++;
-			}
-
-			public void endRow(Object row, int rowIndex) {
-				rcInfo[0].rowCount++;
-				rcInfo[0].maxColumnCount = Math.max(rcInfo[0].maxColumnCount,
-						rowColumnCount);
-			}
-		});
-
-		if (found[0]) {
-			return rcInfo[0];
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Iterate over all rows in the table containing the caret.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget to iterate over.
-	 * @param callback
-	 *            Caller-provided callback that this method calls for each row
-	 *            in the current table.
-	 */
-	public static void iterateTableRows(IVexWidget vexWidget,
-			ElementOrRangeCallback callback) {
-
-		final StyleSheet ss = vexWidget.getStyleSheet();
-		final VEXDocument doc = vexWidget.getDocument();
-		final int offset = vexWidget.getCaretOffset();
-
-		// This may or may not be a table
-		// In any case, it's the element that contains the top-level table
-		// children
-		VEXElement table = doc.getElementAt(offset);
-
-		while (table != null && !LayoutUtils.isTableChild(ss, table)) {
-			table = table.getParent();
-		}
-
-		while (table != null && LayoutUtils.isTableChild(ss, table)) {
-			table = table.getParent();
-		}
-
-		if (table == null || table.getParent() == null) {
-			return;
-		}
-
-		final List tableChildren = new ArrayList();
-		final boolean[] found = new boolean[] { false };
-		LayoutUtils.iterateChildrenByDisplayStyle(ss,
-				LayoutUtils.TABLE_CHILD_STYLES, table,
-				new ElementOrRangeCallback() {
-					public void onElement(Element child, String displayStyle) {
-						if (offset >= child.getStartOffset()
-								&& offset <= child.getEndOffset()) {
-							found[0] = true;
-						}
-						tableChildren.add(child);
-					}
-
-					public void onRange(VEXElement parent, int startOffset,
-							int endOffset) {
-						if (!found[0]) {
-							tableChildren.clear();
-						}
-					}
-				});
-
-		if (!found[0]) {
-			return;
-		}
-
-		int startOffset = ((Element) tableChildren.get(0)).getStartOffset();
-		int endOffset = ((Element) tableChildren.get(tableChildren.size() - 1))
-				.getEndOffset() + 1;
-		LayoutUtils.iterateTableRows(ss, table, startOffset, endOffset,
-				callback);
-	}
-
-	/**
-	 * Returns an IntRange representing the offsets inside the given Element or
-	 * IntRange. If an Element is passed, returns the offsets inside the
-	 * sentinels. If an IntRange is passed it is returned directly.
-	 * 
-	 * @param elementOrRange
-	 *            Element or IntRange to be inspected.
-	 */
-	public static IntRange getInnerRange(Object elementOrRange) {
-		if (elementOrRange instanceof Element) {
-			Element element = (Element) elementOrRange;
-			return new IntRange(element.getStartOffset() + 1, element
-					.getEndOffset());
-		} else {
-			return (IntRange) elementOrRange;
-		}
-	}
-
-	/**
-	 * Returns an IntRange representing the offsets outside the given Element or
-	 * IntRange. If an Element is passed, returns the offsets outside the
-	 * sentinels. If an IntRange is passed it is returned directly.
-	 * 
-	 * @param elementOrRange
-	 *            Element or IntRange to be inspected.
-	 */
-	public static IntRange getOuterRange(Object elementOrRange) {
-		if (elementOrRange instanceof Element) {
-			Element element = (Element) elementOrRange;
-			return new IntRange(element.getStartOffset(), element
-					.getEndOffset() + 1);
-		} else {
-			return (IntRange) elementOrRange;
-		}
-	}
-
-	public static class SelectedRows {
-
-		private SelectedRows() {
-		}
-
-		public List getRows() {
-			return this.rows;
-		}
-
-		public Object getRowBefore() {
-			return this.rowBefore;
-		}
-
-		public Object getRowAfter() {
-			return this.rowAfter;
-		}
-
-		private List rows;
-		private Object rowBefore;
-		private Object rowAfter;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ChangeElementAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ChangeElementAction.java
deleted file mode 100644
index f7ecf02..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/ChangeElementAction.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-import org.eclipse.wst.xml.vex.ui.internal.action.IVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.contentassist.MorphAssistant;
-import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
-
-/**
- * Displays the Change Element dialog.
- */
-public class ChangeElementAction implements IVexAction {
-
-	public void run(IVexWidget vexWidget) {
-		new MorphAssistant().show((VexWidget) vexWidget);
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return true;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteColumnAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteColumnAction.java
deleted file mode 100644
index 14e2ce3..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteColumnAction.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Delete the table column containing the caret.
- */
-public class DeleteColumnAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				final ActionUtils.RowColumnInfo rcInfo = ActionUtils
-						.getRowColumnInfo(vexWidget);
-
-				if (rcInfo == null) {
-					return;
-				}
-
-				final List cellsToDelete = new ArrayList();
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-							public void startRow(Object row, int rowIndex) {
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (cellIndex == rcInfo.cellIndex) {
-									cellsToDelete.add(cell);
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-							}
-						});
-
-				// Iterate the deletions in reverse, so that we don't mess up
-				// offsets that are in anonymous cells, which are not stored
-				// as Positions.
-				for (int i = cellsToDelete.size() - 1; i >= 0; i--) {
-					Object cell = cellsToDelete.get(i);
-					IntRange range = ActionUtils.getOuterRange(cell);
-					vexWidget.moveTo(range.getStart());
-					vexWidget.moveTo(range.getEnd(), true);
-					vexWidget.deleteSelection();
-				}
-			}
-		});
-
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return ActionUtils.getCurrentColumnIndex(vexWidget) != -1;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteRowAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteRowAction.java
deleted file mode 100644
index 529a622..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DeleteRowAction.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Delete selected table rows.
- */
-public class DeleteRowAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final List rows = ActionUtils.getSelectedTableRows(vexWidget).getRows();
-
-		if (rows == null) {
-			return;
-		}
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-				int startOffset = ActionUtils.getOuterRange(rows.get(0))
-						.getStart();
-				int endOffset = ActionUtils.getOuterRange(
-						rows.get(rows.size() - 1)).getEnd();
-
-				vexWidget.moveTo(startOffset);
-				vexWidget.moveTo(endOffset, true);
-				vexWidget.deleteSelection();
-			}
-		});
-
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return ActionUtils.getSelectedTableRows(vexWidget).getRows() != null;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DuplicateSelectionAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DuplicateSelectionAction.java
deleted file mode 100644
index 4bf903e..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/DuplicateSelectionAction.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Duplicates current selection or element.
- */
-public class DuplicateSelectionAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-				if (!vexWidget.hasSelection()) {
-					VEXElement element = vexWidget.getCurrentElement();
-					if (element.getParent() == null) {
-						// Can't dup the root element
-						return;
-					}
-					vexWidget.moveTo(element.getStartOffset());
-					vexWidget.moveTo(element.getEndOffset() + 1, true);
-				}
-
-				vexWidget.copySelection();
-				int startOffset = vexWidget.getSelectionEnd();
-				vexWidget.moveTo(startOffset);
-				vexWidget.paste();
-				int endOffset = vexWidget.getCaretOffset();
-				vexWidget.moveTo(startOffset);
-				vexWidget.moveTo(endOffset, true);
-			}
-		});
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/IVexAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/IVexAction.java
deleted file mode 100644
index 5e730e0..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/IVexAction.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Interface implemented by command objects that can act on a VexWidget.
- */
-public interface IVexAction {
-
-	/**
-	 * Performs the action on the VexWidget.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget on which the action is to be performed.
-	 */
-	public void run(IVexWidget vexWidget);
-
-	/**
-	 * Returns true if the action is valid for the given VexWidget.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget against which to test validity.
-	 */
-	public boolean isEnabled(IVexWidget vexWidget);
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnAfterAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnAfterAction.java
deleted file mode 100644
index c656d15..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnAfterAction.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Inserts a single table column after the current one.
- */
-public class InsertColumnAfterAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final int indexToDup = ActionUtils.getCurrentColumnIndex(vexWidget);
-		if (indexToDup == -1) {
-			return;
-		}
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				final List cellsToDup = new ArrayList();
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-							public void startRow(Object row, int rowIndex) {
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (cellIndex == indexToDup
-										&& cell instanceof Element) {
-									cellsToDup.add(cell);
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-							}
-						});
-
-				int finalOffset = -1;
-				for (Iterator it = cellsToDup.iterator(); it.hasNext();) {
-					Element element = (Element) it.next();
-					if (finalOffset == -1) {
-						finalOffset = element.getStartOffset() + 1;
-					}
-					vexWidget.moveTo(element.getEndOffset() + 1);
-					vexWidget.insertElement((Element) element.clone());
-				}
-
-				if (finalOffset != -1) {
-					vexWidget.moveTo(finalOffset);
-				}
-			}
-		});
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return ActionUtils.getCurrentColumnIndex(vexWidget) != -1;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnBeforeAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnBeforeAction.java
deleted file mode 100644
index 30a2b7d..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertColumnBeforeAction.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Inserts a single table column before the current one.
- */
-public class InsertColumnBeforeAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				final int indexToDup = ActionUtils
-						.getCurrentColumnIndex(vexWidget);
-				if (indexToDup == -1) {
-					return;
-				}
-
-				final List cellsToDup = new ArrayList();
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-							public void startRow(Object row, int rowIndex) {
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (cellIndex == indexToDup
-										&& cell instanceof Element) {
-									cellsToDup.add(cell);
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-							}
-						});
-
-				int finalOffset = -1;
-				for (Iterator it = cellsToDup.iterator(); it.hasNext();) {
-					Element element = (Element) it.next();
-					if (finalOffset == -1) {
-						finalOffset = element.getStartOffset() + 1;
-					}
-					vexWidget.moveTo(element.getStartOffset());
-					vexWidget.insertElement((Element) element.clone());
-				}
-
-				if (finalOffset != -1) {
-					vexWidget.moveTo(finalOffset);
-				}
-
-			}
-		});
-
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return ActionUtils.getCurrentColumnIndex(vexWidget) != -1;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertElementAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertElementAction.java
deleted file mode 100644
index ebfddc6..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertElementAction.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-import org.eclipse.wst.xml.vex.ui.internal.action.IVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.contentassist.InsertAssistant;
-import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
-
-/**
- * @author john
- * 
- *         TODO To change the template for this generated type comment go to
- *         Window - Preferences - Java - Code Style - Code Templates
- */
-public class InsertElementAction implements IVexAction {
-
-	public void run(IVexWidget vexWidget) {
-		new InsertAssistant().show((VexWidget) vexWidget);
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return true;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAboveAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAboveAction.java
deleted file mode 100644
index f5edfd0..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAboveAction.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-/**
- * Inserts one or more table rows above the currently selected one(s).
- */
-public class InsertRowAboveAction extends InsertRowAction {
-
-	public InsertRowAboveAction() {
-		super(true);
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAction.java
deleted file mode 100644
index 876c856..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowAction.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Inserts one or more table rows either above or below the currently selected
- * one(s). This class is meant as a base class for InsertRowAboveAction and
- * InsertRowBelowAction.
- */
-public class InsertRowAction extends AbstractVexAction {
-
-	/**
-	 * Class constructor.
-	 * 
-	 * @param above
-	 *            If true, the new rows are inserted above the currently
-	 *            selected ones, else they are inserted below.
-	 */
-	public InsertRowAction(boolean above) {
-		this.above = above;
-	}
-
-	public void run(final IVexWidget vexWidget) {
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				final List rowsToInsert = new ArrayList();
-				final List rowCellsToInsert = new ArrayList();
-
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-
-							boolean rowSelected;
-							List cellsToInsert;
-
-							public void startRow(Object row, int rowIndex) {
-								rowSelected = ActionUtils
-										.elementOrRangeIsPartiallySelected(
-												vexWidget, row);
-
-								if (rowSelected) {
-									cellsToInsert = new ArrayList();
-								}
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (rowSelected) {
-									cellsToInsert.add(cell);
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-								if (rowSelected) {
-									rowsToInsert.add(row);
-									rowCellsToInsert.add(cellsToInsert);
-								}
-							}
-
-						});
-
-				if (rowsToInsert.size() == 0) {
-					return;
-				}
-
-				//
-				// save the caret offset so that we return just inside the first
-				// table cell
-				//
-				// (innerOffset - outerOffset) represents the final offset of
-				// the caret, relative to the insertion point of the new rows
-				//
-				int outerOffset = ActionUtils
-						.getOuterRange(rowsToInsert.get(0)).getStart();
-				int innerOffset;
-				List firstCells = (List) rowCellsToInsert.get(0);
-				if (firstCells.size() == 0) {
-					innerOffset = ActionUtils
-							.getInnerRange(rowsToInsert.get(0)).getStart();
-				} else {
-					innerOffset = ActionUtils.getInnerRange(firstCells.get(0))
-							.getStart();
-				}
-
-				int insertOffset;
-				if (above) {
-					insertOffset = ActionUtils.getOuterRange(
-							rowsToInsert.get(0)).getStart();
-				} else {
-					Object lastRow = rowsToInsert.get(rowsToInsert.size() - 1);
-					insertOffset = ActionUtils.getOuterRange(lastRow).getEnd();
-				}
-
-				int finalOffset = insertOffset + (innerOffset - outerOffset);
-
-				vexWidget.moveTo(insertOffset);
-
-				for (int i = 0; i < rowsToInsert.size(); i++) {
-
-					Object row = rowsToInsert.get(i);
-
-					if (row instanceof Element) {
-						vexWidget.insertElement((Element) ((VEXElement) row)
-								.clone());
-					}
-
-					List cellsToInsert = (List) rowCellsToInsert.get(i);
-
-					for (int j = 0; j < cellsToInsert.size(); j++) {
-						Object cell = cellsToInsert.get(j);
-						if (cell instanceof Element) {
-							vexWidget.insertElement((Element) ((VEXElement) cell)
-									.clone());
-							vexWidget.moveBy(+1);
-						} else {
-							vexWidget.insertText(" ");
-						}
-					}
-
-					if (row instanceof Element) {
-						vexWidget.moveBy(+1);
-					}
-
-				}
-
-				vexWidget.moveTo(finalOffset);
-			}
-		});
-
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		// TODO only enable (a) if rows are selected, and (b) if not inserting
-		// adjacent anonymous rows
-		return true;
-	}
-
-	private boolean above;
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowBelowAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowBelowAction.java
deleted file mode 100644
index 3a03f27..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/InsertRowBelowAction.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-/**
- * Inserts one or more table rows below the currently selected one(s).
- */
-public class InsertRowBelowAction extends InsertRowAction {
-
-	public InsertRowBelowAction() {
-		super(false);
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnLeftAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnLeftAction.java
deleted file mode 100644
index a0ac322..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnLeftAction.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the current table column to the left.
- */
-public class MoveColumnLeftAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final ActionUtils.RowColumnInfo rcInfo = ActionUtils
-				.getRowColumnInfo(vexWidget);
-
-		if (rcInfo == null || rcInfo.cellIndex < 1) {
-			return;
-		}
-
-		vexWidget.doWork(true, new Runnable() {
-			public void run() {
-
-				// Cells to the left of the current column
-				final List sourceCells = new ArrayList();
-
-				// Cells in the current column
-				final List destCells = new ArrayList();
-
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-							Object prevCell = null;
-
-							public void startRow(Object row, int rowIndex) {
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (cellIndex == rcInfo.cellIndex) {
-									sourceCells.add(this.prevCell);
-									destCells.add(cell);
-								} else if (cellIndex == rcInfo.cellIndex - 1) {
-									this.prevCell = cell;
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-							}
-						});
-
-				// Iterate the deletions in reverse, so that we don't mess up
-				// offsets that are in anonymous cells, which are not stored
-				// as Positions.
-				//
-				// Also, to preserve the current caret position, we don't cut
-				// and paste the current column. Instead, we cut the column
-				// to the left of the current column and paste it on the right.
-				for (int i = sourceCells.size() - 1; i >= 0; i--) {
-
-					Object source = sourceCells.get(i);
-					final IntRange sourceRange = ActionUtils
-							.getOuterRange(source);
-
-					Object dest = destCells.get(i);
-					vexWidget.moveTo(ActionUtils.getOuterRange(dest).getEnd());
-
-					vexWidget.savePosition(new Runnable() {
-						public void run() {
-							vexWidget.moveTo(sourceRange.getStart());
-							vexWidget.moveTo(sourceRange.getEnd(), true);
-							vexWidget.cutSelection();
-						}
-					});
-
-					vexWidget.paste();
-				}
-			}
-		});
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		ActionUtils.RowColumnInfo rcInfo = ActionUtils
-				.getRowColumnInfo(vexWidget);
-		return rcInfo != null && rcInfo.cellIndex > 0;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnRightAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnRightAction.java
deleted file mode 100644
index 69a8e7c..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveColumnRightAction.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the current table column to the right.
- */
-public class MoveColumnRightAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final ActionUtils.RowColumnInfo rcInfo = ActionUtils
-				.getRowColumnInfo(vexWidget);
-
-		if (rcInfo == null || rcInfo.cellIndex >= rcInfo.maxColumnCount - 1) {
-			return;
-		}
-
-		vexWidget.doWork(true, new Runnable() {
-			public void run() {
-
-				// Cells to the right of the current column
-				final List sourceCells = new ArrayList();
-
-				// Cells in the current column
-				final List destCells = new ArrayList();
-
-				ActionUtils.iterateTableCells(vexWidget,
-						new TableCellCallback() {
-							Object thisCell = null;
-
-							public void startRow(Object row, int rowIndex) {
-							}
-
-							public void onCell(Object row, Object cell,
-									int rowIndex, int cellIndex) {
-								if (cellIndex == rcInfo.cellIndex) {
-									this.thisCell = cell;
-								} else if (cellIndex == rcInfo.cellIndex + 1) {
-									sourceCells.add(cell);
-									destCells.add(this.thisCell);
-								}
-							}
-
-							public void endRow(Object row, int rowIndex) {
-							}
-						});
-
-				// Iterate the deletions in reverse, so that we don't mess up
-				// offsets that are in anonymous cells, which are not stored
-				// as Positions.
-				//
-				// Also, to preserve the current caret position, we don't cut
-				// and paste the current column. Instead, we cut the column
-				// to the right of the current column and paste it on the left.
-				for (int i = sourceCells.size() - 1; i >= 0; i--) {
-
-					Object source = sourceCells.get(i);
-					final IntRange sourceRange = ActionUtils
-							.getOuterRange(source);
-
-					Object dest = destCells.get(i);
-					vexWidget
-							.moveTo(ActionUtils.getOuterRange(dest).getStart());
-
-					vexWidget.savePosition(new Runnable() {
-						public void run() {
-							vexWidget.moveTo(sourceRange.getStart());
-							vexWidget.moveTo(sourceRange.getEnd(), true);
-							vexWidget.cutSelection();
-						}
-					});
-
-					vexWidget.paste();
-				}
-			}
-		});
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		ActionUtils.RowColumnInfo rcInfo = ActionUtils
-				.getRowColumnInfo(vexWidget);
-		return rcInfo != null && rcInfo.cellIndex < rcInfo.maxColumnCount - 1;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowDownAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowDownAction.java
deleted file mode 100644
index cfb1456..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowDownAction.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the current table row down below its next sibling.
- */
-public class MoveRowDownAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final ActionUtils.SelectedRows selected = ActionUtils
-				.getSelectedTableRows(vexWidget);
-
-		if (selected.getRows() == null || selected.getRowAfter() == null) {
-			return;
-		}
-
-		vexWidget.doWork(true, new Runnable() {
-			public void run() {
-				IntRange range = ActionUtils.getOuterRange(selected
-						.getRowAfter());
-				vexWidget.moveTo(range.getStart());
-				vexWidget.moveTo(range.getEnd(), true);
-				vexWidget.cutSelection();
-
-				Object firstRow = selected.getRows().get(0);
-				vexWidget
-						.moveTo(ActionUtils.getOuterRange(firstRow).getStart());
-				vexWidget.paste();
-			}
-		});
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		ActionUtils.SelectedRows selected = ActionUtils
-				.getSelectedTableRows(vexWidget);
-		return selected.getRows() != null && selected.getRowAfter() != null;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowUpAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowUpAction.java
deleted file mode 100644
index d6831f1..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveRowUpAction.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the current table row up above its previous sibling.
- */
-public class MoveRowUpAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final ActionUtils.SelectedRows selected = ActionUtils
-				.getSelectedTableRows(vexWidget);
-
-		if (selected.getRows() == null || selected.getRowBefore() == null) {
-			return;
-		}
-
-		vexWidget.doWork(true, new Runnable() {
-			public void run() {
-				IntRange range = ActionUtils.getOuterRange(selected
-						.getRowBefore());
-				vexWidget.moveTo(range.getStart());
-				vexWidget.moveTo(range.getEnd(), true);
-				vexWidget.cutSelection();
-
-				List rows = selected.getRows();
-				Object lastRow = rows.get(rows.size() - 1);
-				vexWidget.moveTo(ActionUtils.getOuterRange(lastRow).getEnd());
-				vexWidget.paste();
-			}
-		});
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		ActionUtils.SelectedRows selected = ActionUtils
-				.getSelectedTableRows(vexWidget);
-		return selected.getRows() != null && selected.getRowBefore() != null;
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveSelectionUpAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveSelectionUpAction.java
deleted file mode 100644
index a89b35d..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/MoveSelectionUpAction.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.layout.BlockBox;
-import org.eclipse.wst.xml.vex.core.internal.layout.Box;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the current selection or block element above the previous sibling. WORK
- * IN PROGRESS.
- */
-public class MoveSelectionUpAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		// First we determine whether we should expand the selection
-		// to contain an entire block box.
-
-		// Find the lowest block box that completely contains the
-		// selection
-		Box box = vexWidget.findInnermostBox(new IBoxFilter() {
-			public boolean matches(Box box) {
-				return box instanceof BlockBox
-						&& box.getElement() != null
-						&& box.getStartOffset() <= vexWidget
-								.getSelectionStart()
-						&& box.getEndOffset() >= vexWidget.getSelectionEnd();
-			}
-		});
-
-		Box[] children = box.getChildren();
-		if (children.length > 0 && children[0] instanceof BlockBox) {
-			// The found box contains other block children, so we
-			// do NOT have to expand the selection
-		} else {
-			// Expand selection to the containing box
-
-			// (Note: This "if" is caused by the fact that getStartOffset is
-			// treated
-			// differently between elements and boxes. Boxes own their
-			// startOffset,
-			// while elements don't own theirs. Perhaps we should fix this by
-			// having
-			// box.getStartOffset() return box.getStartPosition() + 1, but this
-			// would
-			// be a VERY large change.)
-			System.out.println("Box is " + box);
-			VEXElement element = box.getElement();
-			if (element != null) {
-				vexWidget.moveTo(element.getEndOffset());
-				vexWidget.moveTo(element.getStartOffset(), true);
-
-			} else {
-				vexWidget.moveTo(box.getEndOffset());
-				vexWidget.moveTo(box.getStartOffset(), true);
-			}
-		}
-
-		// final int previousSiblingStart =
-		// ActionUtils.getPreviousSiblingStart(vexWidget);
-		//        
-		// vexWidget.doWork(new IRunnable() {
-		// public void run() throws Exception {
-		// vexWidget.cutSelection();
-		// vexWidget.moveTo(previousSiblingStart);
-		// vexWidget.paste();
-		// vexWidget.moveTo(previousSiblingStart, true);
-		// }
-		// });
-
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/NextTableCellAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/NextTableCellAction.java
deleted file mode 100644
index fc7667c..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/NextTableCellAction.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.layout.Box;
-import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
-import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the caret to the next table cell. The contents of the cell are
- * selected. If the current cell is the last cell in the table, the current row
- * is duplicated.
- */
-public class NextTableCellAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final TableRowBox tr = (TableRowBox) vexWidget
-				.findInnermostBox(new IBoxFilter() {
-					public boolean matches(Box box) {
-						return box instanceof TableRowBox;
-					}
-				});
-
-		if (tr == null) {
-			// not in a table row
-			return;
-		}
-
-		int offset = vexWidget.getCaretOffset();
-
-		Box[] cells = tr.getChildren();
-		for (int i = 0; i < cells.length; i++) {
-			if (cells[i].getStartOffset() > offset) {
-				vexWidget.moveTo(cells[i].getStartOffset());
-				vexWidget.moveTo(cells[i].getEndOffset(), true);
-				return;
-			}
-		}
-
-		// No next cell found in this row
-		// Find the next row
-		Box[] rows = tr.getParent().getChildren();
-		for (int i = 0; i < rows.length; i++) {
-			if (rows[i].getStartOffset() > offset) {
-				cells = rows[i].getChildren();
-				if (cells.length > 0) {
-					Box cell = cells[0];
-					vexWidget.moveTo(cell.getStartOffset());
-					vexWidget.moveTo(cell.getEndOffset(), true);
-				} else {
-					System.out.println("TODO - dup row into new empty row");
-				}
-				return;
-			}
-		}
-
-		// We didn't find a "next row", so let's dup the current one
-		ActionUtils.duplicateTableRow(vexWidget, tr);
-
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PasteTextAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PasteTextAction.java
deleted file mode 100644
index ae1e935..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PasteTextAction.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Paste the clipboard contents into the document as plain text, ignoring any
- * markup.
- */
-public class PasteTextAction extends AbstractVexAction {
-
-	public void run(IVexWidget vexWidget) {
-		throw new UnsupportedOperationException(
-				"PasteTextAction is not yet implemented.");
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return false;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PreviousTableCellAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PreviousTableCellAction.java
deleted file mode 100644
index 1ff55c3..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/PreviousTableCellAction.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.layout.Box;
-import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
-import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Moves the caret to the next table cell. The contents of the cell are
- * selected. If the current cell is the last cell in the table, the current row
- * is duplicated.
- */
-public class PreviousTableCellAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-
-		final TableRowBox tr = (TableRowBox) vexWidget
-				.findInnermostBox(new IBoxFilter() {
-					public boolean matches(Box box) {
-						return box instanceof TableRowBox;
-					}
-				});
-
-		if (tr == null) {
-			// not in a table row
-			return;
-		}
-
-		int offset = vexWidget.getCaretOffset();
-
-		Box[] cells = tr.getChildren();
-		for (int i = cells.length - 1; i >= 0; i--) {
-			if (cells[i].getEndOffset() < offset) {
-				vexWidget.moveTo(cells[i].getStartOffset());
-				vexWidget.moveTo(cells[i].getEndOffset(), true);
-				return;
-			}
-		}
-
-		// No next cell found in this row
-		// Find the previous row
-		Box[] rows = tr.getParent().getChildren();
-		for (int i = rows.length - 1; i >= 0; i--) {
-			if (rows[i].getEndOffset() < offset) {
-				cells = rows[i].getChildren();
-				if (cells.length > 0) {
-					Box cell = cells[cells.length - 1];
-					vexWidget.moveTo(cell.getStartOffset());
-					vexWidget.moveTo(cell.getEndOffset(), true);
-				}
-				return;
-			}
-		}
-
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RemoveElementAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RemoveElementAction.java
deleted file mode 100644
index 054f578..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RemoveElementAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocumentFragment;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Removes the current element, adding its content to the parent element.
- */
-public class RemoveElementAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-				VEXElement element = vexWidget.getDocument().getElementAt(
-						vexWidget.getCaretOffset());
-				vexWidget.moveTo(element.getStartOffset() + 1, false);
-				vexWidget.moveTo(element.getEndOffset(), true);
-				VEXDocumentFragment frag = vexWidget.getSelectedFragment();
-				vexWidget.deleteSelection();
-				vexWidget.moveBy(-1, false);
-				vexWidget.moveBy(2, true);
-				vexWidget.deleteSelection();
-				vexWidget.insertFragment(frag);
-			}
-		});
-	}
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RestoreLastSelectionAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RestoreLastSelectionAction.java
deleted file mode 100644
index ffb4fb4..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/RestoreLastSelectionAction.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Restore the selection to what it was before it last changed.
- */
-public class RestoreLastSelectionAction extends AbstractVexAction {
-
-	public void run(IVexWidget vexWidget) {
-		throw new UnsupportedOperationException(
-				"RestoreLastSelectionAction is not yet implemented.");
-	}
-
-	public boolean isEnabled(IVexWidget vexWidget) {
-		return false;
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitAction.java
deleted file mode 100644
index 8285abb..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitAction.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.wst.xml.vex.core.internal.VEXCorePlugin;
-import org.eclipse.wst.xml.vex.core.internal.css.CSS;
-import org.eclipse.wst.xml.vex.core.internal.css.Styles;
-import org.eclipse.wst.xml.vex.core.internal.dom.Element;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocumentFragment;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Splits the current block element.
- */
-public class SplitAction extends AbstractVexAction {
-
-	public void run(final IVexWidget vexWidget) {
-		VEXElement element = vexWidget.getCurrentElement();
-		Styles styles = vexWidget.getStyleSheet().getStyles(element);
-		while (!styles.isBlock()) {
-			element = element.getParent();
-			styles = vexWidget.getStyleSheet().getStyles(element);
-		}
-		splitElement(vexWidget, element);
-	}
-
-	/**
-	 * Splits the given element.
-	 * 
-	 * @param vexWidget
-	 *            IVexWidget containing the document.
-	 * @param element
-	 *            Element to be split.
-	 */
-	public static void splitElement(final IVexWidget vexWidget,
-			final VEXElement element) {
-
-		vexWidget.doWork(new Runnable() {
-			public void run() {
-
-				long start = 0;
-				if (VEXCorePlugin.getInstance().isDebugging()) {
-					start = System.currentTimeMillis();
-				}
-
-				Styles styles = vexWidget.getStyleSheet().getStyles(element);
-
-				if (styles.getWhiteSpace().equals(CSS.PRE)) {
-					// can't call vexWidget.insertText() or we'll get an
-					// infinite loop
-					VEXDocument doc = vexWidget.getDocument();
-					int offset = vexWidget.getCaretOffset();
-					doc.insertText(offset, "\n");
-					vexWidget.moveTo(offset + 1);
-				} else {
-
-					// There may be a number of child elements below the given
-					// element. We cut out the tails of each of these elements
-					// and put them in a list of fragments to be reconstructed
-					// when
-					// we clone the element.
-					List children = new ArrayList();
-					List frags = new ArrayList();
-					VEXElement child = vexWidget.getCurrentElement();
-					while (true) {
-						children.add(child);
-						vexWidget.moveTo(child.getEndOffset(), true);
-						frags.add(vexWidget.getSelectedFragment());
-						vexWidget.deleteSelection();
-						vexWidget.moveTo(child.getEndOffset() + 1);
-						if (child == element) {
-							break;
-						}
-						child = child.getParent();
-					}
-
-					for (int i = children.size() - 1; i >= 0; i--) {
-						child = (Element) children.get(i);
-						VEXDocumentFragment frag = (VEXDocumentFragment) frags.get(i);
-						vexWidget.insertElement((Element) child.clone());
-						int offset = vexWidget.getCaretOffset();
-						if (frag != null) {
-							vexWidget.insertFragment(frag);
-						}
-						vexWidget.moveTo(offset);
-					}
-				}
-
-				if (VEXCorePlugin.getInstance().isDebugging()) {
-					long end = System.currentTimeMillis();
-					System.out.println("split() took " + (end - start) + "ms");
-				}
-			}
-		});
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitItemAction.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitItemAction.java
deleted file mode 100644
index 296cd58..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/SplitItemAction.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.wst.xml.vex.core.internal.css.CSS;
-import org.eclipse.wst.xml.vex.core.internal.css.StyleSheet;
-import org.eclipse.wst.xml.vex.core.internal.layout.Box;
-import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
-import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-
-/**
- * Splits the nearest enclosing table row or list item. If a table row is being
- * split, empty versions of the current row's cells are created.
- */
-public class SplitItemAction extends AbstractVexAction {
-
-	public void run(IVexWidget vexWidget) {
-
-		final StyleSheet ss = vexWidget.getStyleSheet();
-
-		// Item is either a TableRowBox or a BlockElementBox representing
-		// a list item
-		Box item = vexWidget.findInnermostBox(new IBoxFilter() {
-			public boolean matches(Box box) {
-				if (box instanceof TableRowBox) {
-					return true;
-				} else {
-					VEXElement element = box.getElement();
-					return element != null
-							&& ss.getStyles(element).getDisplay().equals(
-									CSS.LIST_ITEM);
-				}
-			}
-		});
-
-		if (item instanceof TableRowBox) {
-			insertRowBelowAction.run(vexWidget);
-			// ActionUtils.duplicateTableRow(vexWidget, (TableRowBox) item);
-		} else if (item != null) {
-			SplitAction.splitElement(vexWidget, item.getElement());
-		}
-	}
-
-	private static InsertRowBelowAction insertRowBelowAction = new InsertRowBelowAction();
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/TableCellCallback.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/TableCellCallback.java
deleted file mode 100644
index 653266b..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/TableCellCallback.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-/**
- * Callback interface called from LayoutUtils.iterateTableCells.
- */
-public interface TableCellCallback {
-
-	/**
-	 * Called before the first cell in a row is visited.
-	 * 
-	 * @param row
-	 *            Element or IntRange representing the row.
-	 * @param rowIndex
-	 *            Zero-based index of the row.
-	 */
-	public void startRow(Object row, int rowIndex);
-
-	/**
-	 * Called when a cell is visited.
-	 * 
-	 * @param row
-	 *            Element or IntRange representing the row.
-	 * @param cell
-	 *            Element or IntRange representing the cell.
-	 * @param rowIndex
-	 *            Zero-based index of the current row.
-	 * @param cellIndex
-	 *            Zero-based index of the current cell.
-	 */
-	public void onCell(Object row, Object cell, int rowIndex, int cellIndex);
-
-	/**
-	 * Called after the last cell in a row is visited.
-	 * 
-	 * @param row
-	 *            Element or IntRange representing the row.
-	 * @param rowIndex
-	 *            Zero-based index of the row.
-	 */
-	public void endRow(Object row, int rowIndex);
-
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/VexActionAdapter.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/VexActionAdapter.java
deleted file mode 100644
index 6cbaa3b..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/action/VexActionAdapter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.action;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.wst.xml.vex.ui.internal.action.IVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.editor.Messages;
-import org.eclipse.wst.xml.vex.ui.internal.editor.VexEditor;
-import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
-
-/**
- * Adapts a JFace Action to an IVexAction instance. The ID and definition ID of
- * the resulting action is set to the classname of the action. Localized strings
- * for the action are pulled from the classname of the given action. For
- * example, if the action is
- * "org.eclipse.wst.vex.ui.internal.action.PasteTextAction", the following
- * properties are retrieved from plugin.xml:
- * 
- * <dl>
- * <dt>PasteTextAction.label</dt>
- * <dd>The action's label.</dd>
- * <dt>PasteTextAction.tooltip</dt>
- * <dd>The action's tooltip.</dd>
- * </dl>
- */
-public class VexActionAdapter extends Action {
-
-	/**
-	 * Class constructor.
-	 * 
-	 * @param editor
-	 *            VexEditor to which the action will apply.
-	 * @param action
-	 *            IVexAction to be invoked.
-	 */
-	public VexActionAdapter(VexEditor editor, IVexAction action) {
-
-		this.editor = editor;
-		this.action = action;
-
-		String id = action.getClass().getName();
-		int i = id.lastIndexOf("."); //$NON-NLS-1$
-		String key = id.substring(i + 1);
-
-		this.setId(id);
-		this.setActionDefinitionId(id);
-		this.setText(Messages.getString(key + ".label")); //$NON-NLS-1$
-		//this.setToolTipText(Messages.getString(key + ".tooltip")); //$NON-NLS-1$
-	}
-
-	public void run() {
-		VexWidget vexWidget = this.editor.getVexWidget();
-		if (vexWidget != null) {
-			this.action.run(vexWidget);
-		}
-	}
-
-	private VexEditor editor;
-	private IVexAction action;
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/InsertAssistant.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/InsertAssistant.java
index a4419c4..58f7bf6 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/InsertAssistant.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/InsertAssistant.java
@@ -25,6 +25,6 @@
 	}
 
 	public String getTitle(VexWidget vexWidget) {
-		return Messages.getString("InsertAssistant.title"); //$NON-NLS-1$
+		return Messages.getString("dialog.addElement.title"); //$NON-NLS-1$
 	}
 }
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/MorphAssistant.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/MorphAssistant.java
index 98dc68f..77d24c5 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/MorphAssistant.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/contentassist/MorphAssistant.java
@@ -28,7 +28,7 @@
 
 	public String getTitle(VexWidget vexWidget) {
 		String message = Messages
-				.getString("ChangeElementAction.dynamic.label"); //$NON-NLS-1$
+				.getString("dialog.convertElement.dynamicTitle"); //$NON-NLS-1$
 		String name = vexWidget.getCurrentElement().getName();
 		return MessageFormat.format(message, new Object[] { name });
 	}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/DocumentContextSourceProvider.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/DocumentContextSourceProvider.java
new file mode 100644
index 0000000..bc191be
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/DocumentContextSourceProvider.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.editor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ui.AbstractSourceProvider;
+import org.eclipse.ui.ISources;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.RowColumnInfo;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * If this class is declared in {@code org.eclipse.ui.services} extension then
+ * state information about {@link VexWidget} could be exposed by variables.
+ * This variables could then be used to manage visibility or enablement of UI
+ * elements declarative in plug-in extensions (e.g. see 'enabledWhen' in
+ * {@code org.eclipse.ui.handlers} extension or 'visibleWhen' in
+ * {@code org.eclipse.ui.menus} extension).
+ */
+public class DocumentContextSourceProvider extends AbstractSourceProvider {
+
+    /** Variable ID of the <em>is-column</em> flag.*/
+    public static final String IS_COLUMN =
+        "org.eclipse.wst.xml.vex.ui.isColumn";
+
+    /** Variable ID of the <em>is-first-column</em> flag.*/
+    public static final String IS_FIRST_COLUMN =
+        "org.eclipse.wst.xml.vex.ui.isFirstColumn";
+
+    /** Variable ID of the <em>is-last-column</em> flag.*/
+    public static final String IS_LAST_COLUMN =
+        "org.eclipse.wst.xml.vex.ui.isLastColumn";
+
+    /** Variable ID of the <em>is-row</em> flag.*/
+    public static final String IS_ROW =
+        "org.eclipse.wst.xml.vex.ui.isRow";
+
+    /** Variable ID of the <em>is-fist-row</em> flag.*/
+    public static final String IS_FIRST_ROW =
+        "org.eclipse.wst.xml.vex.ui.isFirstRow";
+
+    /** Variable ID of the <em>is-last-row</em> flag.*/
+    public static final String IS_LAST_ROW =
+        "org.eclipse.wst.xml.vex.ui.isLastRow";
+
+    private boolean isColumn;
+    private boolean isFirstColumn;
+    private boolean isLastColumn;
+    private boolean isRow;
+    private boolean isFirstRow;
+    private boolean isLastRow;
+
+    public void dispose() {
+        // nothing to clean-up (all fields are primitives)
+    }
+
+    public String[] getProvidedSourceNames() {
+        return new String[] {IS_COLUMN};
+    }
+
+    public Map<String, Boolean> getCurrentState() {
+        Map<String, Boolean> currentState = new HashMap<String, Boolean>(6);
+        currentState.put(IS_COLUMN, Boolean.valueOf(isColumn));
+        currentState.put(IS_FIRST_COLUMN, Boolean.valueOf(isFirstColumn));
+        currentState.put(IS_LAST_COLUMN, Boolean.valueOf(isLastColumn));
+        currentState.put(IS_ROW, Boolean.valueOf(isRow));
+        currentState.put(IS_FIRST_ROW, Boolean.valueOf(isFirstRow));
+        currentState.put(IS_LAST_ROW, Boolean.valueOf(isLastRow));
+        return currentState;
+    }
+
+    /**
+     * Synchronizes the variable values which will be exposed by this service
+     * with the specified {@link VexWidget}.
+     *
+     * @param widget the Vex widget containing the actual states
+     */
+    public void fireUpdate(VexWidget widget) {
+        Map<String, Boolean> changes = new HashMap<String, Boolean>();
+        RowColumnInfo rowColumnInfo = VexHandlerUtil.getRowColumnInfo(widget);
+
+        // column
+        int columnIndex = VexHandlerUtil.getCurrentColumnIndex(widget);
+        int columnCount = rowColumnInfo == null ? -1 : rowColumnInfo.maxColumnCount;
+        isColumn = update(changes, isColumn, columnIndex != -1, IS_COLUMN);
+        isFirstColumn = update(changes, isFirstColumn, columnIndex == 0, IS_FIRST_COLUMN);
+        isLastColumn = update(changes, isLastColumn, columnIndex == columnCount - 1, IS_LAST_COLUMN);
+
+        // row
+        int rowCount = rowColumnInfo == null ? -1 : rowColumnInfo.rowCount;
+        int rowIndex = rowColumnInfo == null ? -1 : rowColumnInfo.rowIndex;
+        isRow = update(changes, isRow, rowIndex != -1, IS_ROW);
+        isFirstRow = update(changes, isFirstRow, rowIndex == 0, IS_FIRST_ROW);
+        isLastRow = update(changes, isLastRow, rowIndex == rowCount - 1, IS_LAST_ROW);
+
+        if (!changes.isEmpty()) {
+            fireSourceChanged(ISources.WORKBENCH, changes);
+        }
+    }
+
+    private static boolean update(Map<String, Boolean> changes,
+                                  boolean oldValue,
+                                  boolean newValue,
+                                  String valueName) {
+        if (newValue == oldValue) return oldValue;
+
+        changes.put(valueName, Boolean.valueOf(newValue));
+        return newValue;
+    }
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionBarContributor.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionBarContributor.java
index 52cc87b..3dfada0 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionBarContributor.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionBarContributor.java
@@ -13,17 +13,14 @@
 import java.util.ResourceBundle;
 
 import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.GroupMarker;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.actions.ActionFactory;
@@ -33,20 +30,6 @@
 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
 import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorActionBarContributor;
 import org.eclipse.wst.xml.vex.core.internal.dom.DocumentValidationException;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-import org.eclipse.wst.xml.vex.ui.internal.action.ActionUtils;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteColumnAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteRowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnAfterAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnBeforeAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowAboveAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowBelowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnLeftAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnRightAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowDownAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowUpAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.VexActionAdapter;
 import org.eclipse.wst.xml.vex.ui.internal.config.Style;
 import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
 
@@ -58,10 +41,6 @@
 	public void dispose() {
 	}
 
-	public MenuManager getContextMenuManager() {
-		return this.contextMenuManager;
-	}
-
 	public VexEditor getVexEditor() {
 		return (VexEditor) activeEditor;
 	}
@@ -77,10 +56,6 @@
 	public void init(IActionBars bars, IWorkbenchPage page) {
 		super.init(bars, page);
 
-		this.contextMenuManager = new MenuManager();
-		this.contextMenuManager.setRemoveAllWhenShown(true);
-		this.contextMenuManager.addMenuListener(this.contextMenuListener);
-
 		page.addSelectionListener(this.selectionListener);
 
 		this.globalCopyAction = ActionFactory.COPY.create(page
@@ -174,44 +149,6 @@
 	private IAction selectAllAction = new SelectAllAction();
 	private IAction undoAction = new UndoAction();
 
-	private MenuManager contextMenuManager;
-	private IMenuListener contextMenuListener = new IMenuListener() {
-
-		public void menuAboutToShow(IMenuManager manager) {
-
-			boolean showTableActions = false;
-			IVexWidget vexWidget = getVexWidget();
-			if (vexWidget != null) {
-				showTableActions = ActionUtils.getSelectedTableRows(vexWidget)
-						.getRows() != null;
-			}
-
-			manager.add(globalUndoAction);
-			manager.add(globalRedoAction);
-			manager.add(new Separator());
-			manager.add(new VexActionAdapter(getVexEditor(),
-					new InsertElementAction()));
-
-			if (showTableActions) {
-				manager.add(new Separator());
-				manager.add(new RowMenuManager());
-				manager.add(new ColumnMenuManager());
-			}
-
-			manager.add(new Separator());
-			manager.add(globalCutAction);
-			manager.add(globalCopyAction);
-			manager.add(globalPasteAction);
-			manager.add(new Separator());
-			manager.add(globalDeleteAction);
-			manager.add(new Separator());
-			manager.add(new StyleMenuManager());
-			manager
-					.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-		}
-
-	};
-
 	private void enableActions() {
 		VexWidget widget = this.getVexWidget();
 		this.copyAction.setEnabled(widget != null && widget.hasSelection());
@@ -301,40 +238,6 @@
 		}
 	}
 
-	private class RowMenuManager extends MenuManager {
-		public RowMenuManager() {
-			super(Messages.getString("VexActionBarContributor.rowMenu.name")); //$NON-NLS-1$
-			this.add(new VexActionAdapter(getVexEditor(),
-					new InsertRowAboveAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new InsertRowBelowAction()));
-			this
-					.add(new VexActionAdapter(getVexEditor(),
-							new DeleteRowAction()));
-			this
-					.add(new VexActionAdapter(getVexEditor(),
-							new MoveRowUpAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new MoveRowDownAction()));
-		}
-	}
-
-	private class ColumnMenuManager extends MenuManager {
-		public ColumnMenuManager() {
-			super(Messages.getString("VexActionBarContributor.columnMenu.name")); //$NON-NLS-1$
-			this.add(new VexActionAdapter(getVexEditor(),
-					new InsertColumnBeforeAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new InsertColumnAfterAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new DeleteColumnAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new MoveColumnLeftAction()));
-			this.add(new VexActionAdapter(getVexEditor(),
-					new MoveColumnRightAction()));
-		}
-	}
-
 	private class RedoAction extends Action {
 		public void run() {
 			if (getVexWidget().canRedo()) {
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionDelegate.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionDelegate.java
deleted file mode 100644
index 63115fa..0000000
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexActionDelegate.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay 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:
- *     John Krasnay - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.xml.vex.ui.internal.editor;
-
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
-import org.eclipse.wst.xml.vex.ui.internal.VexPlugin;
-import org.eclipse.wst.xml.vex.ui.internal.action.ChangeElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.IVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RemoveElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
-
-/**
- * An IWorkbenchWindowActionDelegate that defers to to an instance of
- * IVexAction. The IDs of actions in plugin.xml using this delegate must be the
- * classnames of actions implementing IVexAction. Such classes must have a
- * no-args constructor.
- */
-public class VexActionDelegate implements IWorkbenchWindowActionDelegate {
-
-	private static Map actions = new HashMap();
-
-	public VexActionDelegate() {
-	}
-
-	public void dispose() {
-	}
-
-	public void init(IWorkbenchWindow window) {
-		this.window = window;
-	}
-
-	public void run(IAction action) {
-		IVexAction vexAction = getAction(action.getId());
-		if (vexAction == null) {
-			return;
-		}
-
-		VexWidget vexWidget = this.getVexWidget();
-		if (vexWidget != null) {
-			vexWidget.setFocus();
-			vexAction.run(vexWidget);
-		}
-	}
-
-	public void selectionChanged(IAction action, ISelection selection) {
-
-		IVexAction vexAction = getAction(action.getId());
-		boolean enabled;
-
-		if (vexAction == null) {
-			enabled = false;
-		} else {
-			IVexWidget vexWidget = this.getVexWidget();
-			if (vexWidget == null) {
-				enabled = false;
-			} else {
-				enabled = vexAction.isEnabled(vexWidget);
-
-				if (action.getId().equals(ChangeElementAction.class.getName())) {
-					String elementName = vexWidget.getCurrentElement()
-							.getName();
-					String message = Messages
-							.getString("ChangeElementAction.dynamic.label"); //$NON-NLS-1$
-					action.setText(MessageFormat.format(message,
-							new Object[] { elementName }));
-				}
-
-				if (action.getId().equals(RemoveElementAction.class.getName())) {
-					String elementName = vexWidget.getCurrentElement()
-							.getName();
-					String message = Messages
-							.getString("RemoveElementAction.dynamic.label"); //$NON-NLS-1$
-					action.setText(MessageFormat.format(message,
-							new Object[] { elementName }));
-				}
-			}
-		}
-
-		action.setEnabled(enabled);
-	}
-
-	private IWorkbenchWindow window;
-
-	private VexWidget getVexWidget() {
-		IEditorPart editor = this.window.getActivePage().getActiveEditor();
-		if (editor != null && editor instanceof VexEditor) {
-			return ((VexEditor) editor).getVexWidget();
-		} else {
-			return null;
-		}
-	}
-
-	private static IVexAction getAction(String actionId) {
-		try {
-			IVexAction action = (IVexAction) actions.get(actionId);
-			if (action == null) {
-				action = (IVexAction) Class.forName(actionId).newInstance();
-				actions.put(actionId, action);
-			}
-			return action;
-		} catch (Exception ex) {
-			String message = MessageFormat.format(Messages
-					.getString("VexActionDelegate.errorLoadingAction"), //$NON-NLS-1$
-					new Object[] { actionId, ex.getMessage() });
-			VexPlugin.getInstance().log(IStatus.ERROR, message, ex);
-			return null;
-		}
-	}
-}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditor.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditor.java
index f1e32c0..1308ebc 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditor.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditor.java
@@ -36,9 +36,7 @@
 import org.eclipse.core.runtime.preferences.IPreferencesService;
 import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.commands.ActionHandler;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IFindReplaceTarget;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -53,13 +51,17 @@
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.commands.ICommandService;
 import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.dialogs.SaveAsDialog;
 import org.eclipse.ui.editors.text.ILocationProvider;
 import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.EditorPart;
 import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.services.IServiceLocator;
+import org.eclipse.ui.services.ISourceProviderService;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.eclipse.ui.views.properties.IPropertySheetPage;
 import org.eclipse.ui.views.properties.IPropertySource;
@@ -75,43 +77,23 @@
 import org.eclipse.wst.xml.vex.core.internal.core.ListenerList;
 import org.eclipse.wst.xml.vex.core.internal.dom.DOMDocumentReader;
 import org.eclipse.wst.xml.vex.core.internal.dom.Document;
-import org.eclipse.wst.xml.vex.core.internal.dom.DocumentReader;
 import org.eclipse.wst.xml.vex.core.internal.dom.DocumentWriter;
 import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicy;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicyFactory;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.Validator;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicy;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicyFactory;
 import org.eclipse.wst.xml.vex.core.internal.validator.WTPVEXValidator;
 import org.eclipse.wst.xml.vex.core.internal.widget.CssWhitespacePolicy;
 import org.eclipse.wst.xml.vex.ui.internal.VexPlugin;
-import org.eclipse.wst.xml.vex.ui.internal.action.ChangeElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteColumnAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteRowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DuplicateSelectionAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnAfterAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnBeforeAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowAboveAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowBelowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnLeftAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnRightAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowDownAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowUpAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.NextTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.PasteTextAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.PreviousTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RemoveElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RestoreLastSelectionAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitItemAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.VexActionAdapter;
 import org.eclipse.wst.xml.vex.ui.internal.config.ConfigEvent;
 import org.eclipse.wst.xml.vex.ui.internal.config.ConfigRegistry;
 import org.eclipse.wst.xml.vex.ui.internal.config.DocumentType;
 import org.eclipse.wst.xml.vex.ui.internal.config.IConfigListener;
 import org.eclipse.wst.xml.vex.ui.internal.config.Style;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.ConvertElementHandler;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.RemoveTagHandler;
 import org.eclipse.wst.xml.vex.ui.internal.outline.DocumentOutlinePage;
 import org.eclipse.wst.xml.vex.ui.internal.property.ElementPropertySource;
 import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
@@ -676,9 +658,9 @@
 		VexActionBarContributor contributor = (VexActionBarContributor) this
 				.getEditorSite().getActionBarContributor();
 
-		MenuManager menuMgr = contributor.getContextMenuManager();
-		this.getSite().registerContextMenu(menuMgr, this.vexWidget);
-		this.vexWidget.setMenu(menuMgr.createContextMenu(this.vexWidget));
+		MenuManager menuManager = new MenuManager();
+		getSite().registerContextMenu("org.eclipse.wst.xml.vex.ui.popup", menuManager, vexWidget);
+		vexWidget.setMenu(menuManager.createContextMenu(vexWidget));
 
 		this.savedUndoDepth = this.vexWidget.getUndoDepth();
 
@@ -690,103 +672,6 @@
 		IHandlerService hs = (IHandlerService) this.getSite().getService(
 				IHandlerService.class);
 
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.ChangeElementAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new ChangeElementAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.DeleteColumnAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new DeleteColumnAction())));
-
-		hs.activateHandler("org.eclipse.wst.xml.vex.ui.action.DeleteRowAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new DeleteRowAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.DuplicateSelectionAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new DuplicateSelectionAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.InsertColumnAfterAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new InsertColumnAfterAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.InsertColumnBeforeAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new InsertColumnBeforeAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.editor.action.InsertElementAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new InsertElementAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.InsertRowAboveAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new InsertRowAboveAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.InsertRowBelowAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new InsertRowBelowAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.MoveColumnLeftAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new MoveColumnLeftAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.MoveColumnRightAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new MoveColumnRightAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.MoveRowDownAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new MoveRowDownAction())));
-
-		hs.activateHandler("org.eclipse.wst.xml.vex.ui.action.MoveRowUpAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new MoveRowUpAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.NextTableCellAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new NextTableCellAction())));
-
-		hs.activateHandler("org.eclipse.wst.xml.vex.ui.action.PasteTextAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new PasteTextAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.PreviousTableCellAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new PreviousTableCellAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.RemoveElementAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new RemoveElementAction())));
-
-		hs.activateHandler(
-				"org.eclipse.wst.xml.vex.ui.action.RestoreLastSelectionAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new RestoreLastSelectionAction())));
-
-		hs
-				.activateHandler(
-						"org.eclipse.wst.xml.vex.ui.action.SplitAction",
-						new ActionHandler(new VexActionAdapter(this,
-								new SplitAction())));
-
-		hs.activateHandler("org.eclipse.wst.xml.vex.ui.action.SplitItemAction",
-				new ActionHandler(new VexActionAdapter(this,
-						new SplitItemAction())));
-
 		this.vexWidget.addSelectionChangedListener(this.selectionProvider);
 
 		this.parentControl.layout(true);
@@ -909,6 +794,22 @@
 				wasDirty = isDirty();
 			}
 			setStatus(getLocation());
+			
+			// update dynamic UI element labels
+			IEditorSite editorSite = VexEditor.this.getEditorSite();
+			IWorkbenchWindow window = editorSite.getWorkbenchWindow();
+			if (window instanceof IServiceLocator) {
+				IServiceLocator serviceLocator = (IServiceLocator) window;
+				ICommandService commandService = (ICommandService)serviceLocator.getService(ICommandService.class);
+				commandService.refreshElements(ConvertElementHandler.COMMAND_ID, null);
+				commandService.refreshElements(RemoveTagHandler.COMMAND_ID, null);
+			}
+			
+			// update context service
+			ISourceProviderService service = (ISourceProviderService) window.getService(ISourceProviderService.class);
+			DocumentContextSourceProvider contextProvider =
+				(DocumentContextSourceProvider) service.getSourceProvider(DocumentContextSourceProvider.IS_COLUMN);
+			contextProvider.fireUpdate(vexWidget);
 		}
 	};
 
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditorMultiPage.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditorMultiPage.java
index fa5e541..9f82cc5 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditorMultiPage.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/VexEditorMultiPage.java
@@ -34,8 +34,6 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.preferences.IPreferencesService;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.commands.ActionHandler;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -54,7 +52,6 @@
 import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.dialogs.SaveAsDialog;
 import org.eclipse.ui.editors.text.ILocationProvider;
-import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.part.EditorPart;
 import org.eclipse.ui.part.FileEditorInput;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
@@ -69,40 +66,18 @@
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
 import org.eclipse.wst.xml.vex.core.internal.core.ListenerList;
-import org.eclipse.wst.xml.vex.core.internal.dom.DOMDocumentReader;
 import org.eclipse.wst.xml.vex.core.internal.dom.Document;
 import org.eclipse.wst.xml.vex.core.internal.dom.DocumentReader;
 import org.eclipse.wst.xml.vex.core.internal.dom.DocumentWriter;
 import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicy;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicyFactory;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
 import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.Validator;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicy;
-import org.eclipse.wst.xml.vex.core.internal.provisional.dom.IWhitespacePolicyFactory;
 import org.eclipse.wst.xml.vex.core.internal.validator.WTPVEXValidator;
 import org.eclipse.wst.xml.vex.core.internal.widget.CssWhitespacePolicy;
 import org.eclipse.wst.xml.vex.ui.internal.VexPlugin;
-import org.eclipse.wst.xml.vex.ui.internal.action.ChangeElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteColumnAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DeleteRowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DuplicateSelectionAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnAfterAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertColumnBeforeAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowAboveAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.InsertRowBelowAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnLeftAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveColumnRightAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowDownAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.MoveRowUpAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.NextTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.PasteTextAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.PreviousTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RemoveElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RestoreLastSelectionAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitItemAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.VexActionAdapter;
 import org.eclipse.wst.xml.vex.ui.internal.config.ConfigEvent;
 import org.eclipse.wst.xml.vex.ui.internal.config.ConfigRegistry;
 import org.eclipse.wst.xml.vex.ui.internal.config.DocumentType;
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages.properties b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages.properties
index 7e03ee1..6b7f0d1 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages.properties
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages.properties
@@ -2,46 +2,12 @@
 # Language-specific strings in the vex-editor plugin
 #
 
+command.removeTag.dynamicName= Remove ''{0}'' Tag
+command.removeTag.inRemoveMenu.dynamicName= ''{0}'' &Tag
+command.convertElement.dynamicName= &Convert ''{0}'' To...
 
-#
-# Actions
-#
-# NOTE: THESE MUST BE KEPT IN SYNC WITH THE SAME BLOCK IN plugin.properties
-#
-# Note: when there are multiple labels for an action, the one named
-# Xxx.label is the command listed in the key bindings preference page.
-#
-ChangeElementAction.label=Change Element
-ChangeElementAction.dynamic.label=&Change <{0}> to...
-ChangeElementAction.menu.label=&Change Element...
-DeleteColumnAction.label=Delete Column
-DebugView.noActiveEditor=No Vex editor is currently active.
-DeleteRowAction.label=Delete Row
-DuplicateSelectionAction.label=&Duplicate Selection
-InsertColumnAfterAction.label=Insert Column After
-InsertColumnBeforeAction.label=Insert Column Before
-InsertElementAction.label=Insert Element
-InsertAssistant.title=Insert Element
-InsertElementAction.contextmenu.label=Insert Element...
-InsertElementAction.mainmenu.label=&Element...
-InsertRowAboveAction.label=Insert Row Above
-InsertRowBelowAction.label=Insert Row Below
-MoveColumnLeftAction.label=Move Column Left
-MoveColumnRightAction.label=Move Column Right
-MoveRowDownAction.label=Move Row Down
-MoveRowUpAction.label=Move Row Up
-NextTableCellAction.label=Next Table Cell
-PasteTextAction.label=Paste Text
-PreviousTableCellAction.label=Previous Table Cell
-RemoveElementAction.label=Remove Element
-RemoveElementAction.dynamic.label=Remove <{0}>
-RestoreLastSelectionAction.label=Restore Last Selection
-SplitAction.label=Split Block Element
-SplitItemAction.label=Split Item
-
-#
-# End of Actions
-#
+dialog.addElement.title= Add Element
+dialog.convertElement.dynamicTitle= Convert ''{0}''
 
 DebugView.noActiveEditor=No Vex editor is currently active.
 
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages_fr.properties b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages_fr.properties
index 872a25e..d871b25 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages_fr.properties
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/editor/messages_fr.properties
@@ -1,102 +1,61 @@
-#

-# Language-specific strings in the vex-editor plugin

-#

-

-

-#

-# Actions

-#

-# NOTE: THESE MUST BE KEPT IN SYNC WITH THE SAME BLOCK IN plugin.properties

-#

-# Note: when there are multiple labels for an action, the one named

-# Xxx.label is the command listed in the key bindings preference page.

-#

-ChangeElementAction.label=Changer l'élément

-ChangeElementAction.dynamic.label=&Changer <{0}> en...

-ChangeElementAction.menu.label=&Changer l'élément...

-DeleteColumnAction.label=Detruire la colonne

-DebugView.noActiveEditor=Pas d'éditeur Vex actif

-DeleteRowAction.label=Détruire la ligne

-DuplicateSelectionAction.label=&Dupliquer la sélection

-InsertColumnAfterAction.label=Insérer une colonne après

-InsertColumnBeforeAction.label=Insérer une colonne avant

-InsertElementAction.label=Insérer un élément

-InsertAssistant.title=Insérer un élément

-InsertElementAction.contextmenu.label=Insérer l'élément...

-InsertElementAction.mainmenu.label=&Elément...

-InsertRowAboveAction.label=Insérer une ligne au dessus

-InsertRowBelowAction.label=Insérer une ligne en dessous

-MoveColumnLeftAction.label=Déplacer la colonne à gauche

-MoveColumnRightAction.label=Déplacer la colonne à droite

-MoveRowDownAction.label=Déplacer la ligne en dessous

-MoveRowUpAction.label=Déplacer la ligne au dessus

-NextTableCellAction.label=Prochaine cellule du tableau

-PasteTextAction.label=Copier le texte

-PreviousTableCellAction.label=Cellule précédente du tableau

-RemoveElementAction.label=Supprimer l'élément

-RemoveElementAction.dynamic.label=Supprimer <{0}>

-RestoreLastSelectionAction.label=Restaurer la sélection précédente

-SplitAction.label=Couper le bloc

-SplitItemAction.label=Couper l'item

-

-#

-# End of Actions

-#

-

-DebugView.noActiveEditor=Pas d'éditeur Vex actif.

-

-DocumentFileCreationPage.title=Fichier

-DocumentFileCreationPage.desc=Entrer un nom de fichier pour le nouveau document.

-

-DocumentOutlinePage.loadingError=Exception au chargement de {0} du bundle {1}: {2}

-DocumentOutlinePage.loading=Chargement...

-DocumentOutlinePage.reloading=Rechargement...

-

-Messages.cantFindResource=Ne peut pas trouver la chaine de la ressource {0}

-

-DocumentTypeSelectionDialog.ok=Accepter

-DocumentTypeSelectionDialog.cancel=Abandonner

-DocumentTypeSelectionDialog.unknownDoctype=Vex ne connait pas le type de document '{0}'. Pour ouvrir le document avec un autre type de document, sélectionner un des types enregistrés ci-dessous.

-DocumentTypeSelectionDialog.selectDoctype=Sélectionner un type de document

-DocumentTypeSelectionDialog.noDoctype=Vex ne peut pas déterminer le type de document pour le document sélectionné. Sélectionner un des types de document dans la liste suivante.

-DocumentTypeSelectionDialog.alwaysUse=Toujours utiliser ce type de document pour le document sélectionné.

-Always use this document type for the selected document.

-

-DocumentTypeSelectionPage.title=Type de document

-DocumentTypeSelectionPage.desc=Sélectionner le type de document et la racine pour le nouveau document.

-DocumentTypeSelectionPage.doctype=Type de document:

-DocumentTypeSelectionPage.pageName=Sélectionner le type

-DocumentTypeSelectionPage.rootElement=Elément racine:

-

-ElementPropertySource.multiple=(multiple)

-

-NewDocumentWizard.title=Nouveau Document Vex

-NewDocumentWizard.noStyles.title=Erreur

-NewDocumentWizard.noStyles.message=Pas de styles pour le type de document donné

-NewDocumentWizard.errorLoading.message=Erreur de chargement {0}: {1}

-NewDocumentWizard.errorLoading.title=Erreur

-

-VexActionBarContributor.styleMenu.name=Style

-VexActionBarContributor.noValidItems=Pas d'article valide

-

-VexActionDelegate.errorLoadingAction=Erreur sur l'action de chargement {0}: {1}

-

-VexEditor.errorSaving.title=Erreur

-VexEditor.errorSaving.message=Erreur de sauvegarde {0}: {1}

-VexEditor.unknownInputClass=Impssible d'ouvrir les entrées de type {0}. Envoyer un rapport de bogue à http://krasnay.ca/bugzilla SVP.

-VexEditor.noDoctype=Impossible de déterminer le type de document pour le document sélectionné.

-VexEditor.unknownDoctype=Pas de type de document enregistré pour la clé publique : {0}.

-VexEditor.noStyles=Pas de style enregistré pour la clé publique : {0}.

-VexEditor.parseError=Erreur à la ligne {0} du fichier {1}: {2}

-VexEditor.unexpectedError=Erreur inconnue à l'ouverture de {0}.  Envoyer un rapport de bogue à http://krasnay.ca/bugzilla SVP.

-VexEditor.loading=En chargement...

-VexEditor.errorSavingStylePreference=Erreur à la sauvegarde des préférence de style

-VexEditor.docChanged.title=Document modifié

-VexEditor.docChanged.message=Le fichier {0} a été modifié en dehors de Vex. Voulez vous perdre vos modifications ou écraser les modifications extérieures?

-VexEditor.docChanged.discard=Perdre mes modifications

-VexEditor.docChanged.overwrite=Ecraser les autres

-VexEditor.docDeleted.title=Document supprimé

-VexEditor.docDeleted.message=Le fichier {0} a été supprimé de l'espace de travail. Voulez vous predre vos modifications ou enregistrer un nouveau document? 

-VexEditor.docDeleted.discard=Perdre

-VexEditor.docDeleted.save=Enregistrer

-VexEditor.noUrlForDoctype=Pas d'URL défini pour le doctype {0}

+#
+# Language-specific strings in the vex-editor plugin
+#
+
+DebugView.noActiveEditor=Pas d'éditeur Vex actif.
+
+DocumentFileCreationPage.title=Fichier
+DocumentFileCreationPage.desc=Entrer un nom de fichier pour le nouveau document.
+
+DocumentOutlinePage.loadingError=Exception au chargement de {0} du bundle {1}: {2}
+DocumentOutlinePage.loading=Chargement...
+DocumentOutlinePage.reloading=Rechargement...
+
+Messages.cantFindResource=Ne peut pas trouver la chaine de la ressource {0}
+
+DocumentTypeSelectionDialog.ok=Accepter
+DocumentTypeSelectionDialog.cancel=Abandonner
+DocumentTypeSelectionDialog.unknownDoctype=Vex ne connait pas le type de document '{0}'. Pour ouvrir le document avec un autre type de document, sélectionner un des types enregistrés ci-dessous.
+DocumentTypeSelectionDialog.selectDoctype=Sélectionner un type de document
+DocumentTypeSelectionDialog.noDoctype=Vex ne peut pas déterminer le type de document pour le document sélectionné. Sélectionner un des types de document dans la liste suivante.
+DocumentTypeSelectionDialog.alwaysUse=Toujours utiliser ce type de document pour le document sélectionné.
+Always use this document type for the selected document.
+
+DocumentTypeSelectionPage.title=Type de document
+DocumentTypeSelectionPage.desc=Sélectionner le type de document et la racine pour le nouveau document.
+DocumentTypeSelectionPage.doctype=Type de document:
+DocumentTypeSelectionPage.pageName=Sélectionner le type
+DocumentTypeSelectionPage.rootElement=Elément racine:
+
+ElementPropertySource.multiple=(multiple)
+
+NewDocumentWizard.title=Nouveau Document Vex
+NewDocumentWizard.noStyles.title=Erreur
+NewDocumentWizard.noStyles.message=Pas de styles pour le type de document donné
+NewDocumentWizard.errorLoading.message=Erreur de chargement {0}: {1}
+NewDocumentWizard.errorLoading.title=Erreur
+
+VexActionBarContributor.styleMenu.name=Style
+VexActionBarContributor.noValidItems=Pas d'article valide
+
+VexActionDelegate.errorLoadingAction=Erreur sur l'action de chargement {0}: {1}
+
+VexEditor.errorSaving.title=Erreur
+VexEditor.errorSaving.message=Erreur de sauvegarde {0}: {1}
+VexEditor.unknownInputClass=Impssible d'ouvrir les entrées de type {0}. Envoyer un rapport de bogue à http://krasnay.ca/bugzilla SVP.
+VexEditor.noDoctype=Impossible de déterminer le type de document pour le document sélectionné.
+VexEditor.unknownDoctype=Pas de type de document enregistré pour la clé publique : {0}.
+VexEditor.noStyles=Pas de style enregistré pour la clé publique : {0}.
+VexEditor.parseError=Erreur à la ligne {0} du fichier {1}: {2}
+VexEditor.unexpectedError=Erreur inconnue à l'ouverture de {0}.  Envoyer un rapport de bogue à http://krasnay.ca/bugzilla SVP.
+VexEditor.loading=En chargement...
+VexEditor.errorSavingStylePreference=Erreur à la sauvegarde des préférence de style
+VexEditor.docChanged.title=Document modifié
+VexEditor.docChanged.message=Le fichier {0} a été modifié en dehors de Vex. Voulez vous perdre vos modifications ou écraser les modifications extérieures?
+VexEditor.docChanged.discard=Perdre mes modifications
+VexEditor.docChanged.overwrite=Ecraser les autres
+VexEditor.docDeleted.title=Document supprimé
+VexEditor.docDeleted.message=Le fichier {0} a été supprimé de l'espace de travail. Voulez vous predre vos modifications ou enregistrer un nouveau document?
+VexEditor.docDeleted.discard=Perdre
+VexEditor.docDeleted.save=Enregistrer
+VexEditor.noUrlForDoctype=Pas d'URL défini pour le doctype {0}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddColumnHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddColumnHandler.java
new file mode 100644
index 0000000..fd03c27
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddColumnHandler.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Inserts a single table column before (left of) or after (right of) the
+ * current one.
+ *
+ * @see AddColumnLeftHandler
+ * @see AddColumnRightHandler
+ */
+public abstract class AbstractAddColumnHandler extends AbstractHandler {
+
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        final VexWidget widget = VexHandlerUtil.computeWidget(event);
+        widget.doWork(new Runnable() {
+            public void run() {
+                try {
+                    addColumn(widget);
+                } catch (ExecutionException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        return null;
+    }
+
+    private void addColumn(VexWidget widget) throws ExecutionException {
+        final int indexToDup = VexHandlerUtil.getCurrentColumnIndex(widget);
+
+        // adding possible?
+        if (indexToDup == -1) return;
+
+        final List cellsToDup = new ArrayList();
+        VexHandlerUtil.iterateTableCells(widget, new TableCellCallbackAdapter() {
+            public void onCell(Object row, Object cell, int rowIndex,
+                    int cellIndex) {
+                if (cellIndex == indexToDup && cell instanceof Element) {
+                    cellsToDup.add(cell);
+                }
+            }
+        });
+
+        int finalOffset = -1;
+        for (Iterator it = cellsToDup.iterator(); it.hasNext();) {
+            Element element = (Element) it.next();
+            if (finalOffset == -1) {
+                finalOffset = element.getStartOffset() + 1;
+            }
+            widget.moveTo(addBefore()
+                          ? element.getStartOffset()
+                          : element.getEndOffset() + 1);
+            widget.insertElement((Element) element.clone());
+        }
+
+        if (finalOffset != -1) {
+            widget.moveTo(finalOffset);
+        }
+    }
+
+    /**
+     * @return {@code true} to add new column before (left of) current column or
+     *         {@code false} to add new column after (right of) current column
+     */
+    protected abstract boolean addBefore();
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddRowHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddRowHandler.java
new file mode 100644
index 0000000..8232596
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractAddRowHandler.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Inserts one or more table rows either above or below the currently selected
+ * one(s). If more than one row is selected the same number of new rows will be
+ * created.
+ *
+ * @see AddRowBelowHandler
+ * @see AddRowAboveHandler
+ */
+public abstract class AbstractAddRowHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        widget.doWork(new Runnable() {
+            public void run() {
+                addRow(widget);
+            }
+        });
+    }
+
+    /**
+     * @return {@code true} to add new table row above current row or
+     *         {@code false} to add new row below current row
+     */
+    protected abstract boolean addAbove();
+
+    private void addRow(final VexWidget widget) {
+        final List<Object> rowsToInsert = new ArrayList<Object>();
+        final List<Object> rowCellsToInsert = new ArrayList<Object>();
+
+        VexHandlerUtil.iterateTableCells(widget, new ITableCellCallback() {
+
+            private boolean rowSelected;
+            private List<Object> cellsToInsert;
+
+            public void startRow(Object row, int rowIndex) {
+                rowSelected = VexHandlerUtil
+                .elementOrRangeIsPartiallySelected(
+                        widget, row);
+
+                if (rowSelected) {
+                    cellsToInsert = new ArrayList<Object>();
+                }
+            }
+
+            public void onCell(Object row, Object cell,
+                    int rowIndex, int cellIndex) {
+                if (rowSelected) {
+                    cellsToInsert.add(cell);
+                }
+            }
+
+            public void endRow(Object row, int rowIndex) {
+                if (rowSelected) {
+                    rowsToInsert.add(row);
+                    rowCellsToInsert.add(cellsToInsert);
+                }
+            }
+
+        });
+
+        if (rowsToInsert.size() == 0) {
+            return;
+        }
+
+        //
+        // save the caret offset so that we return just inside the first
+        // table cell
+        //
+        // (innerOffset - outerOffset) represents the final offset of
+        // the caret, relative to the insertion point of the new rows
+        //
+        int outerOffset = VexHandlerUtil.getOuterRange(rowsToInsert.get(0)).getStart();
+        List firstCells = (List) rowCellsToInsert.get(0);
+        Object firstInner = firstCells.isEmpty()
+                            ? rowsToInsert.get(0)
+                            : firstCells.get(0);
+        int innerOffset = VexHandlerUtil.getInnerRange(firstInner).getStart();
+
+        int insertOffset = addAbove()
+            ? VexHandlerUtil.getOuterRange(rowsToInsert.get(0)).getStart()
+            : VexHandlerUtil.getOuterRange(rowsToInsert.get(rowsToInsert.size() - 1)).getEnd();
+
+        int finalOffset = insertOffset + (innerOffset - outerOffset);
+
+        widget.moveTo(insertOffset);
+
+        for (int i = 0; i < rowsToInsert.size(); i++) {
+
+            Object row = rowsToInsert.get(i);
+
+            if (row instanceof Element) {
+                widget.insertElement((Element) ((VEXElement) row)
+                        .clone());
+            }
+
+            List cellsToInsert = (List) rowCellsToInsert.get(i);
+            for (int j = 0; j < cellsToInsert.size(); j++) {
+                Object cell = cellsToInsert.get(j);
+                if (cell instanceof Element) {
+                    widget.insertElement((Element) ((VEXElement) cell)
+                            .clone());
+                    widget.moveBy(+1);
+                } else {
+                    widget.insertText(" ");
+                }
+            }
+
+            if (row instanceof Element) {
+                widget.moveBy(+1);
+            }
+
+        }
+
+        widget.moveTo(finalOffset);
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveColumnHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveColumnHandler.java
new file mode 100644
index 0000000..89899ef
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveColumnHandler.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Moves the current table column either to the left or to the right.
+ *
+ * @see MoveColumnLeftHandler
+ * @see MoveColumnRightHandler
+ */
+public abstract class AbstractMoveColumnHandler extends AbstractHandler {
+
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        final VexWidget widget = VexHandlerUtil.computeWidget(event);
+        final VexHandlerUtil.RowColumnInfo rcInfo =
+            VexHandlerUtil.getRowColumnInfo(widget);
+
+        if (rcInfo == null || !movingPossible(rcInfo)) return null;
+
+        widget.doWork(true, new Runnable() {
+            public void run() {
+                List<Object> sourceCells = new ArrayList<Object>();
+                List<Object> targetCells = new ArrayList<Object>();
+                computeCells(widget, rcInfo, sourceCells, targetCells);
+                swapCells(widget, sourceCells, targetCells);
+            }
+        });
+        return null;
+    }
+
+    /**
+     * @return {@code true} to move column to the right or
+     *         {@code false} to move column to the left
+     */
+    protected abstract boolean moveRight();
+
+    private void computeCells(final VexWidget widget,
+                              final VexHandlerUtil.RowColumnInfo rcInfo,
+                              final List<Object> sourceCells,
+                              final List<Object> targetCells) {
+
+        VexHandlerUtil.iterateTableCells(widget,
+                                         new TableCellCallbackAdapter() {
+
+            private Object leftCell;
+
+            public void onCell(Object row,
+                               Object cell,
+                               int rowIndex,
+                               int cellIndex) {
+
+                if (leftCell(cellIndex, rcInfo.cellIndex)) {
+                    leftCell = cell;
+                } else if (rightCell(cellIndex, rcInfo.cellIndex)) {
+                    sourceCells.add(moveRight() ? cell : leftCell);
+                    targetCells.add(moveRight() ? leftCell : cell);
+                }
+            }
+        });
+    }
+
+    private void swapCells(final VexWidget widget,
+                           final List<Object> sourceCells,
+                           final List<Object> targetCells) {
+
+        // Iterate the deletions in reverse, so that we don't mess up offsets
+        // that are in anonymous cells, which are not stored as positions.
+        for (int i = sourceCells.size() - 1; i >= 0; i--) {
+
+            // Also, to preserve the current caret position, we don't cut and
+            // paste the current column. Instead, we cut the target column and
+            // paste it to the source column.
+            Object source = sourceCells.get(i);
+            Object target = targetCells.get(i);
+            final IntRange sourceRange = VexHandlerUtil.getOuterRange(source);
+            final IntRange outerRange = VexHandlerUtil.getOuterRange(target);
+            widget.moveTo(moveRight()
+                          ? outerRange.getStart()
+                          : outerRange.getEnd());
+            widget.savePosition(new Runnable() {
+                public void run() {
+                    widget.moveTo(sourceRange.getStart());
+                    widget.moveTo(sourceRange.getEnd(), true);
+                    widget.cutSelection();
+                }
+            });
+            widget.paste();
+
+        }
+    }
+
+    /**
+     * @param rcInfo row/column info of the current selected element
+     * @return {@code true} if moving is possible (there must be a column in
+     *         moving direction to swap with), otherwise {@code false}
+     */
+    protected abstract boolean movingPossible(VexHandlerUtil.RowColumnInfo rcInfo);
+
+    private boolean leftCell(int currentIndex, int sourceIndex) {
+        return moveRight()
+               ? currentIndex == sourceIndex
+               : currentIndex == sourceIndex - 1;
+    }
+
+    private boolean rightCell(int currentIndex, int sourceIndex) {
+        return moveRight()
+           ? currentIndex == sourceIndex + 1
+           : currentIndex == sourceIndex;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveRowHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveRowHandler.java
new file mode 100644
index 0000000..62f4bca
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractMoveRowHandler.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.SelectedRows;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Moves the current table row either down below its next sibling or up above
+ * its previous sibling.
+ *
+ * @see MoveRowUpHandler
+ * @see MoveRowDownHandler
+ */
+public abstract class AbstractMoveRowHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        final VexHandlerUtil.SelectedRows selected =
+            VexHandlerUtil.getSelectedTableRows(widget);
+
+        if (selected.getRows() == null || targetRow(selected) == null) return;
+
+        widget.doWork(true, new Runnable() {
+            public void run() {
+                IntRange range =
+                    VexHandlerUtil.getOuterRange(targetRow(selected));
+                widget.moveTo(range.getStart());
+                widget.moveTo(range.getEnd(), true);
+                widget.cutSelection();
+
+                widget.moveTo(target(selected));
+                widget.paste();
+            }
+
+        });
+    }
+
+    /**
+     * @param selected current selected row
+     * @return the row with which to switch current row
+     */
+    protected abstract Object targetRow(SelectedRows selected);
+
+    /**
+     * @param selected current selected row
+     * @return offset where to move to
+     */
+    protected abstract int target(SelectedRows selected);
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java
new file mode 100644
index 0000000..7225bff
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
+import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Navigates either to the next or previous table cell (usual shortcut: {@code
+ * Tab} or {@code Shift+Tab}).
+ *
+ * @see PreviousTableCellHandler
+ */
+public abstract class AbstractNavigateTableCellHandler extends
+        AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(VexWidget widget) throws ExecutionException {
+        IBoxFilter filter = new IBoxFilter() {
+            public boolean matches(Box box) {
+                return box instanceof TableRowBox;
+            }
+        };
+        TableRowBox row = (TableRowBox) widget.findInnermostBox(filter);
+
+        // not in a table row?
+        if (row == null) return;
+
+        int offset = widget.getCaretOffset();
+        navigate(widget, row, offset);
+    }
+
+    /**
+     * Navigates either to the next or previous table cell.
+     *
+     * @param widget the Vex widget containing the document
+     * @param row the current row
+     * @param offset the current offset
+     */
+    protected abstract void navigate(VexWidget widget,
+                                     TableRowBox row,
+                                     int offset);
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractRemoveTableCellsHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractRemoveTableCellsHandler.java
new file mode 100644
index 0000000..4516fa4
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractRemoveTableCellsHandler.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Deletes a given list of table cells (see
+ * {@link #collectCellsToDelete(VexWidget, org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.RowColumnInfo)}
+ * ).
+ *
+ * @see RemoveColumnHandler
+ * @see RemoveRowHandler
+ */
+public abstract class AbstractRemoveTableCellsHandler extends
+        AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        widget.doWork(new Runnable() {
+            public void run() {
+
+                final VexHandlerUtil.RowColumnInfo rcInfo =
+                    VexHandlerUtil.getRowColumnInfo(widget);
+
+                if (rcInfo == null) return;
+
+                deleteCells(widget, collectCellsToDelete(widget, rcInfo));
+            }
+
+
+        });
+    }
+
+    /**
+     * @param widget the Vex widget
+     * @param rcInfo row/column info of the current table cell
+     * @return list of elements to delete
+     */
+    protected abstract List<Object> collectCellsToDelete(VexWidget widget,
+                                                         VexHandlerUtil.RowColumnInfo rcInfo);
+
+    private void deleteCells(final VexWidget widget,
+                             final List<Object> cellsToDelete) {
+        // Iterate the deletions in reverse, so that we don't mess up offsets
+        // that are in anonymous cells, which are not stored as Positions.
+        for (int i = cellsToDelete.size() - 1; i >= 0; i--) {
+            Object cell = cellsToDelete.get(i);
+            IntRange range = VexHandlerUtil.getOuterRange(cell);
+            widget.moveTo(range.getStart());
+            widget.moveTo(range.getEnd(), true);
+            widget.deleteSelection();
+        }
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractVexWidgetHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractVexWidgetHandler.java
new file mode 100644
index 0000000..61b0468
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AbstractVexWidgetHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.text.MessageFormat;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.menus.UIElement;
+import org.eclipse.ui.services.IServiceScopes;
+import org.eclipse.wst.xml.vex.ui.internal.editor.Messages;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Abstract supper class of all command handlers which can be performed on a
+ * {@link VexWidget}.
+ *
+ * @see IVexWidgetHandler
+ */
+public abstract class AbstractVexWidgetHandler extends AbstractHandler
+        implements IVexWidgetHandler {
+
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        execute(VexHandlerUtil.computeWidget(event));
+        return null;
+    }
+
+    public abstract void execute(VexWidget widget) throws ExecutionException;
+
+    /**
+     * Helper method to implement
+     * {@link org.eclipse.ui.commands.IElementUpdater}: Updates the name of the
+     * UI element with the specified message where <code>{0}</code> is replaced
+     * with the name of the current element.
+     *
+     * @param element the UI element to be update
+     * @param parameters parameters containing the workbench window of the UI
+     *                   element
+     * @param dynamicLabelId the ID of the message where <code>{0}</code> is
+     *                       replaced with the name of the current element
+     */
+    public void updateElement(UIElement element,
+                              Map parameters,
+                              String windowScopeDynamicLabelId,
+                              String partsiteScopeDynamicLabelId) {
+        Object windowObject = parameters.get(IServiceScopes.WINDOW_SCOPE);
+        if (!(windowObject instanceof IWorkbenchWindow)) return;
+
+        IWorkbenchWindow window = (IWorkbenchWindow) windowObject;
+        VexWidget widget = VexHandlerUtil.computeWidget(window);
+        if (widget == null) return;
+
+        String name = widget.getCurrentElement().getName();
+        String dynamicLabelId =
+            parameters.containsKey(IServiceScopes.PARTSITE_SCOPE)
+            ? partsiteScopeDynamicLabelId
+            : windowScopeDynamicLabelId;
+        String message = Messages.getString(dynamicLabelId);
+        element.setText(MessageFormat.format(message, name));
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnLeftHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnLeftHandler.java
new file mode 100644
index 0000000..34e524e
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnLeftHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Inserts a single table column before (left of) the current one.
+ *
+ * @see AbstractAddColumnHandler
+ * @see AddColumnRightHandler
+ */
+public class AddColumnLeftHandler extends AbstractAddColumnHandler {
+
+    @Override
+    protected boolean addBefore() {
+        return true;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnRightHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnRightHandler.java
new file mode 100644
index 0000000..14983d9
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddColumnRightHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Inserts a single table column after (right of) the current one.
+ *
+ * @see AddColumnLeftHandler
+ * @see AbstractAddColumnHandler
+ */
+public class AddColumnRightHandler  extends AbstractAddColumnHandler {
+
+    @Override
+    protected boolean addBefore() {
+        return false;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddElementHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddElementHandler.java
new file mode 100644
index 0000000..0ce5c24
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddElementHandler.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.ui.internal.contentassist.InsertAssistant;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Shows the content assist to add a new element ({@link InsertAssistant}).
+ */
+public class AddElementHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(VexWidget widget) throws ExecutionException {
+        new InsertAssistant().show(widget);
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowAboveHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowAboveHandler.java
new file mode 100644
index 0000000..904f424
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowAboveHandler.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Inserts one or more table rows above the currently selected one(s). If more
+ * than one row is selected the same number of new rows will be created.
+ *
+ * @see AbstractAddRowHandler
+ * @see AddRowBelowHandler
+ */
+public class AddRowAboveHandler extends AbstractAddRowHandler {
+
+    @Override
+    protected boolean addAbove() {
+        return true;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowBelowHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowBelowHandler.java
new file mode 100644
index 0000000..d0f672b
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/AddRowBelowHandler.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Inserts one or more table rows below the currently selected one(s). If more
+ * than one row is selected the same number of new rows will be created.
+ *
+ * @see AbstractAddRowHandler
+ * @see AddRowAboveHandler
+ */
+public class AddRowBelowHandler extends AbstractAddRowHandler {
+
+    @Override
+    protected boolean addAbove() {
+        return false;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ConvertElementHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ConvertElementHandler.java
new file mode 100644
index 0000000..1d04106
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ConvertElementHandler.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.menus.UIElement;
+import org.eclipse.wst.xml.vex.ui.internal.contentassist.MorphAssistant;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Shows the content assist to convert current element ({@link MorphAssistant}).
+ */
+public class ConvertElementHandler extends AbstractVexWidgetHandler implements IElementUpdater {
+
+    /** ID of the corresponding convert element command. */
+    public static final String COMMAND_ID =
+        "org.eclipse.wst.xml.vex.ui.ConvertElementCommand"; //$NON-NLS-1$
+
+    private static final String LABEL_ID =
+        "command.convertElement.dynamicName"; //$NON-NLS-1$
+
+    @Override
+    public void execute(VexWidget widget) throws ExecutionException {
+        new MorphAssistant().show(widget);
+    }
+
+    public void updateElement(UIElement element, Map parameters) {
+        updateElement(element, parameters, LABEL_ID, LABEL_ID);
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/DuplicateSelectionHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/DuplicateSelectionHandler.java
new file mode 100644
index 0000000..22b942f
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/DuplicateSelectionHandler.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Duplicates current element or current selection.
+ */
+public class DuplicateSelectionHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        widget.doWork(new Runnable() {
+            public void run() {
+                if (!widget.hasSelection()) {
+                    VEXElement element = widget.getCurrentElement();
+
+                    // Can't duplicate the root element
+                    if (element.getParent() == null) return;
+
+                    widget.moveTo(element.getStartOffset());
+                    widget.moveTo(element.getEndOffset() + 1, true);
+                }
+
+                widget.copySelection();
+                int startOffset = widget.getSelectionEnd();
+                widget.moveTo(startOffset);
+                widget.paste();
+                int endOffset = widget.getCaretOffset();
+                widget.moveTo(startOffset);
+                widget.moveTo(endOffset, true);
+            }
+        });
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ITableCellCallback.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ITableCellCallback.java
new file mode 100644
index 0000000..31db646
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/ITableCellCallback.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Callback interface to iterate over table cells (visitor pattern).
+ *
+ * @see TableCellCallbackAdapter
+ */
+public interface ITableCellCallback {
+
+    /**
+     * Called before the first cell in a row is visited.
+     *
+     * @param row element or IntRange representing the row
+     * @param rowIndex zero-based index of the row
+     */
+    public void startRow(Object row, int rowIndex);
+
+    /**
+     * Called when a cell is visited.
+     *
+     * @param row element or IntRange representing the row
+     * @param cell element or IntRange representing the cell
+     * @param rowIndex zero-based index of the current row
+     * @param cellIndex zero-based index of the current cell
+     */
+    public void onCell(Object row, Object cell, int rowIndex, int cellIndex);
+
+    /**
+     * Called after the last cell in a row is visited.
+     *
+     * @param row element or IntRange representing the row
+     * @param rowIndex zero-based index of the row
+     */
+    public void endRow(Object row, int rowIndex);
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/IVexWidgetHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/IVexWidgetHandler.java
new file mode 100644
index 0000000..a8f728b
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/IVexWidgetHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Interface implemented by handler objects that can act on a {@link VexWidget}.
+ */
+public interface IVexWidgetHandler {
+
+    /**
+     * Executes handler at the specified {@link VexWidget}.
+     *
+     * @param event the {@link VexWidget} at which to execute handler
+     * @throws ExecutionException if an exception occurred during execution
+     */
+    void execute(VexWidget widget) throws ExecutionException;
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnLeftHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnLeftHandler.java
new file mode 100644
index 0000000..12b93a0
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnLeftHandler.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * Moves the current table column to the left.
+ *
+ * @see AbstractMoveColumnHandler
+ * @see MoveColumnRightHandler
+ */
+public class MoveColumnLeftHandler extends AbstractMoveColumnHandler {
+
+    @Override
+    protected boolean moveRight() {
+        return false;
+    }
+
+    @Override
+    protected boolean movingPossible(VexHandlerUtil.RowColumnInfo rcInfo) {
+        return rcInfo.cellIndex >= 1;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnRightHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnRightHandler.java
new file mode 100644
index 0000000..3594b26
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveColumnRightHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.RowColumnInfo;
+
+/**
+ * Moves the current table column to the right.
+ *
+ * @see AbstractMoveColumnHandler
+ * @see MoveColumnLeftHandler
+ */
+public class MoveColumnRightHandler extends AbstractMoveColumnHandler {
+
+    @Override
+    protected boolean moveRight() {
+        return true;
+    }
+
+    @Override
+    protected boolean movingPossible(RowColumnInfo rcInfo) {
+        return rcInfo.cellIndex < rcInfo.maxColumnCount - 1;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowDownHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowDownHandler.java
new file mode 100644
index 0000000..d3ab76c
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowDownHandler.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.SelectedRows;
+
+/**
+ * Moves the current table row down below its next sibling.
+ *
+ * @see AbstractMoveRowHandler
+ * @see MoveRowUpHandler
+ */
+public class MoveRowDownHandler extends AbstractMoveRowHandler {
+
+    @Override
+    protected Object targetRow(SelectedRows selected) {
+        return selected.getRowAfter();
+    }
+
+    @Override
+    protected int target(SelectedRows selected) {
+        Object firstRow = selected.getRows().get(0);
+        return VexHandlerUtil.getOuterRange(firstRow).getStart();
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowUpHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowUpHandler.java
new file mode 100644
index 0000000..cb25083
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveRowUpHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.vex.ui.internal.handlers.VexHandlerUtil.SelectedRows;
+
+/**
+ * Moves the current table row up above its previous sibling.
+ *
+ * @see AbstractMoveRowHandler
+ * @see MoveRowDownHandler
+ */
+public class MoveRowUpHandler extends AbstractMoveRowHandler {
+
+    @Override
+    protected Object targetRow(SelectedRows selected) {
+        return selected.getRowBefore();
+    }
+
+    @Override
+    protected int target(SelectedRows selected) {
+        List rows = selected.getRows();
+        Object lastRow = rows.get(rows.size() - 1);
+        return VexHandlerUtil.getOuterRange(lastRow).getEnd();
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveSelectionUpHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveSelectionUpHandler.java
new file mode 100644
index 0000000..a5d4a75
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/MoveSelectionUpHandler.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.layout.BlockBox;
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Moves the current selection or block element above the previous sibling.
+ *
+ * TODO WORK IN PROGRESS.
+ */
+public class MoveSelectionUpHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        // First we determine whether we should expand the selection
+        // to contain an entire block box.
+
+        // Find the lowest block box that completely contains the
+        // selection
+        Box box = widget.findInnermostBox(new IBoxFilter() {
+            public boolean matches(Box box) {
+                return box instanceof BlockBox
+                        && box.getElement() != null
+                        && box.getStartOffset() <= widget
+                                .getSelectionStart()
+                        && box.getEndOffset() >= widget.getSelectionEnd();
+            }
+        });
+
+        Box[] children = box.getChildren();
+        if (children.length > 0 && children[0] instanceof BlockBox) {
+            // The found box contains other block children, so we do NOT have to
+            // expand the selection
+        } else {
+            // Expand selection to the containing box
+
+            // (Note: This "if" is caused by the fact that getStartOffset is
+            // treated differently between elements and boxes. Boxes own their
+            // startOffset, while elements don't own theirs. Perhaps we should
+            // fix this by having box.getStartOffset() return
+            // box.getStartPosition() + 1, but this would be a VERY large
+            // change.)
+            System.out.println("Box is " + box);
+            VEXElement element = box.getElement();
+            if (element != null) {
+                widget.moveTo(element.getEndOffset());
+                widget.moveTo(element.getStartOffset(), true);
+
+            } else {
+                widget.moveTo(box.getEndOffset());
+                widget.moveTo(box.getStartOffset(), true);
+            }
+        }
+
+        // final int previousSiblingStart =
+        // ActionUtils.getPreviousSiblingStart(vexWidget);
+        //
+        // vexWidget.doWork(new IRunnable() {
+        // public void run() throws Exception {
+        // vexWidget.cutSelection();
+        // vexWidget.moveTo(previousSiblingStart);
+        // vexWidget.paste();
+        // vexWidget.moveTo(previousSiblingStart, true);
+        // }
+        // });
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/NextTableCellHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/NextTableCellHandler.java
new file mode 100644
index 0000000..28d9470
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/NextTableCellHandler.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Navigates to the next table cell (usual shortcut: {@code Tab}).
+ *
+ * @see PreviousTableCellHandler
+ */
+public class NextTableCellHandler extends AbstractNavigateTableCellHandler {
+
+    @Override
+    protected void navigate(VexWidget widget, TableRowBox row, int offset) {
+        Box[] cells = row.getChildren();
+
+        // in this row
+        for (int i = 0; i < cells.length; i++) {
+            if (cells[i].getStartOffset() > offset) {
+                widget.moveTo(cells[i].getStartOffset());
+                widget.moveTo(cells[i].getEndOffset(), true);
+                return;
+            }
+        }
+
+        // in other row
+        Box[] rows = row.getParent().getChildren();
+        for (int i = 0; i < rows.length; i++) {
+            if (rows[i].getStartOffset() > offset) {
+                cells = rows[i].getChildren();
+                if (cells.length > 0) {
+                    Box cell = cells[0];
+                    widget.moveTo(cell.getStartOffset());
+                    widget.moveTo(cell.getEndOffset(), true);
+                } else {
+                    System.out.println("TODO - dup row into new empty row");
+                }
+                return;
+            }
+        }
+
+        // We didn't find a "next row", so let's dup the current one
+        VexHandlerUtil.duplicateTableRow(widget, row);
+
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/PreviousTableCellHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/PreviousTableCellHandler.java
new file mode 100644
index 0000000..1cc84f8
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/PreviousTableCellHandler.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Navigates to the previous table cell (usual shortcut: {@code Shift+Tab}).
+ *
+ * @see NextTableCellHandler
+ */
+public class PreviousTableCellHandler extends AbstractNavigateTableCellHandler {
+
+    @Override
+    protected void navigate(VexWidget widget, TableRowBox row, int offset) {
+        Box[] cells = row.getChildren();
+
+        // in this row
+        for (int i = cells.length - 1; i >= 0; i--) {
+            if (cells[i].getEndOffset() < offset) {
+                widget.moveTo(cells[i].getStartOffset());
+                widget.moveTo(cells[i].getEndOffset(), true);
+                return;
+            }
+        }
+
+        // in other row
+        Box[] rows = row.getParent().getChildren();
+        for (int i = rows.length - 1; i >= 0; i--) {
+            if (rows[i].getEndOffset() < offset) {
+                cells = rows[i].getChildren();
+                if (cells.length > 0) {
+                    Box cell = cells[cells.length - 1];
+                    widget.moveTo(cell.getStartOffset());
+                    widget.moveTo(cell.getEndOffset(), true);
+                }
+                return;
+            }
+        }
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveColumnHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveColumnHandler.java
new file mode 100644
index 0000000..6166994
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveColumnHandler.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Deletes current column.
+ */
+public class RemoveColumnHandler extends AbstractRemoveTableCellsHandler {
+
+    protected List<Object> collectCellsToDelete(final VexWidget widget,
+                                                final VexHandlerUtil.RowColumnInfo rcInfo) {
+        final List<Object> cellsToDelete = new ArrayList<Object>();
+        VexHandlerUtil.iterateTableCells(widget, new TableCellCallbackAdapter() {
+            public void onCell(Object row,
+                               Object cell,
+                               int rowIndex,
+                               int cellIndex) {
+                if (cellIndex == rcInfo.cellIndex) {
+                    cellsToDelete.add(cell);
+                }
+            }
+        });
+        return cellsToDelete;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveRowHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveRowHandler.java
new file mode 100644
index 0000000..8f2e837
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveRowHandler.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Deletes selected row(s).
+ */
+public class RemoveRowHandler extends AbstractRemoveTableCellsHandler {
+
+    protected List<Object> collectCellsToDelete(VexWidget widget,
+                                                VexHandlerUtil.RowColumnInfo rcInfo) {
+        return VexHandlerUtil.getSelectedTableRows(widget).getRows();
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveTagHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveTagHandler.java
new file mode 100644
index 0000000..d6c5ca2
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/RemoveTagHandler.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.menus.UIElement;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocumentFragment;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Removes the current tag: deletes the element but adds its content to the
+ * parent element.
+ */
+public class RemoveTagHandler extends AbstractVexWidgetHandler implements
+        IElementUpdater {
+
+    /** ID of the corresponding remove element command. */
+    public static final String COMMAND_ID =
+        "org.eclipse.wst.xml.vex.ui.RemoveTagCommand"; //$NON-NLS-1$
+
+    /**
+     * The message ID of the command label which is in window scope displayed
+     * in the 'Remove' menu only.
+     */
+    private static final String WINDOW_SCOPE_DYNAMIC_LABEL_ID =
+        "command.removeTag.inRemoveMenu.dynamicName"; //$NON-NLS-1$
+
+    /**
+     * The message ID of the command label which is in partsite scope displayed
+     * in the context menu.
+     */
+    private static final String PARTSITE_SCOPE_DYNAMIC_LABEL_ID =
+        "command.removeTag.dynamicName"; //$NON-NLS-1$
+
+    @Override
+    public void execute(final VexWidget widget) throws ExecutionException {
+        widget.doWork(new Runnable() {
+            public void run() {
+                VEXElement element = widget.getDocument().getElementAt(
+                        widget.getCaretOffset());
+                widget.moveTo(element.getStartOffset() + 1, false);
+                widget.moveTo(element.getEndOffset(), true);
+                VEXDocumentFragment frag = widget.getSelectedFragment();
+                widget.deleteSelection();
+                widget.moveBy(-1, false);
+                widget.moveBy(2, true);
+                widget.deleteSelection();
+                widget.insertFragment(frag);
+            }
+        });
+    }
+
+    public void updateElement(UIElement element, Map parameters) {
+        updateElement(element,
+                      parameters,
+                      WINDOW_SCOPE_DYNAMIC_LABEL_ID,
+                      PARTSITE_SCOPE_DYNAMIC_LABEL_ID);
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitBlockElementHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitBlockElementHandler.java
new file mode 100644
index 0000000..ad2b5c4
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitBlockElementHandler.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.VEXCorePlugin;
+import org.eclipse.wst.xml.vex.core.internal.css.CSS;
+import org.eclipse.wst.xml.vex.core.internal.css.Styles;
+import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocumentFragment;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Splits the current block element, for instance to create new block/paragraph
+ * or table cell (usually by hitting the {@code Return} key).
+ *
+ * @see SplitItemHandler
+ */
+public class SplitBlockElementHandler extends AbstractVexWidgetHandler {
+
+    @Override
+    public void execute(VexWidget widget) throws ExecutionException {
+        VEXElement element = widget.getCurrentElement();
+        Styles styles = widget.getStyleSheet().getStyles(element);
+        while (!styles.isBlock()) {
+            element = element.getParent();
+            styles = widget.getStyleSheet().getStyles(element);
+        }
+        splitElement(widget, element);
+    }
+
+    /**
+     * Splits the given element.
+     *
+     * @param vexWidget IVexWidget containing the document.
+     * @param element Element to be split.
+     */
+    protected void splitElement(final IVexWidget vexWidget,
+                                    final VEXElement element) {
+
+        vexWidget.doWork(new Runnable() {
+            public void run() {
+
+                long start = 0;
+                if (VEXCorePlugin.getInstance().isDebugging()) {
+                    start = System.currentTimeMillis();
+                }
+
+                Styles styles = vexWidget.getStyleSheet().getStyles(element);
+
+                if (styles.getWhiteSpace().equals(CSS.PRE)) {
+                    // can't call vexWidget.insertText() or we'll get an
+                    // infinite loop
+                    VEXDocument doc = vexWidget.getDocument();
+                    int offset = vexWidget.getCaretOffset();
+                    doc.insertText(offset, "\n");
+                    vexWidget.moveTo(offset + 1);
+                } else {
+
+                    // There may be a number of child elements below the given
+                    // element. We cut out the tails of each of these elements
+                    // and put them in a list of fragments to be reconstructed
+                    // when
+                    // we clone the element.
+                    List children = new ArrayList();
+                    List frags = new ArrayList();
+                    VEXElement child = vexWidget.getCurrentElement();
+                    while (true) {
+                        children.add(child);
+                        vexWidget.moveTo(child.getEndOffset(), true);
+                        frags.add(vexWidget.getSelectedFragment());
+                        vexWidget.deleteSelection();
+                        vexWidget.moveTo(child.getEndOffset() + 1);
+                        if (child == element) {
+                            break;
+                        }
+                        child = child.getParent();
+                    }
+
+                    for (int i = children.size() - 1; i >= 0; i--) {
+                        child = (Element) children.get(i);
+                        VEXDocumentFragment frag = (VEXDocumentFragment) frags.get(i);
+                        vexWidget.insertElement((Element) child.clone());
+                        int offset = vexWidget.getCaretOffset();
+                        if (frag != null) {
+                            vexWidget.insertFragment(frag);
+                        }
+                        vexWidget.moveTo(offset);
+                    }
+                }
+
+                if (VEXCorePlugin.getInstance().isDebugging()) {
+                    long end = System.currentTimeMillis();
+                    System.out.println("split() took " + (end - start) + "ms");
+                }
+            }
+        });
+    }
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitItemHandler.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitItemHandler.java
new file mode 100644
index 0000000..92cd0fc
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/SplitItemHandler.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.wst.xml.vex.core.internal.css.CSS;
+import org.eclipse.wst.xml.vex.core.internal.css.StyleSheet;
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Splits the nearest enclosing table row or list item (usually by hitting
+ * {@code Shift+Return}). If a table row is being split, empty versions of the
+ * current row's cells are created.
+ *
+ * @see SplitBlockElementHandler
+ */
+public class SplitItemHandler extends SplitBlockElementHandler {
+
+    @Override
+    public void execute(VexWidget widget) throws ExecutionException {
+        final StyleSheet ss = widget.getStyleSheet();
+
+        // Item is either a TableRowBox or a BlockElementBox representing
+        // a list item
+        Box item = widget.findInnermostBox(new IBoxFilter() {
+            public boolean matches(Box box) {
+                if (box instanceof TableRowBox) {
+                    return true;
+                } else {
+                    VEXElement element = box.getElement();
+                    return element != null
+                            && ss.getStyles(element).getDisplay().equals(
+                                    CSS.LIST_ITEM);
+                }
+            }
+        });
+
+        if (item instanceof TableRowBox) {
+            new AddRowBelowHandler().execute(widget);
+            // VexHandlerUtil.duplicateTableRow(vexWidget, (TableRowBox) item);
+        } else if (item != null) {
+            splitElement(widget, item.getElement());
+        }
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/StyleMenu.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/StyleMenu.java
new file mode 100644
index 0000000..a6b335c
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/StyleMenu.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.xml.vex.ui.internal.config.Style;
+import org.eclipse.wst.xml.vex.ui.internal.editor.VexEditor;
+
+/**
+ * Menu of all registered styles available for the current document to choose
+ * from.
+ */
+public class StyleMenu extends ContributionItem {
+
+    @Override
+    public void fill(Menu menu, int index) {
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+        final VexEditor editor = VexHandlerUtil.computeVexEditor(window);
+        if (editor == null) return;
+
+        String publicId= editor.getVexWidget().getDocument().getPublicID();
+        Style[] styles = Style.getStylesForDoctype(publicId);
+        for (final Style style : styles) {
+            MenuItem menuItem = new MenuItem(menu, SWT.RADIO, index);
+            menuItem.setText(style.getName());
+            menuItem.setSelection(style == editor.getStyle());
+            menuItem.addSelectionListener(new SelectionAdapter() {
+                public void widgetSelected(SelectionEvent e) {
+                    editor.setStyle(style);
+                }
+            });
+        }
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/TableCellCallbackAdapter.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/TableCellCallbackAdapter.java
new file mode 100644
index 0000000..89ff9f8
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/TableCellCallbackAdapter.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Holger Voormann 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:
+ *     Holger Voormann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+/**
+ * This adapter class provides empty default implementations for the methods
+ * of {@link ITableCellCallback}. Callback implementations can extend this class
+ * and override only the methods which they are interested in.
+ */
+public abstract class TableCellCallbackAdapter implements ITableCellCallback {
+
+    public void endRow(Object row, int rowIndex) {
+        // NOP (adapter pattern)
+    }
+
+    public void onCell(Object row, Object cell, int rowIndex, int cellIndex) {
+        // NOP (adapter pattern)
+    }
+
+    public void startRow(Object row, int rowIndex) {
+        // NOP (adapter pattern)
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/VexHandlerUtil.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/VexHandlerUtil.java
new file mode 100644
index 0000000..e6e11ac
--- /dev/null
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/handlers/VexHandlerUtil.java
@@ -0,0 +1,609 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 John Krasnay 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:
+ *     John Krasnay - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.vex.ui.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.wst.xml.vex.core.internal.core.IntRange;
+import org.eclipse.wst.xml.vex.core.internal.css.CSS;
+import org.eclipse.wst.xml.vex.core.internal.css.StyleSheet;
+import org.eclipse.wst.xml.vex.core.internal.dom.Element;
+import org.eclipse.wst.xml.vex.core.internal.layout.BlockBox;
+import org.eclipse.wst.xml.vex.core.internal.layout.Box;
+import org.eclipse.wst.xml.vex.core.internal.layout.ElementOrRangeCallback;
+import org.eclipse.wst.xml.vex.core.internal.layout.LayoutUtils;
+import org.eclipse.wst.xml.vex.core.internal.layout.TableRowBox;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXDocument;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXElement;
+import org.eclipse.wst.xml.vex.core.internal.provisional.dom.I.VEXNode;
+import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
+import org.eclipse.wst.xml.vex.ui.internal.editor.VEXMultiPageEditorPart;
+import org.eclipse.wst.xml.vex.ui.internal.editor.VexEditor;
+import org.eclipse.wst.xml.vex.ui.internal.editor.VexEditorMultiPage;
+import org.eclipse.wst.xml.vex.ui.internal.swt.VexWidget;
+
+/**
+ * Static helper methods used across handlers.
+ */
+public final class VexHandlerUtil {
+
+    public static VexWidget computeWidget(ExecutionEvent event)
+            throws ExecutionException {
+
+        IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
+        assertNotNull(activeEditor);
+
+        VexWidget widget = null;
+        if (activeEditor instanceof VexEditor) {
+            widget = ((VexEditor) activeEditor).getVexWidget();
+        } else if (activeEditor instanceof VEXMultiPageEditorPart) {
+            VEXMultiPageEditorPart part = (VEXMultiPageEditorPart) activeEditor;
+            VexEditorMultiPage editor = part.getVexEditor();
+            assertNotNull(editor);
+            widget = editor.getVexWidget();
+        }
+        assertNotNull(widget);
+        return widget;
+    }
+
+    public static VexWidget computeWidget(IWorkbenchWindow window) {
+        VexEditor editor = computeVexEditor(window);
+        if (editor == null) return null;
+        return editor.getVexWidget();
+    }
+
+    public static VexEditor computeVexEditor(IWorkbenchWindow window) {
+        IEditorPart activeEditor = window.getActivePage().getActiveEditor();
+        if (activeEditor == null) return null;
+
+        if (activeEditor instanceof VexEditor) {
+            return (VexEditor) activeEditor;
+        } else if (activeEditor instanceof VEXMultiPageEditorPart) {
+            VEXMultiPageEditorPart part = (VEXMultiPageEditorPart) activeEditor;
+            return part.getVexEditor();
+        }
+        return null;
+    }
+
+    private static void assertNotNull(Object object) throws ExecutionException {
+        if (object == null) {
+            throw new ExecutionException("Can not compute VexWidget.");
+        }
+    }
+
+    public static class RowColumnInfo {
+        public Object row;
+        public Object cell;
+        public int rowIndex;
+        public int cellIndex;
+        public int rowCount;
+        public int columnCount;
+        public int maxColumnCount;
+    }
+
+    /**
+     * Clone the table cells from the given TableRowBox to the current offset in
+     * vexWidget.
+     *
+     * @param vexWidget
+     *            IVexWidget to modify.
+     * @param tr
+     *            TableRowBox whose cells are to be cloned.
+     * @param moveToFirstCell
+     *            TODO
+     */
+    public static void cloneTableCells(final IVexWidget vexWidget,
+            final TableRowBox tr, final boolean moveToFirstCell) {
+        vexWidget.doWork(new Runnable() {
+            public void run() {
+
+                int offset = vexWidget.getCaretOffset();
+
+                boolean firstCellIsAnonymous = false;
+                Box[] cells = tr.getChildren();
+                for (int i = 0; i < cells.length; i++) {
+                    if (cells[i].isAnonymous()) {
+                        vexWidget.insertText(" ");
+                        if (i == 0) {
+                            firstCellIsAnonymous = true;
+                        }
+                    } else {
+                        vexWidget.insertElement((Element) cells[i].getElement()
+                                .clone());
+                        vexWidget.moveBy(+1);
+                    }
+                }
+
+                if (moveToFirstCell) {
+                    vexWidget.moveTo(offset + 1);
+                    if (firstCellIsAnonymous) {
+                        vexWidget.moveBy(-1, true);
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Duplicate the given table row, inserting a new empty one below it. The
+     * new row contains empty children corresponding to the given row's
+     * children.
+     *
+     * @param vexWidget
+     *            IVexWidget with which we're working
+     * @param tr
+     *            TableRowBox to be duplicated.
+     */
+    public static void duplicateTableRow(final IVexWidget vexWidget,
+            final TableRowBox tr) {
+        vexWidget.doWork(new Runnable() {
+            public void run() {
+
+                vexWidget.moveTo(tr.getEndOffset());
+
+                if (!tr.isAnonymous()) {
+                    vexWidget.moveBy(+1); // Move past sentinel in current row
+                    vexWidget.insertElement((Element) tr.getElement().clone());
+                }
+
+                cloneTableCells(vexWidget, tr, true);
+            }
+        });
+    }
+
+    /**
+     * Returns true if the given element or range is at least partially
+     * selected.
+     *
+     * @param vexWidget
+     *            IVexWidget being tested.
+     * @param elementOrRange
+     *            Element or IntRange being tested.
+     */
+    public static boolean elementOrRangeIsPartiallySelected(
+            IVexWidget vexWidget, Object elementOrRange) {
+        IntRange range = getInnerRange(elementOrRange);
+        return range.getEnd() >= vexWidget.getSelectionStart()
+                && range.getStart() <= vexWidget.getSelectionEnd();
+    }
+
+    /**
+     * Returns the zero-based index of the table column containing the current
+     * offset. Returns -1 if we are not inside a table.
+     */
+    public static int getCurrentColumnIndex(IVexWidget vexWidget) {
+
+        VEXElement row = getCurrentTableRow(vexWidget);
+
+        if (row == null) {
+            return -1;
+        }
+
+        final int offset = vexWidget.getCaretOffset();
+        final int[] column = new int[] { -1 };
+        LayoutUtils.iterateTableCells(vexWidget.getStyleSheet(), row,
+                new ElementOrRangeCallback() {
+                    private int i = 0;
+
+                    public void onElement(Element child, String displayStyle) {
+                        if (offset > child.getStartOffset()
+                                && offset <= child.getEndOffset()) {
+                            column[0] = i;
+                        }
+                        i++;
+                    }
+
+                    public void onRange(VEXElement parent, int startOffset,
+                            int endOffset) {
+                        i++;
+                    }
+                });
+
+        return column[0];
+    }
+
+    /**
+     * Returns the innermost Element with style table-row containing the caret,
+     * or null if no such element exists.
+     *
+     * @param vexWidget
+     *            IVexWidget to use.
+     */
+    public static VEXElement getCurrentTableRow(IVexWidget vexWidget) {
+
+        StyleSheet ss = vexWidget.getStyleSheet();
+        VEXElement element = vexWidget.getCurrentElement();
+
+        while (element != null) {
+            if (ss.getStyles(element).getDisplay().equals(CSS.TABLE_ROW)) {
+                return element;
+            }
+            element = element.getParent();
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the start offset of the next sibling of the parent element.
+     * Returns -1 if there is no previous sibling in the parent.
+     *
+     * @param vexWidget
+     *            VexWidget to use.
+     */
+    public static int getPreviousSiblingStart(IVexWidget vexWidget) {
+        int startOffset;
+
+        if (vexWidget.hasSelection()) {
+            startOffset = vexWidget.getSelectionStart();
+        } else {
+            Box box = vexWidget.findInnermostBox(new IBoxFilter() {
+                public boolean matches(Box box) {
+                    return box instanceof BlockBox && box.getElement() != null;
+                }
+            });
+
+            if (box.getElement() == vexWidget.getDocument().getRootElement()) {
+                return -1;
+            }
+
+            startOffset = box.getElement().getStartOffset();
+        }
+
+        int previousSiblingStart = -1;
+        VEXElement parent = vexWidget.getDocument().getElementAt(startOffset);
+        List<VEXNode> children = parent.getChildNodes();
+        for (int i = 0; i < children.size(); i++) {
+            VEXNode child = children.get(i);
+            if (startOffset == child.getStartOffset()) {
+                break;
+            }
+            previousSiblingStart = child.getStartOffset();
+        }
+        return previousSiblingStart;
+    }
+
+    /**
+     * Returns an array of the selected block boxes. Text nodes between boxes
+     * are not returned. If the selection does not enclose any block boxes,
+     * returns an empty array.
+     *
+     * @param vexWidget
+     *            VexWidget to use.
+     */
+    public static BlockBox[] getSelectedBlockBoxes(final IVexWidget vexWidget) {
+
+        if (!vexWidget.hasSelection()) {
+            return new BlockBox[0];
+        }
+
+        Box parent = vexWidget.findInnermostBox(new IBoxFilter() {
+            public boolean matches(Box box) {
+                System.out.println("Matching " + box);
+                return box instanceof BlockBox
+                        && box.getStartOffset() <= vexWidget
+                                .getSelectionStart()
+                        && box.getEndOffset() >= vexWidget.getSelectionEnd();
+            }
+        });
+
+        System.out.println("Matched " + parent);
+
+        List blockList = new ArrayList();
+
+        Box[] children = parent.getChildren();
+        System.out.println("Parent has " + children.length + " children");
+        for (int i = 0; i < children.length; i++) {
+            Box child = children[i];
+            if (child instanceof BlockBox
+                    && child.getStartOffset() >= vexWidget.getSelectionStart()
+                    && child.getEndOffset() <= vexWidget.getSelectionEnd()) {
+                System.out.println("  adding " + child);
+                blockList.add(child);
+            } else {
+                System.out.println("  skipping " + child);
+            }
+
+        }
+
+        return (BlockBox[]) blockList.toArray(new BlockBox[blockList.size()]);
+    }
+
+    /**
+     * Returns the currently selected table rows, or the current row if ther is
+     * no selection. If no row can be found, returns an empty array.
+     *
+     * @param vexWidget
+     *            IVexWidget to use.
+     */
+    public static SelectedRows getSelectedTableRows(final IVexWidget vexWidget) {
+        final SelectedRows selected = new SelectedRows();
+
+        VexHandlerUtil.iterateTableCells(vexWidget,
+                                         new TableCellCallbackAdapter() {
+            public void startRow(Object row, int rowIndex) {
+                if (VexHandlerUtil.elementOrRangeIsPartiallySelected(vexWidget,
+                        row)) {
+                    if (selected.rows == null) {
+                        selected.rows = new ArrayList();
+                    }
+                    selected.rows.add(row);
+                } else {
+                    if (selected.rows == null) {
+                        selected.rowBefore = row;
+                    } else {
+                        if (selected.rowAfter == null) {
+                            selected.rowAfter = row;
+                        }
+                    }
+                }
+            }
+        });
+
+        return selected;
+    }
+
+    public static void iterateTableCells(IVexWidget vexWidget,
+            final ITableCellCallback callback) {
+
+        final StyleSheet ss = vexWidget.getStyleSheet();
+
+        iterateTableRows(vexWidget, new ElementOrRangeCallback() {
+
+            final private int[] rowIndex = { 0 };
+
+            public void onElement(final Element row, String displayStyle) {
+
+                callback.startRow(row, rowIndex[0]);
+
+                LayoutUtils.iterateTableCells(ss, row,
+                        new ElementOrRangeCallback() {
+                            private int cellIndex = 0;
+
+                            public void onElement(Element cell,
+                                    String displayStyle) {
+                                callback.onCell(row, cell, rowIndex[0],
+                                        cellIndex);
+                                cellIndex++;
+                            }
+
+                            public void onRange(VEXElement parent,
+                                    int startOffset, int endOffset) {
+                                callback.onCell(row, new IntRange(startOffset,
+                                        endOffset), rowIndex[0], cellIndex);
+                                cellIndex++;
+                            }
+                        });
+
+                callback.endRow(row, rowIndex[0]);
+
+                rowIndex[0]++;
+            }
+
+            public void onRange(VEXElement parent, final int startOffset,
+                    final int endOffset) {
+
+                final IntRange row = new IntRange(startOffset, endOffset);
+                callback.startRow(row, rowIndex[0]);
+
+                LayoutUtils.iterateTableCells(ss, parent, startOffset,
+                        endOffset, new ElementOrRangeCallback() {
+                            private int cellIndex = 0;
+
+                            public void onElement(Element cell,
+                                    String displayStyle) {
+                                callback.onCell(row, cell, rowIndex[0],
+                                        cellIndex);
+                                cellIndex++;
+                            }
+
+                            public void onRange(VEXElement parent,
+                                    int startOffset, int endOffset) {
+                                callback.onCell(row, new IntRange(startOffset,
+                                        endOffset), rowIndex[0], cellIndex);
+                                cellIndex++;
+                            }
+                        });
+
+                callback.endRow(row, rowIndex[0]);
+
+                rowIndex[0]++;
+            }
+        });
+    }
+
+    /**
+     * Returns a RowColumnInfo structure containing information about the table
+     * containing the caret. Returns null if the caret is not currently inside a
+     * table.
+     *
+     * @param vexWidget
+     *            IVexWidget to inspect.
+     */
+    public static RowColumnInfo getRowColumnInfo(IVexWidget vexWidget) {
+
+        final boolean[] found = new boolean[1];
+        final RowColumnInfo[] rcInfo = new RowColumnInfo[] { new RowColumnInfo() };
+        final int offset = vexWidget.getCaretOffset();
+
+        rcInfo[0].cellIndex = -1;
+        rcInfo[0].rowIndex = -1;
+
+        iterateTableCells(vexWidget, new ITableCellCallback() {
+
+            private int rowColumnCount;
+
+            public void startRow(Object row, int rowIndex) {
+                rowColumnCount = 0;
+            }
+
+            public void onCell(Object row, Object cell, int rowIndex,
+                    int cellIndex) {
+                found[0] = true;
+                if (LayoutUtils.elementOrRangeContains(row, offset)) {
+                    rcInfo[0].row = row;
+                    rcInfo[0].rowIndex = rowIndex;
+                    rcInfo[0].columnCount++;
+
+                    if (LayoutUtils.elementOrRangeContains(cell, offset)) {
+                        rcInfo[0].cell = cell;
+                        rcInfo[0].cellIndex = cellIndex;
+                    }
+                }
+
+                rowColumnCount++;
+            }
+
+            public void endRow(Object row, int rowIndex) {
+                rcInfo[0].rowCount++;
+                rcInfo[0].maxColumnCount = Math.max(rcInfo[0].maxColumnCount,
+                        rowColumnCount);
+            }
+        });
+
+        if (found[0]) {
+            return rcInfo[0];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Iterate over all rows in the table containing the caret.
+     *
+     * @param vexWidget
+     *            IVexWidget to iterate over.
+     * @param callback
+     *            Caller-provided callback that this method calls for each row
+     *            in the current table.
+     */
+    public static void iterateTableRows(IVexWidget vexWidget,
+            ElementOrRangeCallback callback) {
+
+        final StyleSheet ss = vexWidget.getStyleSheet();
+        final VEXDocument doc = vexWidget.getDocument();
+        final int offset = vexWidget.getCaretOffset();
+
+        // This may or may not be a table
+        // In any case, it's the element that contains the top-level table
+        // children
+        VEXElement table = doc.getElementAt(offset);
+
+        while (table != null && !LayoutUtils.isTableChild(ss, table)) {
+            table = table.getParent();
+        }
+
+        while (table != null && LayoutUtils.isTableChild(ss, table)) {
+            table = table.getParent();
+        }
+
+        if (table == null || table.getParent() == null) {
+            return;
+        }
+
+        final List tableChildren = new ArrayList();
+        final boolean[] found = new boolean[] { false };
+        LayoutUtils.iterateChildrenByDisplayStyle(ss,
+                LayoutUtils.TABLE_CHILD_STYLES, table,
+                new ElementOrRangeCallback() {
+                    public void onElement(Element child, String displayStyle) {
+                        if (offset >= child.getStartOffset()
+                                && offset <= child.getEndOffset()) {
+                            found[0] = true;
+                        }
+                        tableChildren.add(child);
+                    }
+
+                    public void onRange(VEXElement parent, int startOffset,
+                            int endOffset) {
+                        if (!found[0]) {
+                            tableChildren.clear();
+                        }
+                    }
+                });
+
+        if (!found[0]) {
+            return;
+        }
+
+        int startOffset = ((Element) tableChildren.get(0)).getStartOffset();
+        int endOffset = ((Element) tableChildren.get(tableChildren.size() - 1))
+                .getEndOffset() + 1;
+        LayoutUtils.iterateTableRows(ss, table, startOffset, endOffset,
+                callback);
+    }
+
+    /**
+     * Returns an IntRange representing the offsets inside the given Element or
+     * IntRange. If an Element is passed, returns the offsets inside the
+     * sentinels. If an IntRange is passed it is returned directly.
+     *
+     * @param elementOrRange
+     *            Element or IntRange to be inspected.
+     */
+    public static IntRange getInnerRange(Object elementOrRange) {
+        if (elementOrRange instanceof Element) {
+            Element element = (Element) elementOrRange;
+            return new IntRange(element.getStartOffset() + 1, element
+                    .getEndOffset());
+        } else {
+            return (IntRange) elementOrRange;
+        }
+    }
+
+    /**
+     * Returns an IntRange representing the offsets outside the given Element or
+     * IntRange. If an Element is passed, returns the offsets outside the
+     * sentinels. If an IntRange is passed it is returned directly.
+     *
+     * @param elementOrRange
+     *            Element or IntRange to be inspected.
+     */
+    public static IntRange getOuterRange(Object elementOrRange) {
+        if (elementOrRange instanceof Element) {
+            Element element = (Element) elementOrRange;
+            return new IntRange(element.getStartOffset(), element
+                    .getEndOffset() + 1);
+        } else {
+            return (IntRange) elementOrRange;
+        }
+    }
+
+    public static class SelectedRows {
+
+        private SelectedRows() {
+        }
+
+        public List<Object> getRows() {
+            return this.rows;
+        }
+
+        public Object getRowBefore() {
+            return this.rowBefore;
+        }
+
+        public Object getRowAfter() {
+            return this.rowAfter;
+        }
+
+        private List<Object> rows;
+        private Object rowBefore;
+        private Object rowAfter;
+    }
+
+}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/outline/DefaultOutlineProvider.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/outline/DefaultOutlineProvider.java
index 6d94094..9473fe3 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/outline/DefaultOutlineProvider.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/outline/DefaultOutlineProvider.java
@@ -58,10 +58,18 @@
 	public VEXElement getOutlineElement(VEXElement child) {
 		VEXElement element = child;
 		while (element != null) {
+			
+			// block element?
 			if (this.whitespacePolicy.isBlock(element)) {
 				return element;
 			}
-			element = element.getParent();
+			
+			// root?
+			VEXElement parent = element.getParent();
+			if (parent == null) {
+				return element;
+			}
+			element = parent;
 		}
 		return element;
 	}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/swt/VexWidget.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/swt/VexWidget.java
index 35439b0..69d0bf7 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/swt/VexWidget.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.ui/src/org/eclipse/wst/xml/vex/ui/internal/swt/VexWidget.java
@@ -21,6 +21,7 @@
 import javax.swing.undo.CannotUndoException;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -36,6 +37,7 @@
 import org.eclipse.swt.events.ControlListener;
 import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyAdapter;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.MouseEvent;
@@ -68,14 +70,11 @@
 import org.eclipse.wst.xml.vex.core.internal.widget.IBoxFilter;
 import org.eclipse.wst.xml.vex.core.internal.widget.IVexWidget;
 import org.eclipse.wst.xml.vex.core.internal.widget.VexWidgetImpl;
-import org.eclipse.wst.xml.vex.ui.internal.action.AbstractVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.DuplicateSelectionAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.IVexAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.NextTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.PreviousTableCellAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.RemoveElementAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitAction;
-import org.eclipse.wst.xml.vex.ui.internal.action.SplitItemAction;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.DuplicateSelectionHandler;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.IVexWidgetHandler;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.RemoveTagHandler;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.SplitBlockElementHandler;
+import org.eclipse.wst.xml.vex.ui.internal.handlers.SplitItemHandler;
 import org.xml.sax.SAXException;
 
 /**
@@ -508,7 +507,10 @@
 	// ------------------------------------------------------ Fields
 
 	private static final char CHAR_NONE = 0;
-	private static Map keyMap;
+	
+	private static Map<KeyStroke, IVexWidgetHandler> keyMap =
+		new HashMap<KeyStroke, IVexWidgetHandler>();
+	static { buildKeyMap(); }
 
 	private VexWidgetImpl impl;
 
@@ -630,37 +632,26 @@
 
 	};
 
-	private static abstract class Action extends AbstractVexAction {
+	private static abstract class Action implements IVexWidgetHandler {
 
-		public void run(IVexWidget vexWidget) {
-			try {
-				this.runEx(vexWidget);
-			} catch (Exception ex) {
-				ex.printStackTrace();
-			}
+		public void execute(VexWidget widget) throws ExecutionException {
+			runEx(widget);
 		}
 
-		public abstract void runEx(IVexWidget w) throws Exception;
+		public abstract void runEx(IVexWidget w) throws ExecutionException;
+
 	}
 
-	private KeyListener keyListener = new KeyListener() {
+	private KeyListener keyListener = new KeyAdapter() {
 
 		public void keyPressed(KeyEvent e) {
-			// System.out.println("Key pressed, keyCode is " + e.keyCode +
-			// ", keyChar is " + ((int) e.character) + ", stateMask is " +
-			// e.stateMask);
 			KeyStroke keyStroke = new KeyStroke(e);
-			Map map = getKeyMap();
-			if (map.containsKey(keyStroke)) {
-				Object action = map.get(keyStroke);
-				if (action instanceof IVexAction) {
-					((IVexAction) action).run(VexWidget.this);
-				} else {
-					try {
-						((Action) map.get(keyStroke)).runEx(VexWidget.this);
-					} catch (Exception ex) {
-						ex.printStackTrace();
-					}
+			IVexWidgetHandler handler = keyMap.get(keyStroke);
+			if (handler != null) {
+				try {
+					handler.execute(VexWidget.this);
+				} catch (Exception ex) {
+					ex.printStackTrace();
 				}
 			} else if (!Character.isISOControl(e.character)) {
 				try {
@@ -672,8 +663,6 @@
 			}
 		}
 
-		public void keyReleased(KeyEvent e) {
-		}
 	};
 
 	private MouseListener mouseListener = new MouseListener() {
@@ -779,12 +768,7 @@
 			Action action) {
 		keyMap.put(new KeyStroke(character, keyCode, stateMask), action);
 	}
-
-	private static void addKey(char character, int keyCode, int stateMask,
-			IVexAction action) {
-		keyMap.put(new KeyStroke(character, keyCode, stateMask), action);
-	}
-
+	
 	private static void buildKeyMap() {
 		addKey(CHAR_NONE, SWT.ARROW_DOWN, SWT.NONE, new Action() {
 			public void runEx(IVexWidget w) {
@@ -853,19 +837,24 @@
 		});
 
 		addKey(SWT.BS, SWT.BS, SWT.NONE, new Action() {
-			public void runEx(IVexWidget w) throws Exception {
-				w.deletePreviousChar();
+			public void runEx(IVexWidget w) throws ExecutionException {
+				try {
+					w.deletePreviousChar();
+				} catch (DocumentValidationException e) {
+					throw new ExecutionException(e.getMessage(), e);
+				}
 			}
 		});
 		addKey(SWT.DEL, SWT.DEL, SWT.NONE, new Action() {
-			public void runEx(IVexWidget w) throws Exception {
-				w.deleteNextChar();
+			public void runEx(IVexWidget w) throws ExecutionException {
+				try {
+					w.deleteNextChar();
+				} catch (DocumentValidationException e) {
+					throw new ExecutionException(e.getMessage(), e);
+				}
 			}
 		});
 
-		addKey(SWT.TAB, SWT.TAB, SWT.NONE, new NextTableCellAction());
-		addKey(SWT.TAB, SWT.TAB, SWT.SHIFT, new PreviousTableCellAction());
-
 		addKey(CHAR_NONE, SWT.END, SWT.NONE, new Action() {
 			public void runEx(IVexWidget w) {
 				w.moveToLineEnd(false);
@@ -940,21 +929,6 @@
 						((VexWidget) w).showMorphElementPopup();
 					}
 				});
-		addKey((char) 23, 0, SWT.CONTROL, new RemoveElementAction());
-		// addKey('\r', '\r', SWT.NONE, new Action() { // Enter key
-		// public void runEx(IVexWidget w) throws Exception { w.split(); } });
-		addKey('\r', '\r', SWT.NONE, new SplitAction());
-		addKey('\r', '\r', SWT.SHIFT, new SplitItemAction());
-
-		addKey((char) 4, 100, SWT.CONTROL, new DuplicateSelectionAction()); // Ctrl-D
-	}
-
-	private static Map getKeyMap() {
-		if (keyMap == null) {
-			keyMap = new HashMap();
-			buildKeyMap();
-		}
-		return keyMap;
 	}
 
 	/**