class MenuItemFactory {

    @SuppressWarnings("unchecked")
    public <T extends MenuItemWithIconView> MenuItemViewHolder<T> makeMenuItemWithIcon(final String caption,
                                                                                       final Command cmd) {
        final MenuItemView _view = menuItemViewProducer.select(new MenuItemWithIcon() {
            @Override
            public Class<? extends Annotation> annotationType() {
                return MenuItemWithIcon.class;
            }
        }).get();
        final T view = (T) _view;
        final MenuItem item = MenuFactory.newTopLevelCustomMenu(new MenuFactory.CustomMenuBuilder() {

            @Override
            public void push(final MenuFactory.CustomMenuBuilder element) {

            }

            @Override
            public MenuItem build() {
                final BaseMenuCustom<IsWidget> cmdItem = new BaseMenuCustom<IsWidget>(null,
                                                                                      caption) {

                    private final List<EnabledStateChangeListener> enabledStateChangeListeners = new ArrayList<>();

                    @Override
                    public IsWidget build() {
                        return ElementWrapperWidget.getWidget(view.getElement());
                    }

                    @Override
                    public void setEnabled(final boolean enabled) {
                        super.setEnabled(enabled);
                        notifyListeners(enabled);
                    }

                    @Override
                    public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) {
                        enabledStateChangeListeners.add(listener);
                    }

                    private void notifyListeners(final boolean enabled) {
                        for (final EnabledStateChangeListener listener : enabledStateChangeListeners) {
                            listener.enabledStateChanged(enabled);
                        }
                    }
                };
                cmdItem.addEnabledStateChangeListener(view::setEnabled);

                return cmdItem;
            }
        }).endMenu().build().getItems().get(0);

        view.setCaption(caption);
        view.setClickHandler((e) -> {
            if (item.isEnabled()) {
                cmd.execute();
            }
        });

        return new MenuItemViewHolder<>(item,
                                        view);
    }

    @Inject public  MenuItemFactory(final @Any ManagedInstance<MenuItemView> menuItemViewProducer);

}