@Nullable
  @Override
  public JComponent createComponent() {
    myTableModel = new MyTableModel();
    myTableModel.addFromAnnotations(myProject);

    JBTable table = new JBTable(myTableModel);
    table.setColumnSelectionAllowed(false);
    table.setShowGrid(false);

    JTextField stringCellEditor = new JTextField();
    stringCellEditor.putClientProperty(DarculaUIUtil.COMPACT_PROPERTY, Boolean.TRUE);
    table.setDefaultEditor(String.class, new DefaultCellEditor(stringCellEditor));
    table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() {
      @Override
      public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        Dimension editorSize = stringCellEditor.getPreferredSize();
        size.height = Math.max(size.height, editorSize.height);
        return size;
      }
    });

    TableColumnModel columnModel = table.getColumnModel();
    TableUtil.setupCheckboxColumn(columnModel.getColumn(MyTableModel.ENABLED_COLUMN));

    ToolbarDecorator decorator = ToolbarDecorator.createDecorator(table);
    decorator.setAddAction(new AnActionButtonRunnable() {
      @Override
      public void run(AnActionButton button) {
        myTableModel.addRow();
      }
    });
    decorator.setRemoveAction(new AnActionButtonRunnable() {
      @Override
      public void run(AnActionButton button) {
        TableUtil.removeSelectedItems(table);
      }
    });
    decorator.setMoveUpAction(new AnActionButtonRunnable() {
      @Override
      public void run(AnActionButton button) {
        TableUtil.moveSelectedItemsUp(table);
      }
    });
    decorator.setMoveDownAction(new AnActionButtonRunnable() {
      @Override
      public void run(AnActionButton button) {
        TableUtil.moveSelectedItemsDown(table);
      }
    });

    decorator.addExtraAction(new DumbAwareAction(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.duplicate"),
                                                 JavaDebuggerBundle.messagePointer("action.AnActionButton.description.duplicate"),
                                                 PlatformIcons.COPY_ICON) {
      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(table.getSelectedRowCount() == 1);
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }

      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        selectedCapturePoints(table).forEach(c -> {
          try {
            int idx = myTableModel.add(c.clone());
            table.getSelectionModel().setSelectionInterval(idx, idx);
          }
          catch (CloneNotSupportedException ex) {
            LOG.error(ex);
          }
        });
      }
    });

    decorator.addExtraAction(new DumbAwareAction(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.enable.selected"),
                                                 JavaDebuggerBundle.messagePointer("action.AnActionButton.description.enable.selected"),
                                                 PlatformIcons.SELECT_ALL_ICON) {
      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(table.getSelectedRowCount() > 0);
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }

      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        selectedCapturePoints(table).forEach(c -> c.myEnabled = true);
        table.repaint();
      }
    });
    decorator.addExtraAction(new DumbAwareAction(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.disable.selected"),
                                                 JavaDebuggerBundle.messagePointer("action.AnActionButton.description.disable.selected"),
                                                 PlatformIcons.UNSELECT_ALL_ICON) {
      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(table.getSelectedRowCount() > 0);
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }

      @Override
      public void actionPerformed(@NotNull AnActionEvent e) {
        selectedCapturePoints(table).forEach(c -> c.myEnabled = false);
        table.repaint();
      }
    });

    new DumbAwareAction(CommonBundle.message("action.text.toggle")) {
      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(table.getSelectedRowCount() == 1 && !table.isEditing());
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }

      @Override
      public void actionPerformed(@NotNull final AnActionEvent e) {
        selectedCapturePoints(table).forEach(c -> c.myEnabled = !c.myEnabled);
        table.repaint();
      }
    }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), table);

    decorator.addExtraAction(new DumbAwareAction(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.import"),
                                                 JavaDebuggerBundle.messagePointer("action.AnActionButton.description.import"),
                                                 AllIcons.Actions.Install) {
      @Override
      public void actionPerformed(@NotNull final AnActionEvent e) {
        FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, true, false, true, true) {
          @Override
          public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
            return super.isFileVisible(file, showHiddenFiles) &&
                   (file.isDirectory() || "xml".equals(file.getExtension()) || FileTypeRegistry.getInstance().isFileOfType(file, ArchiveFileType.INSTANCE));
          }

          @Override
          public boolean isFileSelectable(@Nullable VirtualFile file) {
            return file != null && FileTypeRegistry.getInstance().isFileOfType(file, StdFileTypes.XML);
          }
        };
        descriptor.setDescription(JavaDebuggerBundle.message("please.select.a.file.to.import"));
        descriptor.setTitle(JavaDebuggerBundle.message("import.capture.points"));

        VirtualFile[] files = FileChooser.chooseFiles(descriptor, e.getProject(), null);
        if (ArrayUtil.isEmpty(files)) return;

        table.getSelectionModel().clearSelection();

        for (VirtualFile file : files) {
          try {
            for (Element element : JDOMUtil.load(file.getInputStream()).getChildren()) {
              int idx = myTableModel.addIfNeeded(XmlSerializer.deserialize(element, CapturePoint.class));
              table.getSelectionModel().addSelectionInterval(idx, idx);
            }
          }
          catch (Exception ex) {
            final String msg = ex.getLocalizedMessage();
            Messages.showErrorDialog(e.getProject(), msg != null && !msg.isEmpty() ? msg : ex.toString(),
                                     JavaDebuggerBundle.message("export.failed"));
          }
        }
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
      }
    });
    decorator.addExtraAction(new DumbAwareAction(JavaDebuggerBundle.messagePointer("action.AnActionButton.text.export"),
                                                 JavaDebuggerBundle.messagePointer("action.AnActionButton.description.export"),
                                                 AllIcons.ToolbarDecorator.Export) {
      @Override
      public void actionPerformed(@NotNull final AnActionEvent e) {
        VirtualFileWrapper wrapper = FileChooserFactory.getInstance()
          .createSaveFileDialog(new FileSaverDescriptor(JavaDebuggerBundle.message("export.selected.capture.points.to.file"), "", "xml"), e.getProject())
          .save((Path)null, null);
        if (wrapper == null) return;

        Element rootElement = new Element("capture-points");
        selectedCapturePoints(table).forEach(c -> {
          try {
            CapturePoint clone = c.clone();
            clone.myEnabled = false;
            rootElement.addContent(XmlSerializer.serialize(clone));
          }
          catch (CloneNotSupportedException ex) {
            LOG.error(ex);
          }
        });
        try {
          JDOMUtil.write(rootElement, wrapper.getFile().toPath());
        }
        catch (Exception ex) {
          final String msg = ex.getLocalizedMessage();
          Messages.showErrorDialog(e.getProject(), msg != null && !msg.isEmpty() ? msg : ex.toString(),
                                   JavaDebuggerBundle.message("export.failed"));
        }
      }

      @Override
      public void update(@NotNull AnActionEvent e) {
        e.getPresentation().setEnabled(table.getSelectedRowCount() > 0);
      }

      @Override
      public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.EDT;
      }
    });

    myConfigureAnnotationsButton.addActionListener(e -> new AsyncAnnotationsDialog(myProject).show());

    myCapturePanel.setBorder(
      IdeBorderFactory.createTitledBorder(JavaDebuggerBundle.message("settings.breakpoints.based"), false, JBUI.insetsTop(8))
        .setShowLine(false));
    myCapturePanel.add(decorator.createPanel(), BorderLayout.CENTER);

    return myPanel;
  }
@Nullable
  @Override
  public JComponent createComponent()