diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties
index a712c1bdb74c41660d045c174a69e0dc851b83ed..964b2df827f4010d4c78f2c5ddc905408e06926e 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties
@@ -80,17 +80,6 @@ DataSourcesNode.name=Data Sources
 DataSourcesNode.createSheet.name.name=Name
 DataSourcesNode.createSheet.name.displayName=Name
 DataSourcesNode.createSheet.name.desc=no description
-DeletedContent.fsDelFilter.text=File System
-DeletedContent.allDelFilter.text=All
-DeletedContent.deletedContentsNode.name=Deleted Files
-DeletedContent.createSheet.name.name=Name
-DeletedContent.createSheet.name.displayName=Name
-DeletedContent.createSheet.name.desc=no description
-DeletedContent.createSheet.filterType.name=Type
-DeletedContent.createSheet.filterType.displayName=Type
-DeletedContent.createSheet.filterType.desc=no description
-DeletedContent.createKeys.maxObjects.msg=There are more Deleted Files than can be displayed. Only the first {0} Deleted Files will be shown.
-DeletedContent.createNodeForKey.typeNotSupported.msg=Not supported for this type of Displayable Item\: {0}
 DirectoryNode.parFolder.text=[parent folder]
 DirectoryNode.curFolder.text=[current folder]
 DirectoryNode.getActions.viewFileInDir.text=View File in Directory
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java
index 589dfc4c86d2c52b33383fb1fb4cee10e212c6c2..28921410663022e02c53708a21992b6ddabbf4f8 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java
@@ -1,15 +1,20 @@
 /*
  * Autopsy Forensic Browser
+<<<<<<< HEAD
  * 
  * Copyright 2013-2017 Basis Technology Corp.
+=======
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+>>>>>>> upstream/rc-2.8.3
  * Contact: carrier <at> sleuthkit <dot> org
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -39,6 +44,7 @@
 import org.sleuthkit.autopsy.casemodule.Case;
 import org.sleuthkit.autopsy.core.UserPreferences;
 import org.sleuthkit.autopsy.coreutils.Logger;
+import static org.sleuthkit.autopsy.datamodel.Bundle.*;
 import org.sleuthkit.autopsy.ingest.IngestManager;
 import org.sleuthkit.datamodel.AbstractFile;
 import org.sleuthkit.datamodel.Content;
@@ -58,14 +64,15 @@ public class DeletedContent implements AutopsyVisitableItem {
 
     private SleuthkitCase skCase;
 
+    @NbBundle.Messages({"DeletedContent.fsDelFilter.text=File System",
+        "DeletedContent.allDelFilter.text=All"})
     public enum DeletedContentFilter implements AutopsyVisitableItem {
 
-        FS_DELETED_FILTER(0,
-                "FS_DELETED_FILTER", //NON-NLS
-                NbBundle.getMessage(DeletedContent.class, "DeletedContent.fsDelFilter.text")),
-        ALL_DELETED_FILTER(1,
-                "ALL_DELETED_FILTER", //NON-NLS
-                NbBundle.getMessage(DeletedContent.class, "DeletedContent.allDelFilter.text"));
+        FS_DELETED_FILTER(0, "FS_DELETED_FILTER", //NON-NLS
+                Bundle.DeletedContent_fsDelFilter_text()),
+        ALL_DELETED_FILTER(1, "ALL_DELETED_FILTER", //NON-NLS
+                Bundle.DeletedContent_allDelFilter_text());
+
         private int id;
         private String name;
         private String displayName;
@@ -110,15 +117,13 @@ public SleuthkitCase getSleuthkitCase() {
 
     public static class DeletedContentsNode extends DisplayableItemNode {
 
-        private static final String NAME = NbBundle.getMessage(DeletedContent.class,
-                "DeletedContent.deletedContentsNode.name");
-        private SleuthkitCase skCase;
+        @NbBundle.Messages("DeletedContent.deletedContentsNode.name=Deleted Files")
+        private static final String NAME = Bundle.DeletedContent_deletedContentsNode_name();
 
         DeletedContentsNode(SleuthkitCase skCase) {
             super(Children.create(new DeletedContentsChildren(skCase), true), Lookups.singleton(NAME));
             super.setName(NAME);
             super.setDisplayName(NAME);
-            this.skCase = skCase;
             this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon-deleted.png"); //NON-NLS
         }
 
@@ -133,6 +138,9 @@ public <T> T accept(DisplayableItemNodeVisitor<T> v) {
         }
 
         @Override
+        @NbBundle.Messages({
+            "DeletedContent.createSheet.name.displayName=Name",
+            "DeletedContent.createSheet.name.desc=no description"})
         protected Sheet createSheet() {
             Sheet s = super.createSheet();
             Sheet.Set ss = s.get(Sheet.PROPERTIES);
@@ -141,9 +149,9 @@ protected Sheet createSheet() {
                 s.put(ss);
             }
 
-            ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.name.name"),
-                    NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.name.displayName"),
-                    NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.name.desc"),
+            ss.put(new NodeProperty<>("Name", //NON-NLS
+                    Bundle.DeletedContent_createSheet_name_displayName(),
+                    Bundle.DeletedContent_createSheet_name_desc(),
                     NAME));
             return s;
         }
@@ -303,6 +311,9 @@ public <T> T accept(DisplayableItemNodeVisitor<T> v) {
             }
 
             @Override
+            @NbBundle.Messages({
+                "DeletedContent.createSheet.filterType.displayName=Type",
+                "DeletedContent.createSheet.filterType.desc=no description"})
             protected Sheet createSheet() {
                 Sheet s = super.createSheet();
                 Sheet.Set ss = s.get(Sheet.PROPERTIES);
@@ -311,10 +322,9 @@ protected Sheet createSheet() {
                     s.put(ss);
                 }
 
-                ss.put(new NodeProperty<>(
-                        NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.filterType.name"),
-                        NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.filterType.displayName"),
-                        NbBundle.getMessage(this.getClass(), "DeletedContent.createSheet.filterType.desc"),
+                ss.put(new NodeProperty<>("Type", //NON_NLS
+                        Bundle.DeletedContent_createSheet_filterType_displayName(),
+                        Bundle.DeletedContent_createSheet_filterType_desc(),
                         filter.getDisplayName()));
 
                 return s;
@@ -334,7 +344,7 @@ public String getItemType() {
                 return DisplayableItemNode.FILE_PARENT_NODE_KEY;
             }
         }
-        
+
         static class DeletedContentChildren extends ChildFactory.Detachable<AbstractFile> {
 
             private final SleuthkitCase skCase;
@@ -375,6 +385,9 @@ protected void removeNotify() {
             }
 
             @Override
+            @NbBundle.Messages("DeletedContent.createKeys.maxObjects.msg="
+                    + "There are more Deleted Files than can be displayed."
+                    + " Only the first {0} Deleted Files will be shown.")
             protected boolean createKeys(List<AbstractFile> list) {
                 List<AbstractFile> queryList = runFsQuery();
                 if (queryList.size() == MAX_OBJECTS) {
@@ -385,9 +398,8 @@ protected boolean createKeys(List<AbstractFile> list) {
                         SwingUtilities.invokeLater(new Runnable() {
                             @Override
                             public void run() {
-                                JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), NbBundle.getMessage(this.getClass(),
-                                        "DeletedContent.createKeys.maxObjects.msg",
-                                        MAX_OBJECTS - 1));
+                                JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
+                                        DeletedContent_createKeys_maxObjects_msg(MAX_OBJECTS - 1));
                             }
                         });
                     }
@@ -435,7 +447,11 @@ static private String makeQuery(DeletedContent.DeletedContentFilter filter) {
                 }
 
                 query += " LIMIT " + MAX_OBJECTS; //NON-NLS
+<<<<<<< HEAD
                 
+=======
+
+>>>>>>> upstream/rc-2.8.3
                 return query;
             }
 
@@ -456,6 +472,9 @@ private List<AbstractFile> runFsQuery() {
             /**
              * Get children count without actually loading all nodes
              *
+             * @param sleuthkitCase
+             * @param filter
+             *
              * @return
              */
             static long calculateItems(SleuthkitCase sleuthkitCase, DeletedContent.DeletedContentFilter filter) {
@@ -468,6 +487,7 @@ static long calculateItems(SleuthkitCase sleuthkitCase, DeletedContent.DeletedCo
             }
 
             @Override
+            @NbBundle.Messages("DeletedContent.createNodeForKey.typeNotSupported.msg=Not supported for this type of Displayable Item: {0}")
             protected Node createNodeForKey(AbstractFile key) {
                 return key.accept(new ContentVisitor.Default<AbstractNode>() {
                     public FileNode visit(AbstractFile f) {
@@ -495,9 +515,7 @@ public FileNode visit(Directory f) {
 
                     @Override
                     protected AbstractNode defaultVisit(Content di) {
-                        throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(),
-                                "DeletedContent.createNodeForKey.typeNotSupported.msg",
-                                di.toString()));
+                        throw new UnsupportedOperationException(Bundle.DeletedContent_createNodeForKey_typeNotSupported_msg(di.toString()));
                     }
                 });
             }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java
index 983433256714560a863adf3720c140a4f1fec68e..45205b0ca725f548849e3a565656307c17c2f712 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/RegexQuery.java
@@ -206,8 +206,8 @@ public QueryResults performQuery() throws NoOpenCoreException {
                         for (KeywordHit hit : keywordHits) {
                             hitsMultiMap.put(new Keyword(hit.getHit(), true, true, originalKeyword.getListName(), originalKeyword.getOriginalTerm()), hit);
                         }
-                    } catch (TskException ex) { 
-                        //
+                    } catch (TskCoreException ex) { 
+                        LOGGER.log(Level.SEVERE, "Error creating keyword hits", ex); //NON-NLS
                     }
                 }
 
