private void processChangeDir(@NotNull final String fileName, final boolean writeHistory) {
        Logger.getLogger("test").fine("cd " + fileName);

        final String curDir = fsReader.getWorkingDirectory();
        if (changeDirWorker != null)
            changeDirWorker.cancel(true);

        changeDirWorker = new SwingWorker<Collection<FileInfo>, Void>() {
            private volatile boolean hasChangedDir = false;

            @Override
            protected Collection<FileInfo> doInBackground() throws Exception {
                if (fsReader.changeDirectory(fileName)) {
                    hasChangedDir = true;
                    return fsReader.getDirectoryContents();
                }
                return null;
            }

            @Override
            public void done() {
                if (hasChangedDir)
                    clearCurrentDirFiles();

                try {
                    Collection<FileInfo> result = get();
                    if (result == null) {
                        Logger.getLogger("test").warning("cd failed (false)");
                        return; // do nothing
                    }

                    updateCurrentDirFiles(result);
                } catch (InterruptedException | CancellationException ignored) {
                } catch (ExecutionException e) {
                    Throwable cause = e.getCause();
                    if (cause instanceof UnsupportedDataTypeException) {
                        Logger.getLogger("test").fine("Unsupported: " + cause.getMessage());
                    } else {
                        Logger.getLogger("test").warning("Exception: " + cause.getMessage());
                        e.printStackTrace();
                    }
                }
                finally {
                    if (hasChangedDir) {
                        String newDir = fsReader.getWorkingDirectory();
                        curDirTextField.setText(newDir);
                        if (writeHistory) {
                            browsingHistory.add(newDir);
                            revalidateHistoryButtons();
                        }

                        fileListView.setDirectoryContents(currentDirFiles);
                        fileListView.setSelectedFile(findPreviousDir(curDir, newDir));
                        Logger.getLogger("test").fine("went to: " + newDir);
                    }

                    stopChDirButton.setEnabled(false);
                    stopChDirButton.setBackground(Color.WHITE);
                }
            }
        };

        stopChDirButton.setEnabled(true);
        stopChDirButton.setBackground(Color.RED);
        changeDirWorker.execute();
    }