diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
index 2232085c5bb2724c28d5a72a855528456192319a..9a711047a8b714f0d7ad7c5480aa13480bb77902 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
@@ -108,11 +108,11 @@ AddImageWizardIterator.stepXofN=Step {0} of {1}
 AddLocalFilesTask.localFileAdd.progress.text=Adding\: {0}/{1}
 Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\!
 Case.create.exception.msg=Error creating a case\: {0} in dir {1}
-Case.databaseConnectionInfo.error.msg=Error accessing case database connection info
+Case.databaseConnectionInfo.error.msg=Error accessing database server connection info. See Tools, Options, Multi-user.
 Case.open.exception.blankCase.msg=Case name is blank.
 Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made\:\n {0}
 Case.open.msgDlg.updated.title=Case Database Schema Update
-Case.open.exception.checkFile.msg=Check that you selected the correct case file (usually with {0} extension)
+Case.open.exception.checkFile.msg=Case file must have {0} extension.
 Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-user.
 Case.checkImgExist.confDlg.doesntExist.msg={0} has detected that one of the images associated with \n\
 this case are missing. Would you like to search for them now?\n\
@@ -139,6 +139,9 @@ Case.createCaseDir.exception.gen=Could not create case directory\: {0}
 Case.CollaborationSetup.FailNotify.ErrMsg=Failed to connect to any other nodes that may be collaborating on this case.
 Case.CollaborationSetup.FailNotify.Title=Connection Failure
 Case.GetCaseTypeGivenPath.Failure=Unable to get case type
+Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted.
+Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
+Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
 CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\
      Case Name\: {0}\n\
      Case Directory\: {1}
@@ -208,14 +211,11 @@ NewCaseWizardPanel1.validate.errMsg.cantCreateDir=Error\: Could not create direc
 NewCaseWizardPanel1.validate.errMsg.invalidBaseDir.msg=ERROR\: The Base Directory that you entered is not valid.\nPlease enter a valid Base Directory.
 NewCaseWizardPanel1.createDir.errMsg.cantCreateDir.msg=ERROR\: Could not create the case directory. \nPlease enter a valid Case Name and Directory.
 NewCaseWizardPanel2.validate.errCreateCase.msg=Error creating case
-OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg=Error\: Case {0} does not exist.
-OpenRecentCasePanel.openCase.msgDlg.err=Error
 OpenRecentCasePanel.colName.caseName=Case Name
 OpenRecentCasePanel.colName.path=Path
 RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of range.
 RecentCases.getName.text=Clear Recent Cases
-RecentItems.openRecentCase.msgDlg.text=Error\: Case {0} does not exist.
-RecentItems.openRecentCase.msgDlg.err=Error
+RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists.
 StartupWindow.title.text=Welcome
 UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases
 UpdateRecentCases.menuItem.empty=-Empty-
@@ -240,17 +240,14 @@ NewCaseVisualPanel1.caseParentDirWarningLabel.text=
 NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-user		
 NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-user
 NewCaseVisualPanel1.caseTypeLabel.text=Case Type: 
-Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
-Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}
 CasePropertiesForm.lbDbType.text=Case Type:
 CasePropertiesForm.tbDbType.text=
 CasePropertiesForm.lbDbName.text=Database Name:
 CasePropertiesForm.tbDbName.text=
-CaseExceptionWarning.CheckMultiUserOptions=Check Multi-user options.
 SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist!
 SingleUserCaseConverter.AlreadyMultiUser=Case is already multi-user!
 SingleUserCaseConverter.NonUniqueDatabaseName=Database name not unique.
 SingleUserCaseConverter.UnableToCopySourceImages=Unable to copy source images
 SingleUserCaseConverter.CanNotOpenDatabase=Unable to open database
 CloseCaseWhileIngesting.Warning=Ingest is running. Are you sure you want to close the case?
-CloseCaseWhileIngesting.Warning.title=Warning\: This will close the current case
+CloseCaseWhileIngesting.Warning.title=Warning\: This will close the current case
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
index 6895817f35325e24e3e90b03e9e6f7cbdd613194..e61c8bf1cb9b9865480159be847acebcaae6111f 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle_ja.properties
@@ -192,14 +192,11 @@ NewCaseWizardPanel1.validate.errMsg.cantCreateDir=\u30a8\u30e9\u30fc\uff1a\u30c7
 NewCaseWizardPanel1.validate.errMsg.invalidBaseDir.msg=\u30a8\u30e9\u30fc\uff1a\u5165\u529b\u3057\u305f\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306f\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\n\u6709\u52b9\u306a\u30d9\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u5165\u529b\u3057\u3066\u4e0b\u3055\u3044\u3002
 NewCaseWizardPanel1.createDir.errMsg.cantCreateDir.msg=\u30a8\u30e9\u30fc\uff1a\u30b1\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\n\u6709\u52b9\u306a\u30b1\u30fc\u30b9\u540d\u304a\u3088\u3073\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u5165\u529b\u3057\u3066\u4e0b\u3055\u3044\u3002
 NewCaseWizardPanel2.validate.errCreateCase.msg=\u30b1\u30fc\u30b9\u4f5c\u6210\u30a8\u30e9\u30fc
-OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg=\u30a8\u30e9\u30fc\uff1a\u30b1\u30fc\u30b9{0}\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
-OpenRecentCasePanel.openCase.msgDlg.err=\u30a8\u30e9\u30fc
 OpenRecentCasePanel.colName.caseName=\u30b1\u30fc\u30b9\u540d
 OpenRecentCasePanel.colName.path=\u30d1\u30b9
 RecentCases.exception.caseIdxOutOfRange.msg=\u6700\u8fd1\u306e\u30b1\u30fc\u30b9\u30a4\u30f3\u30c7\u30c3\u30af\u30b9{0}\u306f\u7bc4\u56f2\u5916\u3067\u3059\u3002
 RecentCases.getName.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u30af\u30ea\u30a2
 RecentItems.openRecentCase.msgDlg.text=\u30a8\u30e9\u30fc\uff1a\u30b1\u30fc\u30b9{0}\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002
-RecentItems.openRecentCase.msgDlg.err=\u30a8\u30e9\u30fc
 StartupWindow.title.text=\u3088\u3046\u3053\u305d
 UpdateRecentCases.menuItem.clearRecentCases.text=\u6700\u8fd1\u958b\u3044\u305f\u30b1\u30fc\u30b9\u3092\u30af\u30ea\u30a2
 UpdateRecentCases.menuItem.empty=-\u7a7a\u767d-
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index fbf53a99fc131d588696b61a0c67330a96af0f0b..b9d67f8746ddd0e3573e8b33eaec97d993721029 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -384,7 +384,8 @@ private static void changeCase(Case newCase) {
 
     @Override
     public void receiveError(String context, String errorMessage) {
-        /* NOTE: We are accessing tskErrorReporter from two different threads.
+        /*
+         * NOTE: We are accessing tskErrorReporter from two different threads.
          * This is ok as long as we only read the value of tskErrorReporter
          * because tskErrorReporter is declared as volatile.
          */
@@ -398,63 +399,87 @@ AddImageProcess makeAddImageProcess(String timezone, boolean processUnallocSpace
     }
 
     /**
-     * Creates a new case (create the XML config file and database). Overload
-     * for API consistency, defaults to a single-user case.
+     * Creates a single-user new case.
      *
-     * @param caseDir    The directory to store case data in. Will be created if
-     *                   it doesn't already exist. If it exists, it should have
-     *                   all of the needed sub dirs that createCaseDirectory()
-     *                   will create.
-     * @param caseName   the name of case
-     * @param caseNumber the case number
-     * @param examiner   the examiner for this case
+     * @param caseDir    The full path of the case directory. It will be created
+     *                   if it doesn't already exist; if it exists, it should
+     *                   have been created using Case.createCaseDirectory() to
+     *                   ensure that the required sub-directories aere created.
+     * @param caseName   The name of case.
+     * @param caseNumber The case number, can be the empty string.
+     * @param examiner   The examiner to associate with the case, can be the
+     *                   empty string.
      *
-     * @throws org.sleuthkit.autopsy.casemodule.CaseActionException
+     * @throws CaseActionException if there is a problem creating the case. The
+     *                             exception will have a user-friendly message
+     *                             and may be a wrapper for a lower-level
+     *                             exception. If so,
+     *                             CaseActionException.getCause will return a
+     *                             Throwable (null otherwise).
      */
     public static void create(String caseDir, String caseName, String caseNumber, String examiner) throws CaseActionException {
         create(caseDir, caseName, caseNumber, examiner, CaseType.SINGLE_USER_CASE);
     }
 
     /**
-     * Creates a new case (create the XML config file and database)
+     * Creates a new case.
      *
-     * @param caseDir    The directory to store case data in. Will be created if
-     *                   it doesn't already exist. If it exists, it should have
-     *                   all of the needed sub dirs that createCaseDirectory()
-     *                   will create.
-     * @param caseName   the name of case
-     * @param caseNumber the case number
-     * @param examiner   the examiner for this case
-     * @param caseType   the type of case, single-user or multi-user
+     * @param caseDir    The full path of the case directory. It will be created
+     *                   if it doesn't already exist; if it exists, it should
+     *                   have been created using Case.createCaseDirectory() to
+     *                   ensure that the required sub-directories aere created.
+     * @param caseName   The name of case.
+     * @param caseNumber The case number, can be the empty string.
+     * @param examiner   The examiner to associate with the case, can be the
+     *                   empty string.
+     * @param caseType   The type of case (single-user or multi-user). The
+     *                   exception will have a user-friendly message and may be
+     *                   a wrapper for a lower-level exception. If so,
+     *                   CaseActionException.getCause will return a Throwable
+     *                   (null otherwise).
+     *
+     * @throws CaseActionException if there is a problem creating the case.
      */
     public static void create(String caseDir, String caseName, String caseNumber, String examiner, CaseType caseType) throws CaseActionException {
-        logger.log(Level.INFO, "Creating new case.\ncaseDir: {0}\ncaseName: {1}", new Object[]{caseDir, caseName}); //NON-NLS
+        logger.log(Level.INFO, "Creating case with case directory {0}, caseName {1}", new Object[]{caseDir, caseName}); //NON-NLS
 
-        // create case directory if it doesn't already exist.
+        /*
+         * Create case directory if it doesn't already exist.
+         */
         if (new File(caseDir).exists() == false) {
             Case.createCaseDirectory(caseDir, caseType);
         }
 
-        String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION;
-
-        XMLCaseManagement xmlcm = new XMLCaseManagement();
-
+        /*
+         * Sanitize the case name, create a unique keyword search index name,
+         * and create a standard (single-user) or unique (multi-user) case
+         * database name.
+         */
+        String santizedCaseName = sanitizeCaseName(caseName);
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
         Date date = new Date();
-        String santizedCaseName = sanitizeCaseName(caseName);
         String indexName = santizedCaseName + "_" + dateFormat.format(date);
         String dbName = null;
-
-        // figure out the database name and index name for text extraction
         if (caseType == CaseType.SINGLE_USER_CASE) {
             dbName = caseDir + File.separator + "autopsy.db"; //NON-NLS
         } else if (caseType == CaseType.MULTI_USER_CASE) {
             dbName = indexName;
         }
 
-        xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName); // create a new XML config file
+        /*
+         * Create the case metadata (.aut) file.
+         *
+         * TODO (AUT-1885): Replace use of obsolete and unsafe XMLCaseManagement
+         * class with use of CaseMetadata class.
+         */
+        String configFilePath = caseDir + File.separator + caseName + CASE_DOT_EXTENSION;
+        XMLCaseManagement xmlcm = new XMLCaseManagement();
+        xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName);
         xmlcm.writeFile();
 
+        /*
+         * Create the case database.
+         */
         SleuthkitCase db = null;
         try {
             if (caseType == CaseType.SINGLE_USER_CASE) {
@@ -463,24 +488,23 @@ public static void create(String caseDir, String caseName, String caseNumber, St
                 db = SleuthkitCase.newCase(dbName, UserPreferences.getDatabaseConnectionInfo(), caseDir);
             }
         } catch (TskCoreException ex) {
-            logger.log(Level.SEVERE, "Error creating a case: " + caseName + " in dir " + caseDir + " " + ex.getMessage(), ex); //NON-NLS
+            logger.log(Level.SEVERE, String.format("Error creating a case %s in %s ", caseName, caseDir), ex); //NON-NLS
             SwingUtilities.invokeLater(() -> {
                 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
             });
+            /*
+             * SleuthkitCase.newCase throws TskCoreExceptions with user-friendly
+             * messages, so propagate the exception message.
+             */
             throw new CaseActionException(ex.getMessage(), ex); //NON-NLS
         } catch (UserPreferencesException ex) {
             logger.log(Level.SEVERE, "Error accessing case database connection info", ex); //NON-NLS
             SwingUtilities.invokeLater(() -> {
                 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
             });
-            throw new CaseActionException(
-                    NbBundle.getMessage(Case.class, "Case.databaseConnectionInfo.error.msg"), ex);
+            throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.databaseConnectionInfo.error.msg"), ex);
         }
 
-        /**
-         * Two-stage initialization to avoid leaking reference to "this" in
-         * constructor.
-         */
         Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
         changeCase(newCase);
     }
@@ -549,20 +573,28 @@ static String sanitizeCaseName(String caseName) {
     /**
      * Opens an existing case.
      *
-     * @param caseMetadataFilePath The path of the case metadata file for the
-     *                             case to be opened.
+     * @param caseMetadataFilePath The path of the case metadata file.
      *
-     * @throws CaseActionException
+     * @throws CaseActionException if there is a problem opening the case. The
+     *                             exception will have a user-friendly message
+     *                             and may be a wrapper for a lower-level
+     *                             exception. If so,
+     *                             CaseActionException.getCause will return a
+     *                             Throwable (null otherwise).
      */
     public static void open(String caseMetadataFilePath) throws CaseActionException {
+        logger.log(Level.INFO, "Opening case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
+
+        /*
+         * Verify the extension of the case metadata file.
+         */
         if (!caseMetadataFilePath.endsWith(CASE_DOT_EXTENSION)) {
             throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.checkFile.msg", CASE_DOT_EXTENSION));
         }
 
-        logger.log(Level.INFO, "Opening case, case metadata file path: {0}", caseMetadataFilePath); //NON-NLS
         try {
-            /**
-             * Get the case metadata from the file.
+            /*
+             * Get the case metadata required to open the case database.
              */
             CaseMetadata metadata = new CaseMetadata(Paths.get(caseMetadataFilePath));
             String caseName = metadata.getCaseName();
@@ -571,7 +603,7 @@ public static void open(String caseMetadataFilePath) throws CaseActionException
             CaseType caseType = metadata.getCaseType();
             String caseDir = metadata.getCaseDirectory();
 
-            /**
+            /*
              * Open the case database.
              */
             SleuthkitCase db;
@@ -585,40 +617,57 @@ public static void open(String caseMetadataFilePath) throws CaseActionException
                 try {
                     db = SleuthkitCase.openCase(metadata.getCaseDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), caseDir);
                 } catch (UserPreferencesException ex) {
-                    logger.log(Level.SEVERE, "Error accessing case database connection info", ex); //NON-NLS
                     throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.databaseConnectionInfo.error.msg"), ex);
                 }
             }
 
-            /**
-             * Do things that require a UI.
+            /*
+             * Check for the presence of the UI and do things that can only be
+             * done with user interaction.
              */
             if (RuntimeProperties.coreComponentsAreActive()) {
-                /**
+                /*
                  * If the case database was upgraded for a new schema, notify
                  * the user.
                  */
                 if (null != db.getBackupDatabasePath()) {
                     SwingUtilities.invokeLater(() -> {
-                        JOptionPane.showMessageDialog(null,
-                                NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg",
-                                        db.getBackupDatabasePath()),
+                        JOptionPane.showMessageDialog(
+                                WindowManager.getDefault().getMainWindow(),
+                                NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg", db.getBackupDatabasePath()),
                                 NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
                                 JOptionPane.INFORMATION_MESSAGE);
                     });
                 }
 
-                /**
-                 * TODO: This currently has no value if it there is no user to
-                 * interact with a fid missing images dialog.
+                /*
+                 * Look for the files for the data sources listed in the case
+                 * database and give the user the opportunity to locate any that
+                 * are missing.
                  */
-                checkImagesExist(db);
+                Map<Long, String> imgPaths = getImagePaths(db);
+                for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
+                    long obj_id = entry.getKey();
+                    String path = entry.getValue();
+                    boolean fileExists = (pathExists(path) || driveExists(path));
+                    if (!fileExists) {
+                        int ret = JOptionPane.showConfirmDialog(
+                                WindowManager.getDefault().getMainWindow(),
+                                NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", getAppName(), path),
+                                NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"),
+                                JOptionPane.YES_NO_OPTION);
+                        if (ret == JOptionPane.YES_OPTION) {
+                            MissingImageDialog.makeDialog(obj_id, db);
+                        } else {
+                            logger.log(Level.WARNING, "Selected image files don't match old files!"); //NON-NLS
+                        }
+                    }
+                }
             }
 
-            /**
-             * Two-stage initialization to avoid leaking reference to "this" in
-             * constructor. TODO: Remove use of obsolete XMLCaseManagement
-             * class.
+            /*
+             * TODO (AUT-1885): Replace use of obsolete and unsafe
+             * XMLCaseManagement class with use of CaseMetadata class.
              */
             XMLCaseManagement xmlcm = new XMLCaseManagement();
             xmlcm.open(caseMetadataFilePath);
@@ -626,28 +675,16 @@ public static void open(String caseMetadataFilePath) throws CaseActionException
             changeCase(openedCase);
 
         } catch (CaseMetadataException ex) {
-            /**
-             * Attempt clean up.
-             */
-            try {
-                Case badCase = Case.getCurrentCase();
-                badCase.closeCase();
-            } catch (IllegalStateException ignored) {
-            }
-            throw new CaseActionException(ex.getMessage(), ex); //NON-NLS
+            throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.metaDataFileCorrupt.exception.msg"), ex); //NON-NLS
         } catch (TskCoreException ex) {
-            /**
-             * Attempt clean up.
-             */
-            try {
-                Case badCase = Case.getCurrentCase();
-                badCase.closeCase();
-            } catch (IllegalStateException ignored) {
-            }
             SwingUtilities.invokeLater(() -> {
                 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
             });
-            throw new CaseActionException(ex.getMessage(), ex); //NON-NLS
+            /*
+             * SleuthkitCase.openCase throws TskCoreExceptions with
+             * user-friendly messages, so propagate the exception message.
+             */
+            throw new CaseActionException(ex.getMessage(), ex);
         }
     }
 
