@Override
  public void reset(@NotNull HttpConfigurable settings) {
    myNoProxyRb.setSelected(true); // default
    myAutoDetectProxyRb.setSelected(settings.USE_PROXY_PAC);
    myPacUrlCheckBox.setSelected(settings.USE_PAC_URL);
    myPacUrlTextField.setText(settings.PAC_URL);
    myUseHTTPProxyRb.setSelected(settings.USE_HTTP_PROXY);
    myProxyAuthCheckBox.setSelected(settings.PROXY_AUTHENTICATION);

    enableProxy(settings.USE_HTTP_PROXY);

    myProxyLoginTextField.setText(settings.getProxyLogin());
    myProxyPasswordTextField.setText(settings.getPlainProxyPassword());

    myProxyPortTextField.setNumber(settings.PROXY_PORT);
    myProxyHostTextField.setText(settings.PROXY_HOST);
    myProxyExceptions.setText(StringUtil.notNullize(settings.PROXY_EXCEPTIONS));

    myRememberProxyPasswordCheckBox.setSelected(settings.KEEP_PROXY_PASSWORD);
    mySocks.setSelected(settings.PROXY_TYPE_IS_SOCKS);
    myHTTP.setSelected(!settings.PROXY_TYPE_IS_SOCKS);

    boolean showError = !StringUtil.isEmptyOrSpaces(settings.LAST_ERROR);
    myErrorLabel.setVisible(showError);
    myErrorLabel.setText(showError ? errorText(settings.LAST_ERROR) : null);

    final String oldStyleText =
        CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
    myOtherWarning.setVisible(oldStyleText != null);
    if (oldStyleText != null) {
      myOtherWarning.setText(oldStyleText);
      myOtherWarning.setIcon(Messages.getWarningIcon());
    }
  }
  public boolean isModified() {
    boolean isModified = false;
    HttpConfigurable httpConfigurable = myHttpConfigurable;
    if (!Comparing.equal(myProxyExceptions.getText().trim(), httpConfigurable.PROXY_EXCEPTIONS))
      return true;
    isModified |= httpConfigurable.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected();
    isModified |= httpConfigurable.USE_PAC_URL != myPacUrlCheckBox.isSelected();
    isModified |= !Comparing.strEqual(httpConfigurable.PAC_URL, myPacUrlTextField.getText());
    isModified |= httpConfigurable.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected();
    isModified |= httpConfigurable.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected();
    isModified |=
        httpConfigurable.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected();
    isModified |= httpConfigurable.PROXY_TYPE_IS_SOCKS != mySocks.isSelected();

    isModified |=
        !Comparing.strEqual(httpConfigurable.PROXY_LOGIN, myProxyLoginTextField.getText());
    isModified |=
        !Comparing.strEqual(
            httpConfigurable.getPlainProxyPassword(),
            new String(myProxyPasswordTextField.getPassword()));

    try {
      isModified |=
          httpConfigurable.PROXY_PORT != Integer.valueOf(myProxyPortTextField.getText()).intValue();
    } catch (NumberFormatException e) {
      isModified = true;
    }
    isModified |= !Comparing.strEqual(httpConfigurable.PROXY_HOST, myProxyHostTextField.getText());
    return isModified;
  }
  public void reset() {
    myNoProxyRb.setSelected(true); // default
    HttpConfigurable httpConfigurable = myHttpConfigurable;
    myAutoDetectProxyRb.setSelected(httpConfigurable.USE_PROXY_PAC);
    myPacUrlCheckBox.setSelected(httpConfigurable.USE_PAC_URL);
    myPacUrlTextField.setText(httpConfigurable.PAC_URL);
    myUseHTTPProxyRb.setSelected(httpConfigurable.USE_HTTP_PROXY);
    myProxyAuthCheckBox.setSelected(httpConfigurable.PROXY_AUTHENTICATION);

    enableProxy(httpConfigurable.USE_HTTP_PROXY);

    myProxyLoginTextField.setText(httpConfigurable.PROXY_LOGIN);
    myProxyPasswordTextField.setText(httpConfigurable.getPlainProxyPassword());

    myProxyPortTextField.setText(Integer.toString(httpConfigurable.PROXY_PORT));
    myProxyHostTextField.setText(httpConfigurable.PROXY_HOST);
    myProxyExceptions.setText(httpConfigurable.PROXY_EXCEPTIONS);

    myRememberProxyPasswordCheckBox.setSelected(httpConfigurable.KEEP_PROXY_PASSWORD);
    mySocks.setSelected(httpConfigurable.PROXY_TYPE_IS_SOCKS);
    myHTTP.setSelected(!httpConfigurable.PROXY_TYPE_IS_SOCKS);

    final boolean showError = !StringUtil.isEmptyOrSpaces(httpConfigurable.LAST_ERROR);
    myErrorLabel.setVisible(showError);
    myErrorLabel.setText(showError ? errorText(httpConfigurable.LAST_ERROR) : "");

    final String oldStyleText =
        CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
    myOtherWarning.setVisible(oldStyleText != null);
    if (oldStyleText != null) {
      myOtherWarning.setText(oldStyleText);
      myOtherWarning.setUI(new MultiLineLabelUI());
      myOtherWarning.setIcon(Messages.getWarningIcon());
    }
  }
  @Override
  public boolean isModified(@NotNull HttpConfigurable settings) {
    if (!isValid()) {
      return false;
    }

    return !Comparing.strEqual(myProxyExceptions.getText().trim(), settings.PROXY_EXCEPTIONS)
        || settings.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected()
        || settings.USE_PAC_URL != myPacUrlCheckBox.isSelected()
        || !Comparing.strEqual(settings.PAC_URL, myPacUrlTextField.getText())
        || settings.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected()
        || settings.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected()
        || settings.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected()
        || settings.PROXY_TYPE_IS_SOCKS != mySocks.isSelected()
        || !Comparing.strEqual(settings.getProxyLogin(), myProxyLoginTextField.getText())
        || !Comparing.strEqual(
            settings.getPlainProxyPassword(), new String(myProxyPasswordTextField.getPassword()))
        || settings.PROXY_PORT != myProxyPortTextField.getNumber()
        || !Comparing.strEqual(settings.PROXY_HOST, myProxyHostTextField.getText());
  }
  @Override
  public void apply(@NotNull HttpConfigurable settings) {
    if (!isValid()) {
      return;
    }

    if (isModified(settings)) {
      settings.AUTHENTICATION_CANCELLED = false;
    }

    settings.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
    settings.USE_PAC_URL = myPacUrlCheckBox.isSelected();
    settings.PAC_URL = getText(myPacUrlTextField);
    settings.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
    settings.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
    settings.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
    settings.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();

    settings.setProxyLogin(getText(myProxyLoginTextField));
    settings.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
    settings.PROXY_EXCEPTIONS = StringUtil.nullize(myProxyExceptions.getText(), true);

    settings.PROXY_PORT = myProxyPortTextField.getNumber();
    settings.PROXY_HOST = getText(myProxyHostTextField);
  }
  private void configureCheckButton() {
    if (HttpConfigurable.getInstance() == null) {
      myCheckButton.setVisible(false);
      return;
    }

    myCheckButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(@NotNull ActionEvent e) {
            final String title = "Check Proxy Settings";
            final String answer =
                Messages.showInputDialog(
                    myMainPanel,
                    "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
                    title,
                    Messages.getQuestionIcon(),
                    "http://",
                    null);
            if (StringUtil.isEmptyOrSpaces(answer)) {
              return;
            }

            final HttpConfigurable settings = HttpConfigurable.getInstance();
            apply(settings);
            final AtomicReference<IOException> exceptionReference = new AtomicReference<>();
            myCheckButton.setEnabled(false);
            myCheckButton.setText("Check connection (in progress...)");
            myConnectionCheckInProgress = true;
            ApplicationManager.getApplication()
                .executeOnPooledThread(
                    () -> {
                      try {
                        // already checked for null above
                        //noinspection ConstantConditions
                        HttpRequests.request(answer).readTimeout(3 * 1000).tryConnect();
                      } catch (IOException e1) {
                        exceptionReference.set(e1);
                      }

                      //noinspection SSBasedInspection
                      SwingUtilities.invokeLater(
                          () -> {
                            myConnectionCheckInProgress = false;
                            reset(settings); // since password might have been set
                            Component parent;
                            if (myMainPanel.isShowing()) {
                              parent = myMainPanel;
                              myCheckButton.setText("Check connection");
                              myCheckButton.setEnabled(canEnableConnectionCheck());
                            } else {
                              IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
                              if (frame == null) {
                                return;
                              }
                              parent = frame.getComponent();
                            }
                            //noinspection ThrowableResultOfMethodCallIgnored
                            final IOException exception = exceptionReference.get();
                            if (exception == null) {
                              Messages.showMessageDialog(
                                  parent,
                                  "Connection successful",
                                  title,
                                  Messages.getInformationIcon());
                            } else {
                              final String message = exception.getMessage();
                              if (settings.USE_HTTP_PROXY) {
                                settings.LAST_ERROR = message;
                              }
                              Messages.showErrorDialog(parent, errorText(message));
                            }
                          });
                    });
          }
        });
  }
  public void apply() {
    HttpConfigurable httpConfigurable = myHttpConfigurable;
    if (isModified()) {
      httpConfigurable.AUTHENTICATION_CANCELLED = false;
    }
    httpConfigurable.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
    httpConfigurable.USE_PAC_URL = myPacUrlCheckBox.isSelected();
    httpConfigurable.PAC_URL = trimFieldText(myPacUrlTextField);
    httpConfigurable.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
    httpConfigurable.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
    httpConfigurable.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
    httpConfigurable.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();

    httpConfigurable.PROXY_LOGIN = trimFieldText(myProxyLoginTextField);
    httpConfigurable.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
    httpConfigurable.PROXY_EXCEPTIONS = myProxyExceptions.getText();

    try {
      httpConfigurable.PROXY_PORT = Integer.valueOf(trimFieldText(myProxyPortTextField)).intValue();
    } catch (NumberFormatException e) {
      httpConfigurable.PROXY_PORT = 80;
    }
    httpConfigurable.PROXY_HOST = trimFieldText(myProxyHostTextField);
  }
  public HTTPProxySettingsPanel(final HttpConfigurable httpConfigurable) {
    final ButtonGroup group = new ButtonGroup();
    group.add(myUseHTTPProxyRb);
    group.add(myAutoDetectProxyRb);
    group.add(myNoProxyRb);
    myNoProxyRb.setSelected(true);

    final ButtonGroup proxyTypeGroup = new ButtonGroup();
    proxyTypeGroup.add(myHTTP);
    proxyTypeGroup.add(mySocks);
    myHTTP.setSelected(true);

    myProxyExceptions.setBorder(UIUtil.getTextFieldBorder());

    final Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY);
    mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property));
    if (Boolean.TRUE.equals(property)) {
      mySystemProxyDefined.setIcon(Messages.getWarningIcon());
      mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD));
      mySystemProxyDefined.setUI(new MultiLineLabelUI());
    }

    myProxyAuthCheckBox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            enableProxyAuthentication(myProxyAuthCheckBox.isSelected());
          }
        });
    myPacUrlCheckBox.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected());
          }
        });

    final ActionListener listener =
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            enableProxy(myUseHTTPProxyRb.isSelected());
          }
        };
    myUseHTTPProxyRb.addActionListener(listener);
    myAutoDetectProxyRb.addActionListener(listener);
    myNoProxyRb.addActionListener(listener);
    myHttpConfigurable = httpConfigurable;

    myClearPasswordsButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            myHttpConfigurable.clearGenericPasswords();
            Messages.showMessageDialog(
                myMainPanel,
                "Proxy passwords were cleared.",
                "Auto-detected proxy",
                Messages.getInformationIcon());
          }
        });

    if (HttpConfigurable.getInstance() != null) {
      myCheckButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              final String title = "Check Proxy Settings";
              final String answer =
                  Messages.showInputDialog(
                      myMainPanel,
                      "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
                      title,
                      Messages.getQuestionIcon(),
                      "http://",
                      null);
              if (!StringUtil.isEmptyOrSpaces(answer)) {
                apply();
                final HttpConfigurable instance = HttpConfigurable.getInstance();
                final AtomicReference<IOException> exc = new AtomicReference<IOException>();
                myCheckButton.setEnabled(false);
                myCheckButton.setText("Check connection (in progress...)");
                myConnectionCheckInProgress = true;
                final Application application = ApplicationManager.getApplication();
                application.executeOnPooledThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        HttpURLConnection connection = null;
                        try {
                          // already checked for null above
                          //noinspection ConstantConditions
                          connection = instance.openHttpConnection(answer);
                          connection.setReadTimeout(3 * 1000);
                          connection.setConnectTimeout(3 * 1000);
                          connection.connect();
                          final int code = connection.getResponseCode();
                          if (HttpURLConnection.HTTP_OK != code) {
                            exc.set(new IOException("Error code: " + code));
                          }
                        } catch (IOException e1) {
                          exc.set(e1);
                        } finally {
                          if (connection != null) {
                            connection.disconnect();
                          }
                        }
                        //noinspection SSBasedInspection
                        SwingUtilities.invokeLater(
                            new Runnable() {
                              @Override
                              public void run() {
                                myConnectionCheckInProgress = false;
                                reset(); // since password might have been set
                                Component parent = null;
                                if (myMainPanel.isShowing()) {
                                  parent = myMainPanel;
                                  myCheckButton.setText("Check connection");
                                  myCheckButton.setEnabled(canEnableConnectionCheck());
                                } else {
                                  final IdeFrame frame =
                                      IdeFocusManager.findInstance().getLastFocusedFrame();
                                  if (frame == null) {
                                    return;
                                  }
                                  parent = frame.getComponent();
                                }
                                //noinspection ThrowableResultOfMethodCallIgnored
                                final IOException exception = exc.get();
                                if (exception == null) {
                                  Messages.showMessageDialog(
                                      parent,
                                      "Connection successful",
                                      title,
                                      Messages.getInformationIcon());
                                } else {
                                  final String message = exception.getMessage();
                                  if (instance.USE_HTTP_PROXY) {
                                    instance.LAST_ERROR = message;
                                  }
                                  Messages.showErrorDialog(parent, errorText(message));
                                }
                              }
                            });
                      }
                    });
              }
            }
          });
    } else {
      myCheckButton.setVisible(false);
    }
  }