@Override
 public void buildWidget(JSONObject jsonObj, Widget parent) {
   VkMenuBarHorizontal tree = (VkMenuBarHorizontal) parent;
   addAttributes(jsonObj, parent);
   JSONArray items = jsonObj.get("items").isArray();
   for (int i = 0; i < items.size(); i++) {
     JSONObject item = items.get(i).isObject();
     JSONValue js = item.get("js");
     if (js != null)
       ((VkMenuBarHorizontalEngine)
               VkStateHelper.getInstance()
                   .getWidgetEngineMapping()
                   .getEngineMap()
                   .get(((IVkWidget) tree).getWidgetName()))
           .addMenuItem(
               tree,
               item.get("html").isString().stringValue(),
               item.get("js").isString().stringValue());
     else if (item.containsKey("child")) {
       JSONObject childObj = item.get("child").isObject();
       JSONString widgetName = childObj.get("widgetName").isString();
       Widget widget = VkStateHelper.getInstance().getEngine().getWidget(widgetName.stringValue());
       VkStateHelper.getInstance().getEngine().addWidget(widget, ((IVkPanel) tree));
       VkStateHelper.getInstance()
           .getWidgetEngineMapping()
           .getEngineMap()
           .get(((IVkWidget) widget).getWidgetName())
           .buildWidget(childObj, widget);
       // addAttributes(childObj, widget);
     } else if (item.get("separator") == null) {
       VkMenuBarHorizontal subTree =
           (VkMenuBarHorizontal)
               VkStateHelper.getInstance()
                   .getEngine()
                   .getWidget(VkMenuBarVertical.NAME); // all submenus are vertical
       // addAttributes(item.get("menu").isObject(), subTree);
       tree.addItem(new MenuItem(item.get("html").isString().stringValue(), subTree));
       VkStateHelper.getInstance()
           .getWidgetEngineMapping()
           .getEngineMap()
           .get(((IVkWidget) tree).getWidgetName())
           .buildWidget(item.get("menu").isObject(), subTree);
     } else addSeparator(tree);
   }
 }
 private void addMenuItem(VkMenuBarHorizontal menuBar, String name, final String js) {
   menuBar.addItem(
       new MenuItem(
           name,
           new Command() {
             @Override
             public void execute() {
               VkStateHelper.getInstance()
                   .getEventHelper()
                   .executeEvent(js, (Map<String, String>) null);
             }
           }));
 }
  @Override
  public void applyAttribute(String attributeName, Widget invokingWidget) {
    final VkMenuBarHorizontal menuBar = (VkMenuBarHorizontal) invokingWidget;
    if (attributeName.equals(ADD_SEPERATOR)) addSeparator(menuBar);
    else if (attributeName.equals(ADD_ITEM)) showAddItemAttributeDialog(menuBar);
    else if (attributeName.equals(REMOVE_ITEM)) {
      final ListBox listBox = new ListBox();
      listBox.setWidth("200px");
      int itemCount = menuBar.getItemCount();
      if (itemCount == 0) {
        Window.alert("No Items found to remove");
        return;
      }
      for (int i = 0; i < itemCount; i++)
        listBox.addItem(menuBar.getMenuItem(i).getText(), Integer.toString(i));
      VkDesignerUtil.showAddListDialog(
          "Choose the item to edit",
          listBox,
          new IDialogCallback() {
            @Override
            public void save(String number) {
              menuBar.removeItem(menuBar.getMenuItem(listBox.getSelectedIndex()));
            }
          });
    } else if (attributeName.equals(EDIT_ITEM)) {
      final ListBox listBox = new ListBox();
      listBox.setWidth("200px");
      int itemCount = menuBar.getItemCount();
      if (itemCount == 0) {
        Window.alert("No Items found to edit");
        return;
      }
      for (int i = 0; i < itemCount; i++)
        listBox.addItem(menuBar.getMenuItem(i).getText(), Integer.toString(i));
      VkDesignerUtil.showAddListDialog(
          "Choose the item to edit",
          listBox,
          new IDialogCallback() {
            @Override
            public void save(String number) {
              int index = listBox.getSelectedIndex();
              showEditItemAttributeDialog(menuBar, index);
            }
          });
    } else if (attributeName.equals(ADD_MENU)) {
      final TextBox nameTb = new TextBox();
      nameTb.setWidth("300px");
      VkDesignerUtil.showAddTextAttributeDialog(
          "Please provide name of sub-menu",
          nameTb,
          new IDialogCallback() {

            @Override
            public void save(String js) {
              final VkMenuBarVertical widget =
                  (VkMenuBarVertical)
                      VkStateHelper.getInstance().getEngine().getWidget(VkMenuBarVertical.NAME);
              menuBar.add(widget);
              menuBar.getMenuItem(menuBar.getItemCount() - 1).setText(nameTb.getText());
            }
          });
    } else VkStateHelper.getInstance().getEngine().applyAttribute(attributeName, invokingWidget);
  }
 @Override
 public void copyAttributes(Widget widgetSource, Widget widgetTarget) {
   super.copyAttributes(widgetSource, widgetTarget);
   VkMenuBarHorizontal sourceMenuBar = (VkMenuBarHorizontal) widgetSource;
   VkMenuBarHorizontal targetMenuBar = (VkMenuBarHorizontal) widgetTarget;
   for (int i = 0, allItems = 0, k = 0; i < sourceMenuBar.getItemCount(); i++, allItems++) {
     if (sourceMenuBar.getItems().get(i).getSubMenu() == null)
       addMenuItem(
           targetMenuBar,
           sourceMenuBar.getItems().get(i).getHTML(),
           sourceMenuBar
               .getCommandJs()
               .get(sourceMenuBar.getItems().indexOf(sourceMenuBar.getItems().get(i))));
     else {
       VkMenuBarHorizontal widget =
           (VkMenuBarHorizontal)
               VkStateHelper.getInstance().getEngine().getWidget(VkMenuBarVertical.NAME);
       targetMenuBar.addItem(
           new MenuItem(
               sourceMenuBar.getItems().get(i).getHTML(),
               (VkMenuBarVertical)
                   VkStateHelper.getInstance()
                       .getWidgetEngineMapping()
                       .getEngineMap()
                       .get(((IVkWidget) widget).getWidgetName())
                       .deepClone(sourceMenuBar.getItems().get(i).getSubMenu(), widget)));
     }
     if (k < sourceMenuBar.getSeperatorIndices().size()
         && sourceMenuBar.getSeperatorIndices().get(k) == allItems + 1)
       addSeparator(targetMenuBar);
   }
 }
 @Override
 public String serialize(IVkWidget widget) {
   StringBuffer buffer = new StringBuffer("{");
   buffer.append("widgetName:'").append(widget.getWidgetName()).append("'");
   buffer.append(",style:'").append(VkDesignerUtil.getCssText((Widget) widget)).append("'");
   serializeAttributes(buffer, (Widget) widget);
   VkMenuBarHorizontal menuBar = (VkMenuBarHorizontal) widget;
   buffer.append(",items:[");
   for (int i = 0, allItems = 0, k = 0; i < menuBar.getItemCount(); i++, allItems++) {
     buffer.append("{html:'").append(menuBar.getItems().get(i).getHTML()).append("'");
     if (menuBar.getItems().get(i).getSubMenu() == null) {
       if (menuBar.getCommandJs().containsKey(i))
         buffer
             .append(",js:'")
             .append(menuBar.getCommandJs().get(i).replace('\'', '"'))
             .append("'");
       else
         buffer
             .append(",child:")
             .append(
                 VkStateHelper.getInstance()
                     .getWidgetEngineMapping()
                     .getEngineMap()
                     .get(((IVkWidget) menuBar.getWidgets().get(i)).getWidgetName())
                     .serialize((IVkWidget) menuBar.getWidgets().get(i)));
     } else
       buffer
           .append(",menu:")
           .append(serialize((IVkWidget) menuBar.getItems().get(i).getSubMenu()));
     buffer.append("},");
     if (k < menuBar.getSeperatorIndices().size()
         && menuBar.getSeperatorIndices().get(k) == allItems + 1) {
       buffer.append("{separator:''},");
       allItems++;
       k++;
     }
   }
   if (buffer.charAt(buffer.length() - 1) == ',') buffer.deleteCharAt(buffer.length() - 1);
   buffer.append("]}");
   return buffer.toString();
 }
 private void showEditItemAttributeDialog(final VkMenuBarHorizontal menuBar, final int index) {
   final DialogBox origDialog = new DialogBox();
   DOM.setStyleAttribute(origDialog.getElement(), "zIndex", Integer.toString(Integer.MAX_VALUE));
   final VerticalPanel dialog = new VerticalPanel();
   origDialog.add(dialog);
   origDialog.setText("Provide html for item name and JS to execute on its click");
   dialog.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
   DOM.setStyleAttribute(origDialog.getElement(), "zIndex", Integer.MAX_VALUE + "");
   HorizontalPanel nameHp = new HorizontalPanel();
   nameHp.setWidth("100%");
   dialog.add(nameHp);
   nameHp.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
   nameHp.add(new Label("Name HTML:"));
   nameHp.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
   nameHp.setCellWidth(nameHp.getWidget(0), "35%");
   final TextArea nameTextArea = new TextArea();
   nameTextArea.setText(menuBar.getMenuItem(index).getHTML());
   nameHp.add(nameTextArea);
   nameTextArea.setSize("300px", "100px");
   new Timer() {
     @Override
     public void run() {
       VkDesignerUtil.centerDialog(dialog);
       nameTextArea.setFocus(true);
     }
   }.schedule(100);
   final VkEventTextArea jsTextArea = new VkEventTextArea();
   if (menuBar.getCommandJs().containsKey(index)) {
     HorizontalPanel jsHp = new HorizontalPanel();
     jsHp.setWidth("100%");
     dialog.add(jsHp);
     jsHp.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
     jsHp.add(new Label("Command Js:"));
     jsHp.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
     jsHp.setCellWidth(jsHp.getWidget(0), "35%");
     jsTextArea.setSize("250px", "80px");
     jsHp.add(jsTextArea);
     jsTextArea.setText(menuBar.getCommandJs().get(index));
   }
   HorizontalPanel buttonsPanel = new HorizontalPanel();
   dialog.add(buttonsPanel);
   Button saveButton = new Button("Save");
   buttonsPanel.add(saveButton);
   saveButton.addClickHandler(
       new ClickHandler() {
         @Override
         public void onClick(ClickEvent event) {
           origDialog.hide();
           MenuItem item = menuBar.getMenuItem(index);
           item.setHTML(nameTextArea.getText());
           if (menuBar.getCommandJs().containsKey(index)) {
             menuBar.getCommandJs().put(index, jsTextArea.getText());
             item.setCommand(
                 new Command() {
                   @Override
                   public void execute() {
                     VkStateHelper.getInstance()
                         .getEventHelper()
                         .executeEvent(jsTextArea.getText(), (Map<String, String>) null);
                   }
                 });
           }
         }
       });
   Button cancelButton = new Button("Cancel");
   buttonsPanel.add(cancelButton);
   cancelButton.addClickHandler(
       new ClickHandler() {
         @Override
         public void onClick(ClickEvent event) {
           origDialog.hide();
         }
       });
   origDialog.center();
   origDialog.setPopupPosition(origDialog.getPopupLeft() + 1, origDialog.getPopupTop());
 }
 private void addSeparator(VkMenuBarHorizontal menuBar) {
   menuBar.getSeperatorIndices().add(menuBar.getSeparatorIndex(menuBar.addSeparator()));
 }