sources/src/io/github/satr/common/StringUtil.java
@NotNull
public static String getNotEmptyString(String lastSelectedItem) {
    return getNotEmptyString(lastSelectedItem, "");
}
sources/src/io/github/satr/idea/plugin/connector/la/ui/components/JComboBoxToolTipProviderImpl.java
public class JComboBoxToolTipProviderImpl<T> implements JComboBoxToolTipProvider {
    final Object value;
    final String toolTip;
    private T entity;

    public JComboBoxToolTipProviderImpl(Object value, String toolTip) {
        this.value = value;
        this.toolTip = toolTip;
    }

    @Override
    public String getToolTip() {
        return toolTip;
    }

    @Override
    public String toString() {
        return value.toString();
    }

    public JComboBoxToolTipProviderImpl withEntity(T entity) {
        this.entity = entity;
        return this;
    }

    @Override
    public T getEntity() {
        return entity;
    }
}
sources/src/io/github/satr/common/MessageHelper.java
public final class MessageHelper {
    private static final Logger log = Logger.getInstance(MessageHelper.class);
    private static final WindowManager windowManager = WindowManager.getInstance();
    private static final JBPopupFactory jbPopupFactory = JBPopupFactory.getInstance();

    public static void showInfo(final Project project, final String format, final Object... args) {
        showMessage(project, MessageType.INFO, format, args);
    }

    public static void showWarning(final Project project, final String format, final Object... args) {
        showMessage(project, MessageType.WARNING, format, args);
    }

    public static void showError(final Project project, final String format, final Object... args) {
        showMessage(project, MessageType.ERROR, format, args);
    }

    public static void showCriticalError(final Project project, final String format, final Object... args) {
        showMessage(project, MessageType.ERROR, format, args);
        log.error(String.format(format, args));
    }

    public static void showCriticalError(Project project, Throwable t) {
        showError(project, t.getMessage());
        log.error(t);
    }

    private static void showMessage(final Project project, final MessageType messageType, final String format, final Object[] args) {
        StatusBar statusBar = windowManager.getStatusBar(project);
        if(statusBar == null || statusBar.getComponent() == null || isEmpty(format)){
            return;
        }
        String message = String.format(format, args);
        jbPopupFactory.createHtmlTextBalloonBuilder(message, messageType, null)
                    .setFadeoutTime(7500)
                    .createBalloon()
                    .show(RelativePoint.getNorthEastOf(statusBar.getComponent()), Balloon.Position.atRight);

        if(messageType == MessageType.INFO){
            log.info(message);
        }
        else if(messageType == MessageType.WARNING) {
            log.warn(message);
        }
        else{
            log.debug(message);
        }
    }

    public static void showError(Project project, Throwable t) {
        showError(project, t.getMessage());
    }
}
sources/src/io/github/satr/common/DateTimeHelper.java
public final class DateTimeHelper {
    public static String toFormattedString(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
    }

    public static LocalDateTime toLocalDateTime(Long timestamp) {
        return LocalDateTime.ofInstant(new Date(timestamp).toInstant(), ZoneId.systemDefault());
    }
}
sources/src/io/github/satr/idea/plugin/connector/la/ui/components/RegexFormatter.java
public class RegexFormatter extends DefaultFormatter {
    private Pattern pattern;

    public RegexFormatter() {
        super();
    }
    public RegexFormatter(String pattern) {
        this();
        this.pattern = Pattern.compile(pattern);
    }

    public Object stringToValue(String text) throws ParseException {
        if (pattern != null) {
            if (pattern.matcher(text).matches()) {
                return super.stringToValue(text);
            }
            //throw new ParseException("Does not match", 0);
        }
        return text;
    }
}
sources/src/io/github/satr/common/StringUtil.java
public final class StringUtil {
    @NotNull
    public static String getNotEmptyString(String lastSelectedItem) {
        return getNotEmptyString(lastSelectedItem, "");
    }

    @NotNull
    public static String getNotEmptyString(String value, String defaultValue) {
        return isEmpty(value) ? defaultValue : value;
    }

    public static int parseNotZeroInteger(String text, int defaultValue) {
        if(isEmpty(text)){
            return defaultValue;
        }
        int value = Integer.parseInt(text);
        return value == 0 ? defaultValue : value;
    }
}
sources/src/io/github/satr/idea/plugin/connector/la/ui/components/JComboBoxItemToolTipRenderer.java
public class JComboBoxItemToolTipRenderer extends DefaultListCellRenderer {

    private final JComboBox comboBox;