@@ -228,7 +228,7 @@ public QueryResults performQuery() throws NoOpenCoreException {
         return results;
     }
 
-    private List<KeywordHit> createKeywordHits(SolrDocument solrDoc) throws TskException {
+    private List<KeywordHit> createKeywordHits(SolrDocument solrDoc) throws TskCoreException {
 
         List<KeywordHit> hits = new ArrayList<>();
         final String docId = solrDoc.getFieldValue(Server.Schema.ID.toString()).toString();
@@ -237,83 +237,93 @@ private List<KeywordHit> createKeywordHits(SolrDocument solrDoc) throws TskExcep
         final Collection<Object> content_str = solrDoc.getFieldValues(Server.Schema.CONTENT_STR.toString());
 
         final Pattern pattern = Pattern.compile(keywordString);
-        for (Object content_obj : content_str) {
-            String content = (String) content_obj;
-            Matcher hitMatcher = pattern.matcher(content);
-            int offset = 0;
-
-            while (hitMatcher.find(offset)) {
-                StringBuilder snippet = new StringBuilder();
-
-                // If the location of the hit is beyond this chunk (i.e. it
-                // exists in the overlap region), we skip the hit. It will
-                // show up again as a hit in the chunk following this one.
-                if (chunkSize != null && hitMatcher.start() >= chunkSize) {
-                    break;
-                }
+        try {
+            for (Object content_obj : content_str) {
+                String content = (String) content_obj;
+                Matcher hitMatcher = pattern.matcher(content);
+                int offset = 0;
+
+                while (hitMatcher.find(offset)) {
+                    StringBuilder snippet = new StringBuilder();
+
+                    // If the location of the hit is beyond this chunk (i.e. it
+                    // exists in the overlap region), we skip the hit. It will
+                    // show up again as a hit in the chunk following this one.
+                    if (chunkSize != null && hitMatcher.start() >= chunkSize) {
+                        break;
+                    }
 
-                String hit = hitMatcher.group();
-
-                offset = hitMatcher.end();
-
-                // We attempt to reduce false positives for phone numbers and IP address hits
-                // by querying Solr for hits delimited by a set of known boundary characters.
-                // See KeywordSearchList.PHONE_NUMBER_REGEX for an example.
-                // Because of this the hits may contain an extra character at the beginning or end that
-                // needs to be chopped off, unless the user has supplied their own wildcard suffix
-                // as part of the regex.
-                if (!queryStringContainsWildcardSuffix
-                        && (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER
-                        || originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS)) {
-                    if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER) {
-                        // For phone numbers replace all non numeric characters (except "(") at the start of the hit.
-                        hit = hit.replaceAll("^[^0-9\\(]", "");
-                    } else {
-                        // Replace all non numeric characters at the start of the hit.
-                        hit = hit.replaceAll("^[^0-9]", "");
+                    String hit = hitMatcher.group();
+
+                    offset = hitMatcher.end();
+
+                    // We attempt to reduce false positives for phone numbers and IP address hits
+                    // by querying Solr for hits delimited by a set of known boundary characters.
+                    // See KeywordSearchList.PHONE_NUMBER_REGEX for an example.
+                    // Because of this the hits may contain an extra character at the beginning or end that
+                    // needs to be chopped off, unless the user has supplied their own wildcard suffix
+                    // as part of the regex.
+                    if (!queryStringContainsWildcardSuffix
+                            && (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER
+                            || originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS)) {
+                        if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER) {
+                            // For phone numbers replace all non numeric characters (except "(") at the start of the hit.
+                            hit = hit.replaceAll("^[^0-9\\(]", "");
+                        } else {
+                            // Replace all non numeric characters at the start of the hit.
+                            hit = hit.replaceAll("^[^0-9]", "");
+                        }
+                        // Replace all non numeric at the end of the hit.
+                        hit = hit.replaceAll("[^0-9]$", "");
                     }
-                    // Replace all non numeric at the end of the hit.
-                    hit = hit.replaceAll("[^0-9]$", "");
-                }
 
-                if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL) {
-                    // Reduce false positives by eliminating email address hits that are either
-                    // too short or are not for valid top level domains.
-                    if (hit.length() < MIN_EMAIL_ADDR_LENGTH
-                            || !DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
-                        continue;
+                    if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL) {
+                        // Reduce false positives by eliminating email address hits that are either
+                        // too short or are not for valid top level domains.
+                        if (hit.length() < MIN_EMAIL_ADDR_LENGTH
+                                || !DomainValidator.getInstance(true).isValidTld(hit.substring(hit.lastIndexOf('.')))) {
+                            continue;
+                        }
                     }
-                }
 
-                /*
+                    /*
                  * If searching for credit card account numbers, do a Luhn check
                  * on the term and discard it if it does not pass.
-                 */
-                if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
-                    Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
-                    if (ccnMatcher.find()) {
-                        final String ccn = CharMatcher.anyOf(" -").removeFrom(ccnMatcher.group("ccn"));
-                        if (false == TermsComponentQuery.CREDIT_CARD_NUM_LUHN_CHECK.isValid(ccn)) {
+                     */
+                    if (originalKeyword.getArtifactAttributeType() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CARD_NUMBER) {
+                        Matcher ccnMatcher = CREDIT_CARD_NUM_PATTERN.matcher(hit);
+                        if (ccnMatcher.find()) {
+                            final String ccn = CharMatcher.anyOf(" -").removeFrom(ccnMatcher.group("ccn"));
+                            if (false == TermsComponentQuery.CREDIT_CARD_NUM_LUHN_CHECK.isValid(ccn)) {
+                                continue;
+                            }
+                        } else {
                             continue;
                         }
-                    } else {
-                        continue;
                     }
-                }
 
-                /**
-                 * Get the snippet from the document if keyword search is
-                 * configured to use snippets.
-                 */
-                int maxIndex = content.length() - 1;
-                snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start())));
-                snippet.appendCodePoint(171);
-                snippet.append(hit);
-                snippet.appendCodePoint(171);
-                snippet.append(content.substring(Integer.min(maxIndex, hitMatcher.end()), Integer.min(maxIndex, hitMatcher.end() + 20)));
-
-                hits.add(new KeywordHit(docId, snippet.toString(), hit));
+                    /**
+                     * Get the snippet from the document if keyword search is
+                     * configured to use snippets.
+                     */
+                    int maxIndex = content.length() - 1;
+                    snippet.append(content.substring(Integer.max(0, hitMatcher.start() - 20), Integer.max(0, hitMatcher.start())));
+                    snippet.appendCodePoint(171);
+                    snippet.append(hit);
+                    snippet.appendCodePoint(171);
+                    snippet.append(content.substring(Integer.min(maxIndex, hitMatcher.end()), Integer.min(maxIndex, hitMatcher.end() + 20)));
+
+                    hits.add(new KeywordHit(docId, snippet.toString(), hit));
+                }
             }
+        } catch (TskCoreException ex) {
+            throw ex;
+        } catch (Throwable error) {
+            /* NOTE: Matcher.find() is known to throw StackOverflowError in rare cases (see JIRA-2700). 
+            StackOverflowError is an error, not an exception, and therefore needs to be caught 
+            as a Throwable. When this occurs we should re-throw the error as TskCoreException so that it is 
+            logged by the calling method and move on to the next Solr document. */
+            throw new TskCoreException("Failed to create keyword hits for Solr document id " + docId + " due to " + error.getMessage());
         }
         return hits;
     }