public synchronized void removeTab(int index) {
    //	setActiveTabIndex(index > 0 ? index-1 : getWidgetModel().getChildren().size()-1);
    if (index < 0 || index >= getTabItemCount()) throw new IllegalArgumentException();
    getWidgetModel().removeChild(getWidgetModel().getChildren().get(index));
    getTabFigure().removeTab(index);
    tabItemList.remove(index);

    // left shift tab's properties
    for (int j = index; j < getWidgetModel().getChildren().size(); j++) {
      for (TabProperty tabProperty : TabProperty.values()) {
        String propID1 = TabModel.makeTabPropID(tabProperty.propIDPre, j);
        String propID2 = TabModel.makeTabPropID(tabProperty.propIDPre, j + 1);
        getWidgetModel().setPropertyValue(propID1, getWidgetModel().getPropertyValue(propID2));
      }
    }
    // updateTabItemsWithModel();

    // update property sheet
    getWidgetModel()
        .setPropertyValue(TabModel.PROP_TAB_COUNT, getWidgetModel().getChildren().size(), false);

    for (TabProperty tabProperty : TabProperty.values()) {
      String propID =
          TabModel.makeTabPropID(tabProperty.propIDPre, getWidgetModel().getChildren().size());
      getWidgetModel().setPropertyVisible(propID, false);
    }

    // update active tab index to the new added tab
    updateTabAreaSize();

    setActiveTabIndex(index >= getWidgetModel().getChildren().size() ? index - 1 : index);
  }
 private void rightShiftTabProperties(int index) {
   for (int j = getWidgetModel().getChildren().size() - 1; j > index; j--) {
     for (TabProperty tabProperty : TabProperty.values()) {
       String propID1 = TabModel.makeTabPropID(tabProperty.propIDPre, j - 1);
       String propID2 = TabModel.makeTabPropID(tabProperty.propIDPre, j);
       getWidgetModel().setPropertyValue(propID2, getWidgetModel().getPropertyValue(propID1));
     }
   }
 }
  private void registerTabPropertyChangeHandlers() {
    // set prop handlers and init all the potential tabs
    for (int i = 0; i < TabModel.MAX_TABS_AMOUNT; i++) {

      for (TabProperty tabProperty : TabProperty.values()) {

        String propID = TabModel.makeTabPropID(tabProperty.propIDPre, i);
        IWidgetPropertyChangeHandler handler = new TabPropertyChangeHandler(i, tabProperty);
        setPropertyChangeHandler(propID, handler);
      }
    }

    for (int i = TabModel.MAX_TABS_AMOUNT - 1; i >= getWidgetModel().getTabsAmount(); i--) {
      for (TabProperty tabProperty : TabProperty.values()) {
        String propID = TabModel.makeTabPropID(tabProperty.propIDPre, i);
        getWidgetModel().setPropertyVisible(propID, false);
      }
    }
  }
  /**
   * Add a TabItem to the index;
   *
   * @param index
   * @param tabItem
   */
  public synchronized void addTab(int index, TabItem tabItem) {

    if (index < 0 || index > getTabItemCount()) throw new IllegalArgumentException();

    if (index >= TabModel.MAX_TABS_AMOUNT) return;
    GroupingContainerModel groupingContainerModel = tabItem.getGroupingContainerModel();

    getWidgetModel().addChild(index, groupingContainerModel);

    getTabFigure().addTab((String) tabItem.getPropertyValue(TabProperty.TITLE), index);
    tabItemList.add(index, tabItem);

    initTabLabel(index, tabItem);

    rightShiftTabProperties(index);

    // apply tab properties from TabItem to TabModel
    for (TabProperty tabProperty : TabProperty.values()) {
      String propID = TabModel.makeTabPropID(tabProperty.propIDPre, index);
      getWidgetModel().setPropertyValue(propID, tabItem.getPropertyValue(tabProperty));
    }

    // update property sheet
    getWidgetModel()
        .setPropertyValue(TabModel.PROP_TAB_COUNT, getWidgetModel().getChildren().size(), false);

    for (TabProperty tabProperty : TabProperty.values()) {
      String propID =
          TabModel.makeTabPropID(tabProperty.propIDPre, getWidgetModel().getChildren().size() - 1);
      getWidgetModel().setPropertyVisible(propID, true);
    }

    // update active tab index to the new added tab
    updateTabAreaSize();

    setActiveTabIndex(index);
  }
  @Override
  protected void registerPropertyChangeHandlers() {
    // init tabs
    int i = 0;
    for (AbstractWidgetModel child : getWidgetModel().getChildren()) {
      if (child instanceof GroupingContainerModel) {
        child.setPropertyValue(AbstractWidgetModel.PROP_VISIBLE, true);
        child.setPropertyValue(AbstractWidgetModel.PROP_VISIBLE, false);
        getTabFigure()
            .addTab(
                (String)
                    getWidgetModel()
                        .getPropertyValue(TabModel.makeTabPropID(TabProperty.TITLE.propIDPre, i)));
        tabItemList.add(i, new TabItem(getWidgetModel(), i, (GroupingContainerModel) child));
        for (TabProperty tabProperty : TabProperty.values())
          setTabProperty(
              i,
              tabProperty,
              getWidgetModel().getPropertyValue(TabModel.makeTabPropID(tabProperty.propIDPre, i)));

        i++;
      }
    }
    IWidgetPropertyChangeHandler relocContainerHandler =
        new IWidgetPropertyChangeHandler() {

          public boolean handleChange(Object oldValue, Object newValue, IFigure figure) {
            updateTabAreaSize();
            refreshVisuals();
            return false;
          }
        };
    setPropertyChangeHandler(AbstractWidgetModel.PROP_WIDTH, relocContainerHandler);
    setPropertyChangeHandler(AbstractWidgetModel.PROP_HEIGHT, relocContainerHandler);

    IWidgetPropertyChangeHandler horizontalHandler =
        new IWidgetPropertyChangeHandler() {
          public boolean handleChange(Object oldValue, Object newValue, IFigure figure) {
            ((TabFigure) figure).setHorizontal((Boolean) newValue);
            updateTabAreaSize();
            refreshVisuals();
            return false;
          }
        };
    setPropertyChangeHandler(TabModel.PROP_HORIZONTAL_TABS, horizontalHandler);

    IWidgetPropertyChangeHandler activeTabHandler =
        new IWidgetPropertyChangeHandler() {
          public boolean handleChange(Object oldValue, Object newValue, IFigure figure) {
            ((TabFigure) figure).setActiveTabIndex((Integer) newValue);
            updateTabAreaSize();
            refreshVisuals();
            return false;
          }
        };
    setPropertyChangeHandler(TabModel.PROP_ACTIVE_TAB, activeTabHandler);

    IWidgetPropertyChangeHandler handler =
        new IWidgetPropertyChangeHandler() {

          @Override
          public boolean handleChange(Object oldValue, Object newValue, IFigure figure) {
            ((TabFigure) figure).setMinimumTabHeight((Integer) newValue);
            return false;
          }
        };
    setPropertyChangeHandler(TabModel.PROP_MINIMUM_TAB_HEIGHT, handler);

    IWidgetPropertyChangeHandler updateTabAreaSizeHandler =
        new IWidgetPropertyChangeHandler() {

          @Override
          public boolean handleChange(Object oldValue, Object newValue, IFigure figure) {
            updateTabAreaSize();
            return false;
          }
        };
    setPropertyChangeHandler(TabModel.PROP_BORDER_WIDTH, updateTabAreaSizeHandler);

    registerTabPropertyChangeHandlers();
    registerTabsAmountChangeHandler();
  }
 private void initTabLabel(int index, TabItem tabItem) {
   for (TabProperty tabProperty : TabProperty.values()) {
     Object propValue = tabItem.getPropertyValue(tabProperty);
     setTabFigureProperty(index, tabProperty, propValue);
   }
 }