    public JComboBoxItemToolTipRenderer(JComboBox comboBox) {
        this.comboBox = comboBox;
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
                                                  int index, boolean isSelected, boolean cellHasFocus) {
        JComponent component = (JComponent) super.getListCellRendererComponent(list, value, index, isSelected,
                cellHasFocus);
        String toolTipText = null;
        if (value instanceof JComboBoxToolTipProvider) {
            JComboBoxToolTipProvider toolTipProvider = (JComboBoxToolTipProvider) value;
            toolTipText = toolTipProvider.getToolTip();
        }
        list.setToolTipText(toolTipText);
        comboBox.setToolTipText(toolTipText);
        return component;
    }
}
sources/src/io/github/satr/idea/plugin/connector/la/models/ProjectModelImpl.java
public class ProjectModelImpl implements ProjectModel {
    private final String JAR_ARTIFACT_TYPE = "jar";
    private final String PLAIN_ARTIFACT_TYPE = "plain";
    private final Project project;
    private final MavenProjectsManager mavenProjectsManager;

    public ProjectModelImpl(Project project) {
        this.project = project;
        mavenProjectsManager = MavenProjectsManager.getInstance(project);
    }

    @Override
    public List<? extends ArtifactEntity> getArtifacts() {
        if(project == null) {
            return Collections.emptyList();
        }
        final ArrayList<ArtifactEntity> artifactEntries = new ArrayList<>();
        addProjectArtifacts(artifactEntries);
        addMavenProjectArtifacts(artifactEntries);
        return artifactEntries;
    }

    private void addMavenProjectArtifacts(ArrayList<ArtifactEntity> artifactEntries) {
        if (mavenProjectsManager == null || !mavenProjectsManager.isMavenizedProject()) {
            return;
        }
        for(MavenProject mavenProject : mavenProjectsManager.getProjects()) {
            if(!JAR_ARTIFACT_TYPE.equals(mavenProject.getPackaging())){
                continue;
            }
            String artifactName = String.format("%s.%s", mavenProject.getFinalName(), mavenProject.getPackaging());
            String buildDirectory = mavenProject.getBuildDirectory();
            String outputFilePath = Paths.appended(buildDirectory, artifactName);
            artifactEntries.add(new ArtifactEntity(artifactName, outputFilePath, true));
        }
    }

    private void addProjectArtifacts(ArrayList<ArtifactEntity> artifactEntries) {
        final ArtifactManager artifactManager = ArtifactManager.getInstance(this.project);
        collectJarArtifacts(artifactEntries, artifactManager);
        collectArchivesFromPlainArtifacts(artifactEntries, artifactManager);
    }

    private void collectArchivesFromPlainArtifacts(ArrayList<ArtifactEntity> artifactEntries, ArtifactManager artifactManager) {
        Collection<? extends Artifact> artifactsByType = artifactManager.getArtifactsByType(ArtifactType.findById(PLAIN_ARTIFACT_TYPE));
        artifactsByType.stream().forEach(artifact -> addArtifactEntity(artifactEntries, artifact));
    }

    private boolean addArtifactEntity(ArrayList<ArtifactEntity> artifactEntries, Artifact artifact) {
        CompositePackagingElement<?> rootElement = artifact.getRootElement();
        if(rootElement.getType() == PackagingElementFactoryImpl.ARCHIVE_ELEMENT_TYPE) {
            artifactEntries.add(new ArtifactEntity(artifact));            return true;
        }
        for(PackagingElement<?> packagingElement : rootElement.getChildren()) {
            if (packagingElement.getType() != PackagingElementFactoryImpl.ARCHIVE_ELEMENT_TYPE) {
                continue;
            }
            ArchivePackagingElement archivePackagingElement = (ArchivePackagingElement) packagingElement;
            if (archivePackagingElement == null) {
                continue;
            }

            String filePath = Paths.appended(artifact.getOutputFilePath(), archivePackagingElement.getArchiveFileName());
            artifactEntries.add(new ArtifactEntity(packagingElement.toString(), filePath, false));
            return true;
        }
        return true;
    }

    private void collectJarArtifacts(ArrayList<ArtifactEntity> artifactEntries, ArtifactManager artifactManager) {
        artifactManager.getArtifactsByType(ArtifactType.findById(JAR_ARTIFACT_TYPE))
                .stream()
                .forEach(artifact -> artifactEntries.add(new ArtifactEntity(artifact)));
    }
}
sources/src/io/github/satr/common/OperationResult.java
public interface OperationResult {
    void addInfo(String format, Object... args);
    void addWarning(String format, Object... arg);
    void addError(String format, Object... args);
    void addDebug(String format, Object... args);
    boolean failed();
    boolean success();
    boolean hasInfo();
    boolean hasWarnings();
    boolean hasErrors();
    String getDebugAsString();
    String getErrorAsString();
    String getWarningsAsString();
    String getInfoAsString();
}
sources/src/io/github/satr/idea/plugin/connector/la/ui/components/JComboBoxToolTipProvider.java
public interface JComboBoxToolTipProvider<T> {
    String getToolTip();
    T getEntity();
}


