public ImportCustomizationDialog(final JabRefFrame frame) {
    super(frame, Localization.lang("Manage custom imports"), false);

    ImportTableModel tableModel = new ImportTableModel();
    customImporterTable = new JTable(tableModel);
    TableColumnModel cm = customImporterTable.getColumnModel();
    cm.getColumn(0).setPreferredWidth(COL_0_WIDTH);
    cm.getColumn(1).setPreferredWidth(COL_1_WIDTH);
    cm.getColumn(2).setPreferredWidth(COL_2_WIDTH);
    cm.getColumn(3).setPreferredWidth(COL_3_WIDTH);
    JScrollPane sp =
        new JScrollPane(
            customImporterTable,
            ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    customImporterTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    customImporterTable.setPreferredScrollableViewportSize(getSize());
    if (customImporterTable.getRowCount() > 0) {
      customImporterTable.setRowSelectionInterval(0, 0);
    }

    JButton addFromFolderButton = new JButton(Localization.lang("Add from folder"));
    addFromFolderButton.addActionListener(
        e -> {
          FileDialog dialog = new FileDialog(frame).withExtension(FileExtensions.CLASS);
          dialog.setDefaultExtension(FileExtensions.CLASS);
          Optional<Path> selectedFile = dialog.showDialogAndGetSelectedFile();

          if (selectedFile.isPresent() && (selectedFile.get().getParent() != null)) {
            String chosenFileStr = selectedFile.get().toString();

            try {
              String basePath = selectedFile.get().getParent().toString();
              String className = pathToClass(basePath, new File(chosenFileStr));
              CustomImporter importer = new CustomImporter(basePath, className);

              addOrReplaceImporter(importer);
              customImporterTable.revalidate();
              customImporterTable.repaint();
            } catch (Exception exc) {
              JOptionPane.showMessageDialog(
                  frame, Localization.lang("Could not instantiate %0", chosenFileStr));
            } catch (NoClassDefFoundError exc) {
              JOptionPane.showMessageDialog(
                  frame,
                  Localization.lang(
                      "Could not instantiate %0. Have you chosen the correct package path?",
                      chosenFileStr));
            }
          }
        });
    addFromFolderButton.setToolTipText(
        Localization.lang("Add a (compiled) custom Importer class from a class path.")
            + "\n"
            + Localization.lang("The path need not be on the classpath of JabRef."));

    JButton addFromJarButton = new JButton(Localization.lang("Add from JAR"));
    addFromJarButton.addActionListener(
        e -> {
          FileDialog dialog =
              new FileDialog(frame)
                  .withExtensions(EnumSet.of(FileExtensions.ZIP, FileExtensions.JAR));
          dialog.setDefaultExtension(FileExtensions.JAR);
          Optional<Path> jarZipFile = dialog.showDialogAndGetSelectedFile();

          if (jarZipFile.isPresent()) {
            try (ZipFile zipFile = new ZipFile(jarZipFile.get().toFile(), ZipFile.OPEN_READ)) {
              ZipFileChooser zipFileChooser = new ZipFileChooser(this, zipFile);
              zipFileChooser.setVisible(true);
              customImporterTable.revalidate();
              customImporterTable.repaint(10);
            } catch (IOException exc) {
              LOGGER.info("Could not open ZIP-archive.", exc);
              JOptionPane.showMessageDialog(
                  frame,
                  Localization.lang("Could not open %0", jarZipFile.get().toString())
                      + "\n"
                      + Localization.lang("Have you chosen the correct package path?"));
            } catch (NoClassDefFoundError exc) {
              LOGGER.info("Could not instantiate ZIP-archive reader.", exc);
              JOptionPane.showMessageDialog(
                  frame,
                  Localization.lang("Could not instantiate %0", jarZipFile.get().toString())
                      + "\n"
                      + Localization.lang("Have you chosen the correct package path?"));
            }
          }
        });
    addFromJarButton.setToolTipText(
        Localization.lang("Add a (compiled) custom Importer class from a ZIP-archive.")
            + "\n"
            + Localization.lang("The ZIP-archive need not be on the classpath of JabRef."));

    JButton showDescButton = new JButton(Localization.lang("Show description"));
    showDescButton.addActionListener(
        e -> {
          int row = customImporterTable.getSelectedRow();
          if (row == -1) {
            JOptionPane.showMessageDialog(frame, Localization.lang("Please select an importer."));
          } else {
            CustomImporter importer =
                ((ImportTableModel) customImporterTable.getModel()).getImporter(row);
            JOptionPane.showMessageDialog(frame, importer.getDescription());
          }
        });

    JButton removeButton = new JButton(Localization.lang("Remove"));
    removeButton.addActionListener(
        e -> {
          int row = customImporterTable.getSelectedRow();
          if (row == -1) {
            JOptionPane.showMessageDialog(frame, Localization.lang("Please select an importer."));
          } else {
            customImporterTable.removeRowSelectionInterval(row, row);
            Globals.prefs.customImports.remove(
                ((ImportTableModel) customImporterTable.getModel()).getImporter(row));
            Globals.IMPORT_FORMAT_READER.resetImportFormats(
                Globals.prefs.getImportFormatPreferences(), Globals.prefs.getXMPPreferences());
            customImporterTable.revalidate();
            customImporterTable.repaint();
          }
        });

    Action closeAction =
        new AbstractAction() {

          @Override
          public void actionPerformed(ActionEvent e) {
            dispose();
          }
        };

    JButton closeButton = new JButton(Localization.lang("Close"));
    closeButton.addActionListener(closeAction);

    JButton helpButton = new HelpAction(HelpFile.CUSTOM_IMPORTS).getHelpButton();

    // Key bindings:
    JPanel mainPanel = new JPanel();
    ActionMap am = mainPanel.getActionMap();
    InputMap im = mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close");
    am.put("close", closeAction);
    mainPanel.setLayout(new BorderLayout());
    mainPanel.add(sp, BorderLayout.CENTER);
    JPanel buttons = new JPanel();
    ButtonBarBuilder bb = new ButtonBarBuilder(buttons);
    buttons.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    bb.addGlue();
    bb.addButton(addFromFolderButton);
    bb.addButton(addFromJarButton);
    bb.addButton(showDescButton);
    bb.addButton(removeButton);
    bb.addButton(closeButton);
    bb.addUnrelatedGap();
    bb.addButton(helpButton);
    bb.addGlue();

    getContentPane().add(mainPanel, BorderLayout.CENTER);
    getContentPane().add(buttons, BorderLayout.SOUTH);
    this.setSize(getSize());
    pack();
    this.setLocationRelativeTo(frame);
    customImporterTable.requestFocus();
  }
 /**
  * Adds an importer to the model that underlies the custom importers.
  *
  * @param importer importer
  */
 public void addOrReplaceImporter(CustomImporter importer) {
   Globals.prefs.customImports.replaceImporter(importer);
   Globals.IMPORT_FORMAT_READER.resetImportFormats(
       Globals.prefs.getImportFormatPreferences(), Globals.prefs.getXMPPreferences());
   ((ImportTableModel) customImporterTable.getModel()).fireTableDataChanged();
 }