@Override
  public void apply() throws ConfigurationException {
    List<X509Certificate> existing = myTrustManager.getCertificates();

    Set<X509Certificate> added = new HashSet<X509Certificate>(myCertificates);
    added.removeAll(existing);

    Set<X509Certificate> removed = new HashSet<X509Certificate>(existing);
    removed.removeAll(myCertificates);

    for (X509Certificate certificate : added) {
      if (!myTrustManager.addCertificate(certificate)) {
        throw new ConfigurationException(
            "Cannot add certificate for " + getCommonName(certificate), "Cannot Add Certificate");
      }
    }

    for (X509Certificate certificate : removed) {
      if (!myTrustManager.removeCertificate(certificate)) {
        throw new ConfigurationException(
            "Cannot remove certificate for " + getCommonName(certificate),
            "Cannot Remove Certificate");
      }
    }
    CertificateManager.Config state = CertificateManager.getInstance().getState();

    state.ACCEPT_AUTOMATICALLY = myAcceptAutomatically.isSelected();
    state.CHECK_HOSTNAME = myCheckHostname.isSelected();
    state.CHECK_VALIDITY = myCheckValidityPeriod.isSelected();
  }
  @Override
  public void reset() {
    List<X509Certificate> original = myTrustManager.getCertificates();
    myTreeBuilder.reset(original);

    myCertificates.clear();
    myCertificates.addAll(original);

    myDetailsPanel.removeAll();
    myDetailsPanel.add(myEmptyPanel, EMPTY_PANEL);

    // fill lower panel with cards
    for (X509Certificate certificate : original) {
      addCertificatePanel(certificate);
    }

    if (!myCertificates.isEmpty()) {
      myTreeBuilder.selectFirstCertificate();
    }

    CertificateManager.Config state = CertificateManager.getInstance().getState();
    myAcceptAutomatically.setSelected(state.ACCEPT_AUTOMATICALLY);
    myCheckHostname.setSelected(state.CHECK_HOSTNAME);
    myCheckValidityPeriod.setSelected(state.CHECK_VALIDITY);
  }
 @Override
 public boolean isModified() {
   CertificateManager.Config state = CertificateManager.getInstance().getState();
   return myAcceptAutomatically.isSelected() != state.ACCEPT_AUTOMATICALLY
       || myCheckHostname.isSelected() != state.CHECK_HOSTNAME
       || myCheckValidityPeriod.isSelected() != state.CHECK_VALIDITY
       || !myCertificates.equals(new HashSet<X509Certificate>(myTrustManager.getCertificates()));
 }
  private void initializeUI() {
    myTree = new Tree();
    myTreeBuilder = new CertificateTreeBuilder(myTree);

    // are not fully functional by now
    myCheckHostname.setVisible(false);
    myCheckValidityPeriod.setVisible(false);

    myTrustManager = CertificateManager.getInstance().getCustomTrustManager();
    // show newly added certificates
    myTrustManager.addListener(this);

    myTree.getEmptyText().setText("No certificates");
    myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    myTree.setRootVisible(false);
    // myTree.setShowsRootHandles(false);

    ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree).disableUpDownActions();
    decorator
        .setAddAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                // show choose file dialog, add certificate
                FileChooser.chooseFile(
                    CERTIFICATE_DESCRIPTOR,
                    null,
                    null,
                    file -> {
                      String path = file.getPath();
                      X509Certificate certificate = CertificateUtil.loadX509Certificate(path);
                      if (certificate == null) {
                        Messages.showErrorDialog(
                            myRootPanel, "Malformed X509 server certificate", "Not Imported");
                      } else if (myCertificates.contains(certificate)) {
                        Messages.showWarningDialog(
                            myRootPanel, "Certificate already exists", "Not Imported");
                      } else {
                        myCertificates.add(certificate);
                        myTreeBuilder.addCertificate(certificate);
                        addCertificatePanel(certificate);
                        myTreeBuilder.selectCertificate(certificate);
                      }
                    });
              }
            })
        .setRemoveAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                // allow to delete several certificates at once
                for (X509Certificate certificate : myTreeBuilder.getSelectedCertificates(true)) {
                  myCertificates.remove(certificate);
                  myTreeBuilder.removeCertificate(certificate);
                }
                if (myCertificates.isEmpty()) {
                  showCard(EMPTY_PANEL);
                } else {
                  myTreeBuilder.selectFirstCertificate();
                }
              }
            });

    myTree.addTreeSelectionListener(
        new TreeSelectionListener() {
          @Override
          public void valueChanged(TreeSelectionEvent e) {
            X509Certificate certificate = myTreeBuilder.getFirstSelectedCertificate(true);
            if (certificate != null) {
              showCard(getCardName(certificate));
            }
          }
        });
    myCertificatesListPanel.add(decorator.createPanel(), BorderLayout.CENTER);
  }
 @Override
 public void disposeUIResources() {
   Disposer.dispose(myTreeBuilder);
   myTrustManager.removeListener(this);
 }