Question: import com.amazonaws.SdkClientException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.model.AWSLambdaException;
import com.amazonaws.services.logs.model.InvalidOperationException;
import com.intellij.codeInspection.ui.RegExFormatter;
import com.intellij.compiler.server.BuildManagerListener;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.messages.MessageBusConnection;
import io.github.satr.common.DateTimeHelper;
import io.github.satr.common.MessageHelper;
import io.github.satr.common.OperationResult;
import io.github.satr.common.StringUtil;
import io.github.satr.idea.plugin.connector.la.entities.*;
import io.github.satr.idea.plugin.connector.la.models.ProjectModelImpl;
import io.github.satr.idea.plugin.connector.la.ui.components.JComboBoxItemToolTipRenderer;
import io.github.satr.idea.plugin.connector.la.ui.components.JComboBoxToolTipProvider;
import io.github.satr.idea.plugin.connector.la.ui.components.JComboBoxToolTipProviderImpl;
import io.github.satr.idea.plugin.connector.la.ui.components.RegexFormatter;
import org.apache.log4j.AsyncAppender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import static io.github.satr.common.StringUtil.getNotEmptyString;
import static org.apache.http.util.TextUtils.isEmpty;
        }, "Reformat JSON function test output");
    }

    private void runFunctionTest() {
        if(operationInProgress || runFunctionTestOperationInProgress) {
            return;
        }
        runOperation(() -> {
            runFunctionTestOperationInProgress = true;
            try {
                presenter.runFunctionTest(functionTestInputText.getText(), isAutoFormatFunctionTestOutput());
            } finally {
                runFunctionTestOperationInProgress = false;
            }
        }, "Run test of the function");
    }

    private boolean isAutoFormatFunctionTestOutput() {
        return autoFormatJsonFunctionTestOutputCheckBox.isSelected();
    }

    private void runSetCredentialProfile(ItemEvent e) {
        if(e.getStateChange() != ItemEvent.SELECTED)
            return;
        CredentialProfileEntity entity = (CredentialProfileEntity)e.getItem();
        if(entity == null) {
            return;
        }
        runOperation(() -> presenter.setCredentialProfile(entity), "Select credential profile: " + entity.toString());
    }


    private void updateProxySetting() {
        runOperation(() -> presenter.setProxySettings(), "Update proxy settings from IDEA settings.");
    }

    private void runSetArtifact(ItemEvent e) {
        if(e.getStateChange() != ItemEvent.SELECTED)
            return;
        ArtifactEntity entity = (ArtifactEntity) e.getItem();
        if(entity == null) {
            return;
        }
        runOperation(() -> presenter.setArtifact(entity), "Select artifact: " + entity.toString());
    }

    private void runUpdateFunction() {
        runOperation(() -> presenter.updateFunction(),
                    "Update selected AWS Lambda function with artifact");
    }

    private void clearLocalLog() {
        localLogText.setText("");
    }

    private void clearFunctionTestInput() {
        functionTestInputText.setText("");
    }

    private void clearFunctionTestOutput() {
        functionTestOutputText.setText("");
    }

    private void runDeleteAwsLogStreams() {
        runOperation(() -> presenter.deleteAwsLogStreams(), "Delete AWS log streams.");
    }

    private void runRefreshAll() {
        runOperation(() -> presenter.refreshAll(), "Refresh all");
    }

    private void runRefreshFunctionList() {
        runOperation(() -> presenter.refreshFunctionList(), "Refresh list of AWS Lambda functions");
    }

    private void runRefreshFunctionConfiguration() {
        runOperation(() -> presenter.refreshFunctionConfiguration(), "Refresh AWS Lambda function configuration");
    }

    private void runRefreshArtifactList() {
        runOperation(() -> presenter.refreshArtifactList(), "Refresh list of artifacts in the project");
    }

    private void runInitializeFunctionRoleList() {
        runOperation(() -> {
            if(presenter.initializeFunctionRoleList()) {
                JPopupMenu popupMenu = functionRoles.getComponentPopupMenu();
                if(popupMenu != null) {
                    popupMenu.invalidate();
                }
                functionRoles.hidePopup();
            }
        }, "Initialize function role list");
    }

    private void runRefreshRegionList() {
        runOperation(() -> presenter.refreshRegionList(), "Refresh list of AWS regions");
    }

    private void runRefreshCredentialProfilesList() {
        runOperation(() -> presenter.refreshCredentialProfilesList(), "Refresh list of credential profiles");
    }

    private void runOperation(Runnable runnable, final String format, Object... args) {
        if(operationInProgress) {
            return;
        }
        try {
            operationInProgress = true;
            setControlsEnabled(false);
            final String title = String.format(format, args);
            progressManager.run(new Task.Backgroundable(project, title, true) {
                @Override
                public void run(@NotNull ProgressIndicator progressIndicator) {
                    try {
                        logDebug(title);
                        runnable.run();
                    } catch (Throwable t) {
                        Class<? extends Throwable> exceptionClass = t.getClass();
                        if(exceptionClass.equals(AWSLambdaException.class)){
Answer:                             MessageHelper.showError(project, t.getMessage());