@Override
  public JComponent createComponent() {
    internalTemplateNames = ContainerUtil.map2Set(manager.getInternalTemplates(), FileTemplate::getName);

    myUIDisposable = Disposer.newDisposable();

    myTemplatesList = new FileTemplateTabAsList(getTemplatesTitle()) {
      @Override
      public void onTemplateSelected() {
        onListSelectionChanged();
      }
    };
    myIncludesList = new FileTemplateTabAsList(getIncludesTitle()) {
      @Override
      public void onTemplateSelected() {
        onListSelectionChanged();
      }
    };
    myCodeTemplatesList = new FileTemplateTabAsList(getCodeTitle()) {
      @Override
      public void onTemplateSelected() {
        onListSelectionChanged();
      }
    };
    currentTab = myTemplatesList;

    final List<FileTemplateTab> allTabs = new ArrayList<>(Arrays.asList(myTemplatesList, myIncludesList, myCodeTemplatesList));

    final List<FileTemplateGroupDescriptorFactory> factories = FileTemplateGroupDescriptorFactory.EXTENSION_POINT_NAME.getExtensionList();
    if (!factories.isEmpty()) {
      otherTemplatesList = new FileTemplateTabAsTree(getOtherTitle()) {
        @Override
        public void onTemplateSelected() {
          onListSelectionChanged();
        }

        @Override
        protected FileTemplateNode initModel() {
          SortedSet<FileTemplateGroupDescriptor> categories =
            new TreeSet<>(Comparator.comparing(FileTemplateGroupDescriptor::getTitle));

          for (FileTemplateGroupDescriptorFactory templateGroupFactory : factories) {
            ContainerUtil.addIfNotNull(categories, templateGroupFactory.getFileTemplatesDescriptor());
          }

          return new FileTemplateNode("ROOT", null, ContainerUtil.map(categories, FileTemplateNode::new));
        }
      };
      allTabs.add(otherTemplatesList);
    }

    editor = new FileTemplateConfigurable(myProject);
    editor.addChangeListener(__ -> onEditorChanged());
    myEditorComponent = editor.createComponent();
    myEditorComponent.setBorder(JBUI.Borders.empty(10, 0, 10, 10));

    myTabs = allTabs.toArray(new FileTemplateTab[0]);
    myTabbedPane = new TabbedPaneWrapper(myUIDisposable);
    myTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
    myLeftPanel = new JPanel(new CardLayout());
    for (FileTemplateTab tab : myTabs) {
      myLeftPanel.add(ScrollPaneFactory.createScrollPane(tab.getComponent()), tab.getTitle());
      JPanel fakePanel = new JPanel();
      fakePanel.setPreferredSize(new Dimension(0, 0));
      myTabbedPane.addTab(tab.getTitle(), fakePanel);
    }

    myTabbedPane.addChangeListener(__ -> onTabChanged());

    DefaultActionGroup group = new DefaultActionGroup();
    AnAction removeAction = new DumbAwareAction(IdeBundle.message("action.remove.template"), null, AllIcons.General.Remove) {
      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        onRemove();
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        if (currentTab == null) {
          e.getPresentation().setEnabled(false);
          return;
        }
        FileTemplate selectedItem = getSelectedTemplate();
        e.getPresentation().setEnabled(selectedItem != null && !isInternalTemplate(selectedItem.getName(), currentTab.getTitle()));
      }
      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    };
    AnAction addAction = new DumbAwareAction(IdeBundle.message("action.create.template"), null, AllIcons.General.Add) {
      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        onAdd(false);
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(!(currentTab == myCodeTemplatesList || currentTab == otherTemplatesList));
      }
      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    };
    AnAction addChildAction = new DumbAwareAction(IdeBundle.message("action.create.child.template"), null, AllIcons.Actions.AddFile) {
      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        onAdd(true);
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(getSelectedTemplate() != null &&
                                       currentTab != null &&
                                       !isInternalTemplate(getSelectedTemplate().getName(), currentTab.getTitle()) &&
                                       !FileTemplateBase.isChild(getSelectedTemplate()) &&
                                       currentTab == myTemplatesList);
      }
      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    };
    AnAction cloneAction = new DumbAwareAction(IdeBundle.message("action.copy.template"), null, PlatformIcons.COPY_ICON) {
      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        onClone();
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(currentTab != myCodeTemplatesList
                                       && currentTab != otherTemplatesList
                                       && getSelectedTemplate() != null);
      }
      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    };
    AnAction resetAction = new DumbAwareAction(IdeBundle.message("action.reset.to.default"), null, AllIcons.Actions.Rollback) {
      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        onReset();
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        if (currentTab == null) {
          e.getPresentation().setEnabled(false);
          return;
        }
        final FileTemplate selectedItem = getSelectedTemplate();
        e.getPresentation().setEnabled(selectedItem instanceof BundledFileTemplate && !selectedItem.isDefault());
      }
      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    };
    group.add(addAction);
    group.add(addChildAction);
    group.add(removeAction);
    group.add(cloneAction);
    group.add(resetAction);

    addAction.registerCustomShortcutSet(CommonShortcuts.getInsert(), currentTab.getComponent());
    removeAction.registerCustomShortcutSet(CommonShortcuts.getDelete(),
                                           currentTab.getComponent());

    ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("FileTemplatesConfigurable", group, true);
    toolbar.setTargetComponent(myLeftPanel);
    myToolBar = toolbar.getComponent();
    myToolBar.setBorder(new CustomLineBorder(1, 1, 0, 1));

    mySchemesPanel = new SchemesPanel();
    mySchemesPanel.setBorder(JBUI.Borders.empty(5, 10, 0, 10));
    mySchemesPanel.resetSchemes(Arrays.asList(FileTemplatesScheme.DEFAULT, manager.getProjectScheme()));

    JPanel leftPanelWrapper = new JPanel(new BorderLayout());
    leftPanelWrapper.setBorder(JBUI.Borders.empty(10, 10, 10, 0));
    leftPanelWrapper.add(BorderLayout.NORTH, myToolBar);
    leftPanelWrapper.add(BorderLayout.CENTER, myLeftPanel);

    JPanel centerPanel = new JPanel(new BorderLayout());
    centerPanel.add(myTabbedPane.getComponent(), BorderLayout.NORTH);
    Splitter splitter = new Splitter(false, 0.3f);
    splitter.setDividerWidth(JBUIScale.scale(10));
    splitter.setFirstComponent(leftPanelWrapper);
    splitter.setSecondComponent(myEditorComponent);
    centerPanel.add(splitter, BorderLayout.CENTER);

    myMainPanel = new JPanel(new BorderLayout());
    myMainPanel.add(mySchemesPanel, BorderLayout.NORTH);
    myMainPanel.add(centerPanel, BorderLayout.CENTER);

    final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance();
    final String tabName = propertiesComponent.getValue(CURRENT_TAB);
    selectTab(tabName);

    return myMainPanel;
  }
@Override
  public JComponent createComponent()