@@ -666,35 +703,6 @@ static Map<Long, String> getImagePaths(SleuthkitCase db) { //TODO: clean this up
         return imgPaths;
     }
 
-    /**
-     * Ensure that all image paths point to valid image files
-     */
-    private static void checkImagesExist(SleuthkitCase db) {
-        Map<Long, String> imgPaths = getImagePaths(db);
-        for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
-            long obj_id = entry.getKey();
-            String path = entry.getValue();
-            boolean fileExists = (pathExists(path) || driveExists(path));
-            if (!fileExists) {
-                int ret = JOptionPane.showConfirmDialog(null,
-                        NbBundle.getMessage(Case.class,
-                                "Case.checkImgExist.confDlg.doesntExist.msg",
-                                getAppName(), path),
-                        NbBundle.getMessage(Case.class,
-                                "Case.checkImgExist.confDlg.doesntExist.title"),
-                        JOptionPane.YES_NO_OPTION);
-                if (ret == JOptionPane.YES_OPTION) {
-
-                    MissingImageDialog.makeDialog(obj_id, db);
-
-                } else {
-                    logger.log(Level.WARNING, "Selected image files don't match old files!"); //NON-NLS
-                }
-
-            }
-        }
-    }
-
     /**
      * Adds the image to the current case after it has been added to the DB.
      * Sends out event and reopens windows if needed.
@@ -1585,10 +1593,10 @@ private static void doCaseChange(Case toChangeTo) {
 
             if (RuntimeProperties.coreComponentsAreActive()) {
                 // enable these menus
-                    CallableSystemAction.get(AddImageAction.class).setEnabled(true);
-                    CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
-                    CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
-                    CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
+                CallableSystemAction.get(AddImageAction.class).setEnabled(true);
+                CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
+                CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
+                CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
 
                 if (toChangeTo.hasData()) {
                     // open all top components
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
index 5ea268adf47f42def8cff64568a1c953ee415167..f879393558e772ebacaa9a13b2f41a4b65382d17 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
@@ -65,7 +65,7 @@ public CaseOpenAction() {
     }
 
     /**
-     * Pops up a file chooser to allow the user to select a case meta data file
+     * Pops up a file chooser to allow the user to select a case metadata file
      * (.aut file) and attempts to open the case described by the file.
      *
      * @param e The action event.
@@ -73,21 +73,28 @@ public CaseOpenAction() {
     @Override
     public void actionPerformed(ActionEvent e) {
         /*
-         * If ingest is running, do a dialog to warn the user and confirm
-         * abandoning the ingest.
+         * If ingest is running, do a dialog to warn the user and confirm the
+         * intent to close the current case and leave the ingest process
+         * incomplete.
          */
         if (IngestManager.getInstance().isIngestRunning()) {
-            String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning");
-            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(closeCurrentCase,
+            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
+                    NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
                     NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
                     NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
             descriptor.setValue(NotifyDescriptor.NO_OPTION);
             Object res = DialogDisplayer.getDefault().notify(descriptor);
             if (res != null && res == DialogDescriptor.YES_OPTION) {
+                Case currentCase = null;
                 try {
-                    Case.getCurrentCase().closeCase();
-                } catch (Exception ex) {
-                    logger.log(Level.SEVERE, "Error closing case", ex); //NON-NLS
+                    currentCase = Case.getCurrentCase();
+                    currentCase.closeCase();
+                } catch (IllegalStateException ignored) {
+                    /*
+                     * No current case.
+                     */
+                } catch (CaseActionException ex) {
+                    logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null != currentCase ? currentCase.getCaseDirectory() : "?")), ex); //NON-NLS
                 }
             } else {
                 return;
@@ -100,17 +107,13 @@ public void actionPerformed(ActionEvent e) {
          */
         int retval = fileChooser.showOpenDialog(WindowManager.getDefault().getMainWindow());
         if (retval == JFileChooser.APPROVE_OPTION) {
-            /**
-             * This is a bit of a hack, but close the startup window, if it was
-             * the source of the action invocation.
+            /*
+             * Close the startup window, if it is open.
              */
-            try {
-                StartupWindowProvider.getInstance().close();
-            } catch (Exception unused) {
-            }
+            StartupWindowProvider.getInstance().close();
 
-            /**
-             * Try to open the case associated with the case meta data file the
+            /*
+             * Try to open the case associated with the case metadata file the
              * user selected.
              */
             final String path = fileChooser.getSelectedFile().getPath();
@@ -121,12 +124,14 @@ public void actionPerformed(ActionEvent e) {
                 try {
                     Case.open(path);
                 } catch (CaseActionException ex) {
-                    logger.log(Level.SEVERE, String.format("Could not open case at %s", path), ex);
+                    logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", path), ex); //NON-NLS
                     SwingUtilities.invokeLater(() -> {
                         WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-                        JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), 
-                                ex.getMessage(),
-                                NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), JOptionPane.ERROR_MESSAGE); //NON-NLS
+                        JOptionPane.showMessageDialog(
+                                WindowManager.getDefault().getMainWindow(),
+                                ex.getMessage(), // Should be user-friendly
+                                NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
+                                JOptionPane.ERROR_MESSAGE); 
                         if (!Case.isCaseOpen()) {
                             StartupWindowProvider.getInstance().open();
                         }
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
index 9b6c29a7c5696bc12bedc3de8b9b5320f8af148e..39f831c5a188b4be6ca8cb3aaa8a1600ae97dc34 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
@@ -39,10 +39,11 @@
 import org.sleuthkit.autopsy.casemodule.Case.CaseType;
 import org.openide.windows.WindowManager;
 import java.awt.Cursor;
+import java.util.concurrent.ExecutionException;
 import org.sleuthkit.autopsy.ingest.IngestManager;
 
 /**
- * An action that runs the new case wizard.
+ * An action that creates and runs the new case wizard.
  */
 final class NewCaseWizardAction extends CallableSystemAction {
 
@@ -53,32 +54,39 @@ final class NewCaseWizardAction extends CallableSystemAction {
     @Override
     public void performAction() {
         /*
-         * If ingest is running, do a dialog to warn the user and confirm
-         * abandoning the ingest.
+         * If ingest is running, do a dialog to warn the user and confirm the
+         * intent to close the current case and leave the ingest process
+         * incomplete.
          */
         if (IngestManager.getInstance().isIngestRunning()) {
-            String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning");
-            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(closeCurrentCase,
+            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
+                    NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
                     NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
                     NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
             descriptor.setValue(NotifyDescriptor.NO_OPTION);
             Object res = DialogDisplayer.getDefault().notify(descriptor);
             if (res != null && res == DialogDescriptor.YES_OPTION) {
+                Case currentCase = null;
                 try {
-                    Case.getCurrentCase().closeCase();
-                } catch (Exception ex) {
-                    Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.WARNING, "Error closing case", ex); //NON-NLS
+                    currentCase = Case.getCurrentCase();
+                    currentCase.closeCase();
+                } catch (IllegalStateException ignored) {
+                    /*
+                     * No current case.
+                     */
+                } catch (CaseActionException ex) {
+                    logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null != currentCase ? currentCase.getCaseDirectory() : "?")), ex); //NON-NLS
                 }
             } else {
                 return;
             }
         }
         WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-        newCaseAction();
+        runNewCaseWizard();
     }
 
-    private void newCaseAction() {
-        final WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
+    private void runNewCaseWizard() {
+        final WizardDescriptor wizardDescriptor = new WizardDescriptor(getNewCaseWizardPanels());
         wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
         wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
         Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
@@ -104,21 +112,14 @@ protected void done() {
                         AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
                         addImageAction.actionPerformed(null);
                     } catch (Exception ex) {
-                        logger.log(Level.SEVERE, "Error creating case", ex); //NON-NLS
+                        logger.log(Level.SEVERE, String.format("Error creating case %s", wizardDescriptor.getProperty("caseName")), ex); //NON-NLS                                                
                         SwingUtilities.invokeLater(() -> {
-                            JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), ex.getCause().getMessage() + " "
-                                    + NbBundle.getMessage(this.getClass(), "CaseExceptionWarning.CheckMultiUserOptions"),
-                                    NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"),
-                                    JOptionPane.ERROR_MESSAGE); //NON-NLS
-                            /**
-                             * This is a bit of a hack, but close the startup
-                             * window, if it was the source of the action
-                             * invocation.
-                             */
-                            try {
-                                StartupWindowProvider.getInstance().close();
-                            } catch (Exception unused) {
-                            }
+                            JOptionPane.showMessageDialog(
+                                    WindowManager.getDefault().getMainWindow(),
+                                    (ex instanceof ExecutionException ? ex.getCause().getMessage() : ex.getMessage()),
+                                    NbBundle.getMessage(this.getClass(), "CaseCreateAction.msgDlg.cantCreateCase.msg"), //NON-NLS
+                                    JOptionPane.ERROR_MESSAGE);
+                            StartupWindowProvider.getInstance().close(); // RC: Why close and open?
                             if (!Case.isCaseOpen()) {
                                 StartupWindowProvider.getInstance().open();
                             }
@@ -137,7 +138,6 @@ protected void done() {
     private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor) {
         String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
         if (createdDirectory != null) {
-            logger.log(Level.INFO, "Deleting a created case directory due to an error, dir: {0}", createdDirectory); //NON-NLS
             Case.deleteCaseDirectory(new File(createdDirectory));
         }
         SwingUtilities.invokeLater(() -> {
@@ -146,10 +146,10 @@ private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor) {
     }
 
     /**
-     * Initializes the new case wizard panels.
+     * Creates the new case wizard panels.
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    private WizardDescriptor.Panel<WizardDescriptor>[] getPanels() {
+    private WizardDescriptor.Panel<WizardDescriptor>[] getNewCaseWizardPanels() {
         if (panels == null) {
             panels = new WizardDescriptor.Panel[]{
                 new NewCaseWizardPanel1(),
@@ -180,21 +180,33 @@ private WizardDescriptor.Panel<WizardDescriptor>[] getPanels() {
         return panels;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public String getName() {
         return NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.getName.text");
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public String iconResource() {
         return null;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
 
+    /**
+     * @inheritDoc
+     */
     @Override
     protected boolean asynchronous() {
         return false;
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java
index 6a0c0742eb7cc1dfa8105b963b4cd771bf0dbcf7..07706cc798d05e9a40d449c1130329a6df328c5f 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java
@@ -43,31 +43,39 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
     private static String[] casePaths;
     private RecentCasesTableModel model;
 
+    /**
+     * Constructs a panel used by the the open recent case option of the start
+     * window.
+     */
     private OpenRecentCasePanel() {
         initComponents();
     }
 
+    /*
+     * Gets the singleton instance of the panel used by the the open recent case
+     * option of the start window.
+     */
     static OpenRecentCasePanel getInstance() {
         if (instance == null) {
             instance = new OpenRecentCasePanel();
         }
-        instance.generateRecentCases(); // refresh the case list
+        instance.refreshRecentCasesTable();
         return instance;
     }
 
     /**
-     * Sets the Close button action listener.
+     * Adds an action listener to the cancel button.
      *
-     * @param e the action listener
+     * @param listener An action listener.
      */
-    public void setCloseButtonActionListener(ActionListener e) {
-        this.cancelButton.addActionListener(e);
+    void setCloseButtonActionListener(ActionListener listener) {
+        this.cancelButton.addActionListener(listener);
     }
-    
+
     /**
      * Retrieves all the recent cases and adds them to the table.
      */
-    private void generateRecentCases() {
+    private void refreshRecentCasesTable() {
         caseNames = RecentCases.getInstance().getRecentCaseNames();
         casePaths = RecentCases.getInstance().getRecentCasePaths();
         model = new RecentCasesTableModel();
@@ -85,8 +93,10 @@ private void generateRecentCases() {
             openButton.setEnabled(false);
         }
     }
-    
-    // Open the selected case
+
+    /*
+     * Opens the selected case.
+     */
     private void openCase() {
         if (casePaths.length < 1) {
             return;
@@ -102,7 +112,7 @@ private void openCase() {
             }
 
             /*
-             * Verify the case name and metadata file path.
+             * Open the case.
              */
             if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
                 JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
@@ -110,14 +120,9 @@ private void openCase() {
                         NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
                         JOptionPane.ERROR_MESSAGE);
                 RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
-
-                /*
-                 * If a case was not already open, pop up the start window.
-                 */
                 if (Case.isCaseOpen() == false) {
                     StartupWindowProvider.getInstance().open();
                 }
-
             } else {
                 SwingUtilities.invokeLater(() -> {
                     WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
@@ -131,12 +136,9 @@ private void openCase() {
                             WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                             JOptionPane.showMessageDialog(
                                     WindowManager.getDefault().getMainWindow(),
-                                    ex.getMessage(),
-                                    NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), JOptionPane.ERROR_MESSAGE); //NON-NLS
-                            /*
-                             * If a case was not already open, pop up the start
-                             * window.
-                             */
+                                    ex.getMessage(), // Should be user-friendly
+                                    NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
+                                    JOptionPane.ERROR_MESSAGE); 
                             if (!Case.isCaseOpen()) {
                                 StartupWindowProvider.getInstance().open();
                             }
@@ -154,6 +156,9 @@ private class RecentCasesTableModel extends AbstractTableModel {
 
         private static final long serialVersionUID = 1L;
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public int getRowCount() {
             int count = 0;
@@ -165,11 +170,17 @@ public int getRowCount() {
             return count;
         }
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public int getColumnCount() {
             return 2;
         }
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public String getColumnName(int column) {
             String colName = null;
@@ -186,6 +197,9 @@ public String getColumnName(int column) {
             return colName;
         }
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public Object getValueAt(int rowIndex, int columnIndex) {
             Object ret = null;
@@ -203,15 +217,28 @@ public Object getValueAt(int rowIndex, int columnIndex) {
             return ret;
         }
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public boolean isCellEditable(int rowIndex, int columnIndex) {
             return false;
         }
 
+        /**
+         * @inheritDoc
+         */
         @Override
         public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
         }
 
+        /**
+         * Shortens a path to fit the display.
+         *
+         * @param path The path to shorten.
+         *
+         * @return The shortened path.
+         */
         private String shortenPath(String path) {
             String shortenedPath = path;
             if (shortenedPath.length() > 50) {
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java b/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java
index 8e9c989d5ac53e70c4a793ef9eb941b373cb2095..2df4401ad9f7da16b22c74fae2455f340843a76d 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/RecentItems.java
@@ -1,7 +1,7 @@
 /*
  * Autopsy Forensic Browser
  *
- * Copyright 2011-2015 Basis Technology Corp.
+ * Copyright 2011-2016 Basis Technology Corp.
  * Contact: carrier <at> sleuthkit <dot> org
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,6 @@
 import java.awt.event.ActionListener;
 import java.io.File;
 import javax.swing.JOptionPane;
-import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 import org.openide.util.NbBundle;
 import org.openide.windows.WindowManager;
@@ -36,21 +35,23 @@
 import org.sleuthkit.autopsy.ingest.IngestManager;
 
 /**
- * This class is used to add the action to the recent case menu item. When the
- * the recent case menu is pressed, it should open that selected case.
+ * An action listener that opens a recent case.
  */
 class RecentItems implements ActionListener {
 
-    final String caseName;
-    final String casePath;
-    private JPanel caller; // for error handling
+    private static final Logger logger = Logger.getLogger(RecentItems.class.getName());
+    private final String caseName;
+    private final String caseMetaDataFilePath;
 
     /**
-     * the constructor
+     * Constructs an action listener that opens a recent case.
+     *
+     * @param caseName             The name of the case.
+     * @param caseMetaDataFilePath The path to the case metadata file.
      */
-    public RecentItems(String caseName, String casePath) {
+    public RecentItems(String caseName, String caseMetaDataFilePath) {
         this.caseName = caseName;
-        this.casePath = casePath;
+        this.caseMetaDataFilePath = caseMetaDataFilePath;
     }
 
     /**
@@ -60,58 +61,65 @@ public RecentItems(String caseName, String casePath) {
      */
     @Override
     public void actionPerformed(ActionEvent e) {
-
-        // if ingest is ongoing, warn and get confirmaion before opening a different case
+        /*
+         * If ingest is running, do a dialog to warn the user and confirm the
+         * intent to close the current case and leave the ingest process
+         * incomplete.
+         */
         if (IngestManager.getInstance().isIngestRunning()) {
-            // show the confirmation first to close the current case and open the "New Case" wizard panel
-            String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning");
-            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(closeCurrentCase,
+            NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(
+                    NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning"),
                     NbBundle.getMessage(this.getClass(), "CloseCaseWhileIngesting.Warning.title"),
                     NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
             descriptor.setValue(NotifyDescriptor.NO_OPTION);
-
             Object res = DialogDisplayer.getDefault().notify(descriptor);
             if (res != null && res == DialogDescriptor.YES_OPTION) {
+                Case currentCase = null;
                 try {
-                    Case.getCurrentCase().closeCase(); // close the current case
-                } catch (Exception ex) {
-                    Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.WARNING, "Error closing case.", ex); //NON-NLS
+                    currentCase = Case.getCurrentCase();
+                    currentCase.closeCase();
+                } catch (IllegalStateException ignored) {
+                    /*
+                     * No current case.
+                     */
+                } catch (CaseActionException ex) {
+                    logger.log(Level.SEVERE, String.format("Error closing case at %s while ingest was running", (null!= currentCase ? currentCase.getCaseDirectory() : "?")),ex); //NON-NLS
                 }
             } else {
                 return;
             }
         }
 
-        // check if the file exists
-        if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
-            // throw an error here
-            JOptionPane.showMessageDialog(caller,
-                    NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text",
-                            caseName),
-                    NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.err"),
+        /*
+         * Open the case. 
+         */
+        if (caseName.equals("") || caseMetaDataFilePath.equals("") || (!new File(caseMetaDataFilePath).exists())) {
+            JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
+                    NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text", caseName),
+                    NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
                     JOptionPane.ERROR_MESSAGE);
-            RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
-
-            //if case is not opened, open the start window
+            RecentCases.getInstance().removeRecentCase(caseName, caseMetaDataFilePath);
             if (Case.isCaseOpen() == false) {
                 EventQueue.invokeLater(() -> {
                     StartupWindowProvider.getInstance().open();
                 });
-
             }
         } else {
             SwingUtilities.invokeLater(() -> {
                 WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
             });
             new Thread(() -> {
-                // Create case.
                 try {
-                    Case.open(casePath);
+                    Case.open(caseMetaDataFilePath);
                 } catch (CaseActionException ex) {
                     SwingUtilities.invokeLater(() -> {
+                        logger.log(Level.SEVERE, String.format("Error opening case with metadata file path %s", caseMetaDataFilePath), ex); //NON-NLS
                         WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-                        JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), ex.getMessage(),
-                                NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), JOptionPane.ERROR_MESSAGE); //NON-NLS
+                        JOptionPane.showMessageDialog(
+                                WindowManager.getDefault().getMainWindow(),
+                                ex.getMessage(), // Should be user-friendly
+                                NbBundle.getMessage(RecentItems.this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"), //NON-NLS
+                                JOptionPane.ERROR_MESSAGE);
                         if (!Case.isCaseOpen()) {
                             StartupWindowProvider.getInstance().open();
                         }