diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
index 05f773a7846644e88ea23bd4f7ad15509eb76a13..9d7c3973ed7a0a816eb24e73bb672f5fba452a40 100644
--- a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
@@ -145,8 +145,6 @@ private static Lookup getLookups(BlackboardArtifact artifact) {
     private static Content getAssociatedContent(BlackboardArtifact artifact){
         try {
             return artifact.getSleuthkitCase().getContentById(artifact.getObjectID());
-        } catch (SQLException ex) {
-            logger.log(Level.WARNING, "SQL query threw exception", ex);
         } catch (TskException ex) {
             logger.log(Level.WARNING, "Getting file failed", ex);
         }
diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java
index 35be0170b404a89806ad2ef636cde47f70bf8e21..fffb10a3ca48a65a86dc0e448e24a4759834b6fb 100644
--- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java
+++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java
@@ -18,6 +18,7 @@
  */
 package org.sleuthkit.autopsy.hashdatabase;
 
+import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.sql.SQLException;
 import java.util.Collections;
@@ -185,9 +186,6 @@ public ProcessResult process(FsContent fsContent) {
                 // TODO: This shouldn't be at level INFO, but it needs to be to hide the popup
                 logger.log(Level.INFO, "Couldn't analyze file " + name + " - see sleuthkit log for details", ex);
                 ret = ProcessResult.ERROR;
-            } catch (SQLException ex) {
-                logger.log(Level.WARNING, "Error updating file known status in database", ex);
-                ret = ProcessResult.ERROR;
             } catch (IOException ex) {
                 // TODO: This shouldn't be at level INFO, but it needs to be to hide the popup
                 logger.log(Level.INFO, "Error reading file", ex);
@@ -207,6 +205,11 @@ public boolean hasBackgroundJobsRunning() {
         return false;
     }
     
+    @Override
+    public boolean backgroundJobsCompleteListener(PropertyChangeListener l) {
+        return false;
+    }
+    
     @Override
     public boolean hasSimpleConfiguration() {
         return false;
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java
index d1b837b729a89e3e4228c87dd1db6c54d1e37826..bf497be0952610597d5a6f7b5f44820c6ec69ff7 100755
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java
@@ -18,6 +18,7 @@
  */
 package org.sleuthkit.autopsy.ingest;
 
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.text.DateFormat;
@@ -139,7 +140,7 @@ IngestServiceFsContent.ProcessResult getFsContentServiceResult(String serviceNam
      * @param images images to execute services on
      */
     void execute(final List<IngestServiceAbstract> services, final List<Image> images) {
-        logger.log(Level.INFO, "Will enqueue number of images: " + images.size());
+        logger.log(Level.INFO, "Will enqueue number of images: " + images.size() + " to " + services.size() + " services.");
 
         if (!isIngestRunning()) {
             ui.clearMessages();
@@ -443,8 +444,9 @@ public void run() {
      */
     public static List<IngestServiceImage> enumerateImageServices() {
         List<IngestServiceImage> ret = new ArrayList<IngestServiceImage>();
-        for (IngestServiceImage list : Lookup.getDefault().lookupAll(IngestServiceImage.class))
+        for (IngestServiceImage list : Lookup.getDefault().lookupAll(IngestServiceImage.class)) {
             ret.add(list);
+        }
         return ret;
     }
 
@@ -453,8 +455,9 @@ public static List<IngestServiceImage> enumerateImageServices() {
      */
     public static List<IngestServiceFsContent> enumerateFsContentServices() {
         List<IngestServiceFsContent> ret = new ArrayList<IngestServiceFsContent>();
-        for (IngestServiceFsContent list : Lookup.getDefault().lookupAll(IngestServiceFsContent.class))
+        for (IngestServiceFsContent list : Lookup.getDefault().lookupAll(IngestServiceFsContent.class)) {
             ret.add(list);
+        }
         return ret;
     }
 
@@ -750,7 +753,7 @@ private QueueUnit<FsContent, IngestServiceFsContent> findFsContent(FsContent fsC
         public synchronized String toString() {
             return "FsContentQueue, size: " + Integer.toString(fsContentUnits.size());
         }
-        
+
         public String printQueue() {
             StringBuilder sb = new StringBuilder();
             for (QueueUnit<FsContent, IngestServiceFsContent> u : fsContentUnits) {
@@ -903,7 +906,7 @@ public int hashCode() {
             hash = 37 * hash + (this.services != null ? this.services.hashCode() : 0);
             return hash;
         }
-        
+
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
@@ -957,14 +960,10 @@ public String toString() {
         public String toHtmlString() {
             StringBuilder sb = new StringBuilder();
             sb.append("<html>");
-            if (startTime != null) {
-                sb.append("Start time: ").append(dateFormatter.format(startTime)).append("<br />");
-            }
-            if (endTime != null) {
-                sb.append("End time: ").append(dateFormatter.format(endTime)).append("<br />");
-            }
-            sb.append("Total ingest time: ").append(getTotalTimeString()).append("<br />");
+            
+            sb.append("Ingest time: ").append(getTotalTimeString()).append("<br />");
             sb.append("Total errors: ").append(errorsTotal).append("<br />");
+            /*
             if (errorsTotal > 0) {
                 sb.append("Errors per service:");
                 for (IngestServiceAbstract service : errors.keySet()) {
@@ -972,6 +971,8 @@ public String toHtmlString() {
                     sb.append("\t").append(service.getName()).append(": ").append(errorsService).append("<br />");
                 }
             }
+             * */
+            
             sb.append("</html>");
             return sb.toString();
         }
@@ -1134,18 +1135,63 @@ protected void done() {
                 handleInterruption();
                 logger.log(Level.SEVERE, "Fatal error during ingest.", ex);
             } finally {
-                stats.end();
+                //stats.end();
                 progress.finish();
 
                 if (!this.isCancelled()) {
-                    logger.log(Level.INFO, "Summary Report: " + stats.toString());
-                    ui.displayReport(stats.toHtmlString());
+                    //logger.log(Level.INFO, "Summary Report: " + stats.toString());
+                    //ui.displayReport(stats.toHtmlString());
+                    new FsServicesComplete(stats);
                 }
                 initMainProgress(0);
             }
 
         }
 
+        /**
+         * Ensures that all background threads are done
+         * then finalize the stats and show dialog
+         */
+        private class FsServicesComplete {
+
+            private IngestManagerStats stats; //ongoing stats
+            private List<IngestServiceAbstract> running = new ArrayList<IngestServiceAbstract>();
+
+            FsServicesComplete(IngestManagerStats stats) {
+                this.stats = stats;
+
+                for (IngestServiceAbstract s : fsContentServices) {
+                    if (s.backgroundJobsCompleteListener(new PropertyChangeListener() {
+
+                        @Override
+                        public void propertyChange(PropertyChangeEvent evt) {
+                            if (evt.getPropertyName().equals(IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT)) {
+                                IngestServiceAbstract service = (IngestServiceAbstract) evt.getNewValue();
+                                running.remove(service);
+                                if (running.isEmpty()) {
+                                    showStats();
+                                }
+                            }
+                        }
+                    })) {
+                        running.add(s);
+                    }
+                }
+
+                //no listeners registered since no services running any longer
+                if (running.isEmpty()) {
+                    showStats();
+                }
+
+            }
+
+            void showStats() {
+                stats.end();
+                logger.log(Level.INFO, "Summary Report: " + stats.toString());
+                ui.displayReport(stats.toHtmlString());
+            }
+        }
+
         private void handleInterruption() {
             for (IngestServiceFsContent s : fsContentServices) {
                 s.stop();
@@ -1254,9 +1300,9 @@ private void queueAll(List<IngestServiceAbstract> services, final List<Image> im
                     progress.progress(serviceName + " " + imageName, ++processed);
                 }
             }
-            
+
             //logger.log(Level.INFO, fsContentQueue.printQueue());
-            
+
             progress.progress("Sorting files", processed);
             sortFsContents();
         }
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java
index 64792b87230018ed054cbcb1122c374147b9a20f..b53fe8da17b2bb6fc4015e10de5da47853695289 100644
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java
@@ -555,7 +555,7 @@ static class IngestMessageGroup {
 
         static Color VERY_HIGH_PRI_COLOR = new Color(164, 164, 202); //for a single message in a group
         static Color HIGH_PRI_COLOR = new Color(180, 180, 211);
-        static Color MED_PRI_COLOR = new Color(199, 199, 202);
+        static Color MED_PRI_COLOR = new Color(199, 199, 222);
         static Color LOW_PRI_COLOR = new Color(221, 221, 235);
         private List<IngestMessage> messages;
         private int count;
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java
index bb6f3213e184160b18398aa82f093aa405956155..192ecdcf6dd937a223a6a316261a8429deaaac55 100644
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java
@@ -20,13 +20,15 @@
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.swing.Action;
 import javax.swing.BoxLayout;
 import javax.swing.JOptionPane;
 import org.openide.util.ImageUtilities;
 import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
 import org.openide.windows.Mode;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
@@ -103,22 +105,22 @@ public void componentOpened() {
         if (manager == null) {
             manager = IngestManager.getDefault();
         }
-        
+
     }
 
     @Override
     public void componentClosed() {
         //logger.log(Level.INFO, "CLOSED");
         super.componentClosed();
-        
+
         /*
         Mode mode = WindowManager.getDefault().findMode("dockedBottom");
         if (mode != null) {
-            mode.dockInto(this);
-            this.open();
+        mode.dockInto(this);
+        this.open();
         }
          * */
-         
+
         //this.close();
     }
 
@@ -126,7 +128,7 @@ public void componentClosed() {
     protected void componentShowing() {
         //logger.log(Level.INFO, "SHOWING");
         super.componentShowing();
-        
+
         Mode mode = WindowManager.getDefault().findMode("floatingLeftBottom");
         if (mode != null) {
             TopComponent[] tcs = mode.getTopComponents();
@@ -138,7 +140,7 @@ protected void componentShowing() {
             }
             mode.dockInto(this);
             this.open();
-        }                
+        }
     }
 
     @Override
@@ -151,7 +153,7 @@ protected void componentHidden() {
     @Override
     protected void componentActivated() {
         //logger.log(Level.INFO, "ACTIVATED");
-        super.componentActivated();   
+        super.componentActivated();
     }
 
     @Override
@@ -226,11 +228,40 @@ private void customizeComponents() {
      */
     @Override
     public void displayReport(String ingestReport) {
-        JOptionPane.showMessageDialog(
-                null,
+
+        Object[] options = {"OK",
+            "Generate Report"};
+        final int choice = JOptionPane.showOptionDialog(null,
                 ingestReport,
-                "File Ingest Summary",
-                JOptionPane.INFORMATION_MESSAGE);
+                "Ingest Report",
+                JOptionPane.YES_NO_OPTION,
+                JOptionPane.INFORMATION_MESSAGE,
+                null,
+                options,
+                options[0]);
+
+        final String reportActionName = "org.sleuthkit.autopsy.report.reportAction";
+        Action reportAction = null;
+        
+        //find action by name from action lookup, without introducing cyclic dependency
+        if (choice == JOptionPane.NO_OPTION) {
+            List<? extends Action> actions = Utilities.actionsForPath("Toolbars/File");
+            for (Action a : actions) {
+                //separators are null actions
+                if (a != null) {
+                    if (a.getClass().getCanonicalName().equals(reportActionName)) {
+                        reportAction = a;
+                        break;
+                    }
+                }
+            }
+            
+            if (reportAction == null)
+                logger.log(Level.SEVERE, "Could not locate Action: " + reportActionName);
+            else reportAction.actionPerformed(null);
+        
+        }
+
     }
 
     /**
@@ -261,7 +292,6 @@ public void displayIngestDialog(final Image image) {
         ingestDialog.setImage(image);
         ingestDialog.display();    
          */
-
     }
 
     @Override
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java
index fb67fec0ef2127f7c831e59ad72ed0ce35030697..b8ffdf756fdd516dcf9961fe101de0095e3134a8 100644
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java
@@ -19,12 +19,15 @@
 
 package org.sleuthkit.autopsy.ingest;
 
+import java.beans.PropertyChangeListener;
+
 /**
  * Base interface for ingest services
  */
 public interface IngestServiceAbstract {
     
     public enum ServiceType {Image, FsContent};
+    public static final String BCKGRND_JOBS_COMPLETED_EVT = "BCKGRND_JOBS_COMPLETED_EVT";
 
     /**
      * notification from manager that brand new processing should be initiated.
@@ -61,11 +64,28 @@ public enum ServiceType {Image, FsContent};
      /**
      * A service can manage and use additional threads to perform some work in the background.
      * This method provides insight to the manager if the service has truly completed its work or not.
+     *
+     * 
      * @return true if any background threads/workers managed by this service are still running
-     * false if all work has been done, or if background threads are not used by this service
+     * false if all work has been done, or if background threads are not managed by this service
      */
     public boolean hasBackgroundJobsRunning();
     
+    /**
+     * Register listener to notify when all background jobs managed by this service have completed and the service 
+     * has truly finished.  The service should first check if it has threads running, and then register the listener, all in a single atomic, synchronized operation, and return the result of the registration.
+     * Do not register the listener if the background threads are not running and will not run during this service invocation.
+     * If the service does use background threads it is required to implement this method properly and ensure the event is fired when the service-managed threads complete (are finished or cancelled)
+     * The event fired off should be IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT, with the instance of IngestServiceAbstract in the newValue parameter.
+     * The listeners should be reset at service init() - listeners are expected to register again as needed during the new service run.
+     * Typical use case is for ingest manager to try to register the listener for every service when the queue has been consumed,
+     * for a precise indication when all work is truly done.
+     * 
+     * @param l listener
+     * @return true if listener registered, false otherwise (i.e. no background jobs were running, or the service does not manage additional threads)
+     */
+    public boolean backgroundJobsCompleteListener(PropertyChangeListener l);
+    
     
     /**
      * @return does this service have a simple configuration?
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java
index 41bc0b9f678c2336498bcf73f90093c8c7baced6..8819b72357dadd3766a473c311e63f7ae4d21bda 100644
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java
@@ -18,9 +18,9 @@
  */
 package org.sleuthkit.autopsy.ingest.example;
 
+import java.beans.PropertyChangeListener;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.swing.JPanel;
 import org.sleuthkit.autopsy.ingest.IngestManagerProxy;
 import org.sleuthkit.autopsy.ingest.IngestMessage;
 import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
@@ -117,6 +117,11 @@ public boolean hasBackgroundJobsRunning() {
         return false;
     }
     
+    @Override
+    public boolean backgroundJobsCompleteListener(PropertyChangeListener l) {
+        return false;
+    }
+    
     @Override
     public void saveAdvancedConfiguration() {
     }
diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java
index ae38dbf2eea05eee92217659944c04d125e77963..73ab81203440ef17ca9b0ac08b9b37325df43f09 100644
--- a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java
+++ b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java
@@ -18,6 +18,7 @@
  */
 package org.sleuthkit.autopsy.ingest.example;
 
+import java.beans.PropertyChangeListener;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
@@ -147,6 +148,11 @@ public boolean hasBackgroundJobsRunning() {
         return false;
     }
     
+    @Override
+    public boolean backgroundJobsCompleteListener(PropertyChangeListener l) {
+        return false;
+    }
+    
     @Override
     public void saveAdvancedConfiguration() {
     }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java
index 8a7c5ef0420219d756b5cc322379058b2ec604ba..48c5f07340c2e2ffd73670be5cc24c332ddf6a4c 100755
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java
@@ -48,6 +48,7 @@ class Ingester {
     }
 
     @Override
+    @SuppressWarnings("FinalizeDeclaration")
     protected void finalize() throws Throwable {
         super.finalize();
 
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
index d0f7e2096bba9b6bf8f401d1ad9dc7f417e674a2..c9228d544a80a3eb5bdc81968bf6bf64651acb96 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
@@ -844,7 +844,7 @@ void deleteSelected(int[] selected) {
 
         }
 
-        class TableEntry implements Comparable {
+        class TableEntry implements Comparable<TableEntry> {
 
             Keyword keyword;
 
@@ -853,12 +853,12 @@ class TableEntry implements Comparable {
             }
 
             @Override
-            public int compareTo(Object o) {
-                int keywords = this.keyword.getQuery().compareTo(((TableEntry) o).keyword.getQuery());
+            public int compareTo(TableEntry te) {
+                int keywords = this.keyword.getQuery().compareTo(te.keyword.getQuery());
                 if (keywords != 0) {
                     return keywords;
                 } else {
-                    return Boolean.valueOf(keyword.isLiteral()).compareTo(((TableEntry) o).keyword.isLiteral());
+                    return Boolean.valueOf(keyword.isLiteral()).compareTo(te.keyword.isLiteral());
                 }
             }
         }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java
index e9eada1663bcc525b685f734b73b49e5196b026a..3d64f4a671db499cf5d403408a9b4c901361d9ba 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java
@@ -18,6 +18,8 @@
  */
 package org.sleuthkit.autopsy.keywordsearch;
 
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -25,7 +27,6 @@
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 import javax.swing.SwingWorker;
 import org.apache.commons.lang.StringEscapeUtils;
@@ -38,6 +39,7 @@
 import org.sleuthkit.autopsy.ingest.IngestManagerProxy;
 import org.sleuthkit.autopsy.ingest.IngestMessage;
 import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
+import org.sleuthkit.autopsy.ingest.IngestServiceAbstract;
 import org.sleuthkit.autopsy.ingest.IngestServiceFsContent;
 import org.sleuthkit.autopsy.ingest.ServiceDataEvent;
 import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException;
@@ -66,13 +68,17 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent
     //private final Object lock = new Object();
     private Thread timer;
     private Indexer indexer;
-    private SwingWorker searcher;
+    private Searcher searcher;
     private volatile boolean searcherDone = true;
+    private static PropertyChangeSupport pcs = null;
     private Map<Keyword, List<FsContent>> currentResults;
     private volatile int messageID = 0;
+    private boolean processedFiles;
     private volatile boolean finalRun = false;
+    private volatile boolean finalRunComplete = false;
     private final String hashDBServiceName = "Hash Lookup";
     private SleuthkitCase caseHandle = null;
+  
     // TODO: use a more robust method than checking file extension to determine
     // whether to try a file
     // supported extensions list from http://www.lucidimagination.com/devzone/technical-articles/content-extraction-tika
@@ -108,6 +114,9 @@ else if (hashDBResult == IngestServiceFsContent.ProcessResult.ERROR) {
             //notify depending service that keyword search (would) encountered error for this file
             return ProcessResult.ERROR;
         }
+        
+        if (processedFiles == false)
+            processedFiles = true;
 
         //check if time to commit and previous search is not running
         //commiting while searching causes performance issues
@@ -151,11 +160,12 @@ public void complete() {
 
         updateKeywords();
         //run one last search as there are probably some new files committed
-        if (keywords != null && !keywords.isEmpty()) {
+        if (keywords != null && !keywords.isEmpty() && processedFiles == true) {
             finalRun = true;
             searcher = new Searcher(keywords);
             searcher.execute();
         } else {
+            finalRunComplete = true;
             managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, this, "Completed"));
         }
         //postSummary();
@@ -191,6 +201,9 @@ public void init(IngestManagerProxy managerProxy) {
         caseHandle = Case.getCurrentCase().getSleuthkitCase();
 
         this.managerProxy = managerProxy;
+        
+        //this deregisters previously registered listeners at every init()
+        pcs = new PropertyChangeSupport(KeywordSearchIngestService.class);
 
         final Server.Core solrCore = KeywordSearch.getServer().getCore();
         ingester = solrCore.getIngester();
@@ -209,7 +222,9 @@ public void init(IngestManagerProxy managerProxy) {
             managerProxy.postMessage(IngestMessage.createWarningMessage(++messageID, instance, "No keywords in keyword list.", "Only indexing will be done and and keyword search will be skipped (it can be executed later again as ingest or using toolbar search feature)."));
         }
 
+        processedFiles = false;
         finalRun = false;
+        finalRunComplete = false;
         searcherDone = true; //make sure to start the initial searcher
         //keeps track of all results per run not to repeat reporting the same hits
         currentResults = new HashMap<Keyword, List<FsContent>>();
@@ -271,6 +286,17 @@ public boolean hasBackgroundJobsRunning() {
         //no need to check timer thread
 
     }
+    
+    @Override
+    public synchronized boolean backgroundJobsCompleteListener(PropertyChangeListener l) {
+        if (finalRunComplete == true)
+            return false;
+        else {
+            pcs.addPropertyChangeListener(l);
+            return true;
+        }
+       
+    }
 
     private void commit() {
         ingester.commit();
@@ -468,16 +494,17 @@ private void processNonIngestible(FsContent fsContent) {
             if (fsContent.getSize() < MAX_STRING_EXTRACT_SIZE) {
                 if (!extractAndIngest(fsContent)) {
                     logger.log(Level.INFO, "Failed to extract strings and ingest, file '" + fsContent.getName() + "' (id: " + fsContent.getId() + ").");
+                    ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED);
                 } else {
                     ingestStatus.put(fsContent.getId(), IngestStatus.EXTRACTED_INGESTED);
                 }
             } else {
-                ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED);
+                //ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED);
             }
         }
     }
 
-    private class Searcher extends SwingWorker {
+    private class Searcher extends SwingWorker<Object,Void> {
 
         private List<Keyword> keywords;
         private ProgressHandle progress;
@@ -499,6 +526,7 @@ protected Object doInBackground() throws Exception {
 
                 @Override
                 public boolean cancel() {
+                    finalRunComplete = true;
                     return Searcher.this.cancel(true);
                 }
             });
@@ -655,9 +683,11 @@ protected void done() {
 
             //logger.log(Level.INFO, "Finished search");
             if (finalRun) {
+                finalRunComplete = true;
                 keywords.clear();
                 keywordLists.clear();
                 managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, KeywordSearchIngestService.instance, "Completed"));
+                pcs.firePropertyChange(IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT, null, KeywordSearchIngestService.this);
             }
         }
     }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
index 71f90cc2c2839c153d5cbcec195faed34eda6029..03e5ba8eef9573e281f1bb35228ead1b9adfcdb7 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
@@ -396,7 +396,7 @@ private void addLists(List<KeywordSearchList> lists) {
         }
 
         //single model entry
-        class TableEntry implements Comparable {
+        class TableEntry implements Comparable<TableEntry> {
 
             String name;
 
@@ -405,8 +405,8 @@ class TableEntry implements Comparable {
             }
 
             @Override
-            public int compareTo(Object o) {
-                return this.name.compareTo(((TableEntry) o).name);
+            public int compareTo(TableEntry te) {
+                return this.name.compareTo(te.name);
             }
         }
     }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
index 74c3fe83c073d299b9512c32cb795a4660729a03..db3f8db9ea994418ecdecbe8b14ec430d804d246 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
@@ -506,7 +506,7 @@ private void addLists(List<KeywordSearchList> lists) {
         }
 
         //single model entry
-        private class ListTableEntry implements Comparable {
+        private class ListTableEntry implements Comparable<ListTableEntry> {
 
             String name;
             Boolean selected;
@@ -520,8 +520,8 @@ private class ListTableEntry implements Comparable {
             }
 
             @Override
-            public int compareTo(Object o) {
-                return this.name.compareTo(((ListTableEntry) o).name);
+            public int compareTo(ListTableEntry e) {
+                return this.name.compareTo(e.name);
             }
         }
     }
@@ -606,7 +606,7 @@ void deleteAll() {
         }
         
         //single model entry
-        private class KeywordTableEntry implements Comparable {
+        private class KeywordTableEntry implements Comparable<KeywordTableEntry> {
 
             String name;
             Boolean regex;
@@ -617,8 +617,8 @@ private class KeywordTableEntry implements Comparable {
             }
 
             @Override
-            public int compareTo(Object o) {
-                return this.name.compareTo(((KeywordTableEntry) o).name);
+            public int compareTo(KeywordTableEntry e) {
+                return this.name.compareTo(e.name);
             }
         }
     }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java
index a9f8a4744e0becc77564456c716504ad368354f6..fc7abb5cce544dc1c139c94ea793fc0d415a5944 100755
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java
@@ -131,7 +131,9 @@ public static boolean displayConfirmDialog(final String title, final String mess
     //TODO escaping should be handled by blackboard
     public static String escapeForBlackBoard(String text) {
         try {
-            text = text.replaceAll("\\\\'", URLEncoder.encode("\\'", "UTF-8"));
+            //text = text.replaceAll("\\\\'", URLEncoder.encode("\\'", "UTF-8"));
+            text = text.replaceAll("'", URLEncoder.encode("'", "UTF-8"));
+            //text = text.replaceAll("\"", URLEncoder.encode("\"", "UTF-8"));
             //text = text.replaceAll("\\\\", URLEncoder.encode("\\", "UTF-8"));
         } catch (UnsupportedEncodingException ex) {
         }
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java
index 819e7984eed62956babb694369abe139e96c8a41..f296739a34d8e61f3159fdcf839ad1cec3c263a2 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java
@@ -199,7 +199,8 @@ public Collection<KeywordWriteResult> writeToBlackBoard(FsContent newFsHit, Stri
             attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID(), MODULE_NAME, "", KeywordSearchUtil.escapeForBlackBoard(termsQuery)));
 
             //regex match
-            attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, "", regexMatch));
+            final String regexMatchEscaped = KeywordSearchUtil.escapeForBlackBoard(regexMatch);
+            attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, "", regexMatchEscaped));
             //list
             if (listName == null) {
                 listName = "";
@@ -214,7 +215,7 @@ public Collection<KeywordWriteResult> writeToBlackBoard(FsContent newFsHit, Stri
             if (keywordQuery != null) {
                 BlackboardAttribute.ATTRIBUTE_TYPE selType = keywordQuery.getType();
                 if (selType != null) {
-                    BlackboardAttribute selAttr = new BlackboardAttribute(selType.getTypeID(), MODULE_NAME, "", regexMatch);
+                    BlackboardAttribute selAttr = new BlackboardAttribute(selType.getTypeID(), MODULE_NAME, "", regexMatchEscaped);
                     attributes.add(selAttr);
                 }
             }
@@ -297,7 +298,7 @@ public void execute() {
 
         logger.log(Level.INFO, "Executing TermsComponent query: " + q.toString());
 
-        final SwingWorker worker = new TermsQueryWorker(q);
+        final SwingWorker<List<Term>, Void> worker = new TermsQueryWorker(q);
         worker.execute();
     }
 
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java
index fad833d7a3e810b1e6432c3f25c9cdf7519b77c4..8bdee2792b4eb510668c9aaa27ebe8da457467a3 100755
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java
@@ -31,6 +31,8 @@ public class Chrome {
            + "datetime(urls.last_visit_time/1000000-11644473600,'unixepoch','localtime') as last_visit_time, urls.hidden, visits.visit_time, visits.from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url";
    public static final String chcookiequery = "select name, value, host, expires_utc, datetime(last_access_utc/1000000-11644473600,'unixepoch','localtime') as last_access_utc, creation_utc from cookies";
    public static final String chbookmarkquery = "SELECT starred.title, urls.url, starred.date_added, starred.date_modified, urls.typed_count, datetime(urls.last_visit_time/1000000-11644473600,'unixepoch','localtime') as urls._last_visit_time FROM starred INNER JOIN urls ON urls.id = starred.url_id";
+   public static final String chdownloadquery = "select full_path, url, start_time, received_bytes  from `downloads`";
+   public static final String chloginquery = "select origin_url, username_value, signon_realm from `logins`";
    private final Logger logger = Logger.getLogger(this.getClass().getName());
    public int ChromeCount = 0;
     
@@ -82,7 +84,7 @@ public void getchdb(List<String> image, IngestImageWorkerController controller){
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",temprs.getString("url")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Accessed",temprs.getString("last_visit_time")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",temprs.getString("from_visit")));
-                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "No Title")));
+                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
                       bbart.addAttributes(bbattributes);
                      
@@ -144,7 +146,7 @@ public void getchdb(List<String> image, IngestImageWorkerController controller){
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", "", temprs.getString("host")));
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),"RecentActivity", "Last Visited",temprs.getString("access_utc")));
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(),"RecentActivity", "",temprs.getString("value")));
-                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "No name")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "")));
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
                      bbart.addAttributes(bbattributes);
                    } 
@@ -202,8 +204,132 @@ public void getchdb(List<String> image, IngestImageWorkerController controller){
                       BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK); 
                       Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("last_visit_time")));
-                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "No URL")));
-                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "No Title")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
+                     bbart.addAttributes(bbattributes);
+                      
+                   } 
+                   tempdbconnect.closeConnection();
+                   temprs.close();
+                    
+                 }
+                 catch (Exception ex)
+                 {
+                    logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex);      
+                 }
+                j++;
+                dbFile.delete();
+            }
+        }
+        catch (SQLException ex) 
+        {
+           logger.log(Level.WARNING, "Error while trying to get Chrome SQLite db.", ex);
+        }
+        catch(IOException ioex)
+        {   
+            logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex);
+        } 
+         
+          //Downloads section
+          // This gets the downloads info
+         try 
+         {   
+            Case currentCase = Case.getCurrentCase(); // get the most updated case
+            SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+            List<FsContent> FFSqlitedb;  
+            ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'History' and parent_path LIKE '%Chrome%' and fs_obj_id = '" + image + "'");
+            FFSqlitedb = tempDb.resultSetToFsContents(rs);
+            rs.close();
+            rs.getStatement().close();  
+            
+            int j = 0;
+     
+            while (j < FFSqlitedb.size())
+            {
+                String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db";
+                String connectionString = "jdbc:sqlite:" + temps;
+                ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"));
+                File dbFile = new File(temps);
+                if (controller.isCancelled() ) {
+                 dbFile.delete();
+                 break;
+                }  
+                 try
+                {
+                   dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString);
+                   ResultSet temprs = tempdbconnect.executeQry(chdownloadquery);  
+                   while(temprs.next()) 
+                   {
+                      BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD); 
+                      Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("start_time")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "")));
+                     //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "Recent Activity", "", temprs.getString("full_path")));
+                     
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
+                     bbart.addAttributes(bbattributes);
+                      
+                   } 
+                   tempdbconnect.closeConnection();
+                   temprs.close();
+                    
+                 }
+                 catch (Exception ex)
+                 {
+                    logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex);      
+                 }
+                j++;
+                dbFile.delete();
+            }
+        }
+        catch (SQLException ex) 
+        {
+           logger.log(Level.WARNING, "Error while trying to get Chrome SQLite db.", ex);
+        }
+        catch(IOException ioex)
+        {   
+            logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex);
+        } 
+         
+          //Login/Password section
+          // This gets the user info
+         try 
+         {   
+            Case currentCase = Case.getCurrentCase(); // get the most updated case
+            SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+            List<FsContent> FFSqlitedb;  
+            ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'signons.sqlite' and parent_path LIKE '%Chrome%' and fs_obj_id = '" + image + "'");
+            FFSqlitedb = tempDb.resultSetToFsContents(rs);
+            rs.close();
+            rs.getStatement().close();  
+            
+            int j = 0;
+     
+            while (j < FFSqlitedb.size())
+            {
+                String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db";
+                String connectionString = "jdbc:sqlite:" + temps;
+                ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"));
+                File dbFile = new File(temps);
+                if (controller.isCancelled() ) {
+                 dbFile.delete();
+                 break;
+                }  
+                 try
+                {
+                   dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString);
+                   ResultSet temprs = tempdbconnect.executeQry(chloginquery);  
+                   while(temprs.next()) 
+                   {
+                      BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY); 
+                      Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
+                     //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("start_time")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("origin_url") != null) ? temprs.getString("origin_url") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USERNAME.getTypeID(), "RecentActivity","", ((temprs.getString("username_value") != null) ? temprs.getString("username_value").replaceAll("'", "''") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", "", temprs.getString("signon_realm")));
+                     
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
                      bbart.addAttributes(bbattributes);
                       
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java
index 84c03334567109be4fb8aa41169f0c48dcb02872..6cc7779ff54390661990af8e1f020730d34acef3 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java
@@ -14,7 +14,7 @@
 public class ExtractAll {
     
        void ExtractAll(){
-            
+              
         }
        
 
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java
index 1d3440d9400fd2e97a3357b15337ec791d2bdb98..1e0968b8d679e508245a50e5b796bc71528d8a93 100755
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java
@@ -292,9 +292,7 @@ public void parsePascoResults() {
                                         PASCO_RESULTS_LIST.add(PASCO_RESULTS_LUT);
                                     } catch (TskException ex) {
                                         Exceptions.printStackTrace(ex);
-                                    } catch (SQLException ex) {
-                                        logger.log(Level.WARNING, "Couldn't find file with id: " + artObjId, ex);
-                                    }
+                                    } 
                                 }
 
                             }
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
index e9fa80a8a9bfb8993b7ec826aa3631e065774075..366382e6b82e2d42cfd164806a15ffce4de86687 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java
@@ -42,7 +42,7 @@ public class ExtractRegistry {
       public Logger logger = Logger.getLogger(this.getClass().getName());
      private String RR_PATH;
      boolean rrFound = false;
-     
+     private int sysid;
     ExtractRegistry(){
         final File rrRoot = InstalledFileLocator.getDefault().locate("rr", ExtractRegistry.class.getPackage().getName(), false);
          if (rrRoot == null) {
@@ -53,7 +53,18 @@ public class ExtractRegistry {
          else {
              rrFound = true;
          }
-         
+         try{
+              Case currentCase = Case.getCurrentCase(); // get the most updated case
+              SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+               ResultSet artset = tempDb.runQuery("SELECT * from blackboard_artifact_types WHERE type_name = 'TSK_SYS_INFO'");
+                  
+                   while (artset.next()){
+                       sysid = artset.getInt("artifact_type_id");
+                      }
+         }
+         catch(Exception e){
+             
+         }
         final String rrHome = rrRoot.getAbsolutePath();
         logger.log(Level.INFO, "RegRipper home: " + rrHome);
              
@@ -175,7 +186,9 @@ private boolean parseReg(String regRecord, long orgId)
     {
         Case currentCase = Case.getCurrentCase(); // get the most updated case
         SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+        
          try {
+           
            String regString = new Scanner(new File(regRecord)).useDelimiter("\\Z").next();
            String startdoc = "<document>";
            String result = regString.replaceAll("----------------------------------------","");
@@ -199,7 +212,7 @@ private boolean parseReg(String regRecord, long orgId)
                
                Element artroot = tempnode.getChild("artifacts");
                List artlist = artroot.getChildren();
-            BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
+               
             Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
             bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", context, time));
               Iterator aiterator = artlist.iterator();
@@ -210,16 +223,27 @@ private boolean parseReg(String regRecord, long orgId)
                   bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", context, name));
                  bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", context, value));
                }
-                
-                
-                 
-              
+                if("recentdocs".equals(context)){
+               BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
                 bbart.addAttributes(bbattributes);
+                 }
+               else if("runMRU".equals(context)){
+                BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
+                 bbart.addAttributes(bbattributes);
+    
+                }
+               else
+               {   
+                 
+                   BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(sysid);
+                    bbart.addAttributes(bbattributes);
+               }  
+               
             }
            }
            catch (Exception ex)
            {
-               String hi = "";
+            
             logger.log(Level.WARNING, "Error while trying to read into a sqlite db." +  ex);      
            }
    
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java
index 2380a191eb35e25d9def2e7d25ee552c55393b47..47c27467ff64e4dedcaec3d5e0bee85d71328e52 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java
@@ -31,6 +31,7 @@ public class Firefox {
     private static final String ffquery = "SELECT moz_historyvisits.id,url,title,visit_count,datetime(moz_historyvisits.visit_date/1000000,'unixepoch','localtime') as visit_date,from_visit,(SELECT url FROM moz_places WHERE id=moz_historyvisits.from_visit) as ref FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0";
     private static final String ffcookiequery = "SELECT name,value,host,expiry,datetime(moz_cookies.lastAccessed/1000000,'unixepoch','localtime') as lastAccessed,creationTime FROM moz_cookies";
     private static final String ffbookmarkquery = "SELECT fk, moz_bookmarks.title, url FROM moz_bookmarks INNER JOIN moz_places ON moz_bookmarks.fk=moz_places.id";
+    private static final String ffdownloadquery = "select target, source, startTime, maxBytes  from `moz_downloads`";
     
     public Logger logger = Logger.getLogger(this.getClass().getName());
 
@@ -88,8 +89,8 @@ public void getffdb(List<String> image, IngestImageWorkerController controller){
                        Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",temprs.getString("url")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("visit_date")));
-                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",((temprs.getString("ref") != null) ? temprs.getString("ref") : "None")));
-                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "No Title")));
+                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",((temprs.getString("ref") != null) ? temprs.getString("ref") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox"));
                        bbart.addAttributes(bbattributes);
                       
@@ -100,8 +101,8 @@ public void getffdb(List<String> image, IngestImageWorkerController controller){
                    {
                       BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
                       Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
-                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "No URL")));
-                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "No Title")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "")));
+                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox")); 
                      bbart.addAttributes(bbattributes);
                    } 
@@ -168,7 +169,7 @@ public void getffdb(List<String> image, IngestImageWorkerController controller){
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", "", temprs.getString("host")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Last Visited", temprs.getString("lastAccessed")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", "", temprs.getString("value")));
-                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "No name")));
+                      bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "")));
                       bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox"));
                        bbart.addAttributes(bbattributes);
                       
@@ -193,6 +194,69 @@ public void getffdb(List<String> image, IngestImageWorkerController controller){
         {   
             logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex);
         }
+         
+         
+          //Downloads section
+          // This gets the downloads info
+         try 
+         {   
+            Case currentCase = Case.getCurrentCase(); // get the most updated case
+            SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+            List<FsContent> FFSqlitedb;  
+            ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'downloads.sqlite' and parent_path LIKE '%Firefox%' and fs_obj_id = '" + image + "'");
+            FFSqlitedb = tempDb.resultSetToFsContents(rs);
+            rs.close();
+            rs.getStatement().close();  
+            
+            int j = 0;
+     
+            while (j < FFSqlitedb.size())
+            {
+                String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db";
+                String connectionString = "jdbc:sqlite:" + temps;
+                ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"));
+                File dbFile = new File(temps);
+                if (controller.isCancelled() ) {
+                 dbFile.delete();
+                 break;
+                }  
+                 try
+                {
+                   dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString);
+                   ResultSet temprs = tempdbconnect.executeQry(ffdownloadquery);  
+                   while(temprs.next()) 
+                   {
+                      BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD); 
+                      Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("startTime")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("source") != null) ? temprs.getString("source") : "")));
+                     //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "")));
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "Recent Activity", "", temprs.getString("target")));
+                     
+                     bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome"));
+                     bbart.addAttributes(bbattributes);
+                      
+                   } 
+                   tempdbconnect.closeConnection();
+                   temprs.close();
+                    
+                 }
+                 catch (Exception ex)
+                 {
+                    logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex);      
+                 }
+                j++;
+                dbFile.delete();
+            }
+        }
+        catch (SQLException ex) 
+        {
+           logger.log(Level.WARNING, "Error while trying to get FireFox SQLite db.", ex);
+        }
+        catch(IOException ioex)
+        {   
+            logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex);
+        } 
    } 
 }
    //@Override
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java
index 9e9332bf8ef48591870310ff3fa86825848d5f36..02526d349ecad80ab1e9717c66159aa8e10fcc8f 100644
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java
@@ -18,12 +18,13 @@
  */
 package org.sleuthkit.autopsy.recentactivity;
 
+import java.beans.PropertyChangeListener;
+import java.sql.ResultSet;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.swing.JPanel;
 import org.sleuthkit.autopsy.casemodule.Case;
 import org.sleuthkit.autopsy.ingest.IngestImageWorkerController;
 import org.sleuthkit.autopsy.ingest.IngestManager;
@@ -80,7 +81,28 @@ public void process(Image image, IngestImageWorkerController controller) {
 
         try {
             //do the work for(FileSystem img : imageFS )
-
+            try{
+           ResultSet artset = sCurrentCase.runQuery("SELECT * from blackboard_artifact_types WHERE type_name = 'TSK_SYS_INFO'");
+               int artcount = 0; 
+           while (artset.next()){
+              artcount++;
+              }
+       
+         //  artset.beforeFirst();
+               if(artcount > 0)
+               {
+
+               }
+               else
+               {
+                   int artint = sCurrentCase.addArtifactType("TSK_SYS_INFO", "System Information"); 
+               }
+           
+            }
+            catch(Exception e)
+            {
+              
+            }
             ext.extractToBlackboard(controller, fsIds);
 
 
@@ -162,4 +184,10 @@ public void saveSimpleConfiguration() {
     public boolean hasBackgroundJobsRunning() {
         return false;
     }
+    
+    
+    @Override
+    public boolean backgroundJobsCompleteListener(PropertyChangeListener l) {
+        return false;
+    }
 }
diff --git a/Report/src/org/sleuthkit/autopsy/report/report.java b/Report/src/org/sleuthkit/autopsy/report/report.java
index 5dadd4722074f28e2dfa1533167b5e48f99f93da..ae8c5a2a571daa68186a87a95e685364e25099bb 100644
--- a/Report/src/org/sleuthkit/autopsy/report/report.java
+++ b/Report/src/org/sleuthkit/autopsy/report/report.java
@@ -5,16 +5,14 @@
 package org.sleuthkit.autopsy.report;
 
 import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.sleuthkit.autopsy.casemodule.Case;
 import org.sleuthkit.datamodel.BlackboardArtifact;
 import org.sleuthkit.datamodel.BlackboardAttribute;
-import org.sleuthkit.datamodel.FsContent;
 import org.sleuthkit.datamodel.SleuthkitCase;
 
 /**
@@ -199,4 +197,57 @@ public HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> getHashHit() {
     return reportMap;
 }
 
+@Override
+public String getGroupedKeywordHit() {
+    StringBuilder table = new StringBuilder();
+    HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> reportMap = new HashMap();
+    Case currentCase = Case.getCurrentCase(); // get the most updated case
+    SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+    try
+    {
+       ResultSet uniqueresults = tempDb.runQuery("SELECT DISTINCT value_text from blackboard_attributes where attribute_type_id = '10' order by value_text ASC");
+        while(uniqueresults.next())
+        {  
+           table.append("<strong>").append(uniqueresults.getString("value_text")).append("</strong>");
+           table.append("<table><thead><tr><th>").append("File Name").append("</th><th>Preview</th><th>Keyword List</th></tr><tbody>");
+           ArrayList<BlackboardArtifact> artlist = new ArrayList<BlackboardArtifact>();
+           ResultSet tempresults = tempDb.runQuery("select DISTINCT artifact_id from blackboard_attributes where attribute_type_id = '10' and value_text = '" + uniqueresults.getString("value_text") +"'");
+            while(tempresults.next())
+            {
+                artlist.add(tempDb.getBlackboardArtifact(tempresults.getLong("artifact_id")));
+            }
+            for(BlackboardArtifact art : artlist)
+            {
+              String filename = tempDb.getFsContentById(art.getObjectID()).getName();
+              String preview = "";
+              String set = "";
+              table.append("<tr><td>").append(filename).append("</td>");
+              ArrayList<BlackboardAttribute> tempatts = art.getAttributes();
+                for(BlackboardAttribute att : tempatts)
+                {                  
+                    if(att.getAttributeTypeID() == 12)
+                    {
+                        preview = "<td>" + att.getValueString() + "</td>";
+                    }
+                    if(att.getAttributeTypeID() == 13)
+                    {
+                        set = "<td>" + att.getValueString() + "</td>";
+                    }
+                }
+                table.append(preview).append(set).append("</tr>");
+            }
+           
+           
+           table.append("</tbody></table><br /><br />");
+        }
+    }
+    catch (Exception e)
+    {
+        Logger.getLogger(report.class.getName()).log(Level.INFO, "Exception occurred", e);
+    }
+    
+    String result = table.toString();
+    return result;
+}
+
 }
\ No newline at end of file
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportFilter.form b/Report/src/org/sleuthkit/autopsy/report/reportFilter.form
index dac82f751fd62a3ae232d6448074b04994c1e848..8c3a8123f96841b3533c168671a7ed19db352b9b 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportFilter.form
+++ b/Report/src/org/sleuthkit/autopsy/report/reportFilter.form
@@ -32,34 +32,35 @@
     <DimensionLayout dim="0">
       <Group type="103" groupAlignment="0" attributes="0">
           <Group type="102" attributes="0">
+              <EmptySpace min="-2" pref="38" max="-2" attributes="0"/>
               <Group type="103" groupAlignment="0" attributes="0">
                   <Group type="102" attributes="0">
-                      <EmptySpace min="-2" pref="28" max="-2" attributes="0"/>
                       <Group type="103" groupAlignment="0" attributes="0">
                           <Component id="jCheckBox3" alignment="0" min="-2" max="-2" attributes="0"/>
                           <Group type="102" alignment="0" attributes="0">
                               <Group type="103" groupAlignment="0" attributes="0">
                                   <Component id="jCheckBox2" alignment="0" min="-2" max="-2" attributes="0"/>
                                   <Component id="jCheckBox1" alignment="0" min="-2" max="-2" attributes="0"/>
-                                  <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
                               </Group>
                               <EmptySpace max="-2" attributes="0"/>
                               <Group type="103" groupAlignment="0" attributes="0">
                                   <Component id="jCheckBox5" min="-2" max="-2" attributes="0"/>
-                                  <Group type="103" alignment="0" groupAlignment="0" attributes="0">
-                                      <Component id="jCheckBox4" min="-2" max="-2" attributes="0"/>
-                                      <Component id="progBar" alignment="1" min="-2" pref="188" max="-2" attributes="0"/>
-                                  </Group>
+                                  <Component id="jCheckBox4" alignment="0" min="-2" max="-2" attributes="0"/>
                               </Group>
                           </Group>
                       </Group>
+                      <EmptySpace min="-2" pref="69" max="-2" attributes="0"/>
                   </Group>
                   <Group type="102" alignment="0" attributes="0">
-                      <EmptySpace min="-2" pref="106" max="-2" attributes="0"/>
                       <Component id="jButton1" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace pref="15" max="32767" attributes="0"/>
+                      <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="progBar" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="42" max="-2" attributes="0"/>
                   </Group>
               </Group>
-              <EmptySpace pref="108" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
           </Group>
       </Group>
     </DimensionLayout>
@@ -79,13 +80,12 @@
               <EmptySpace type="separate" max="-2" attributes="0"/>
               <Component id="jCheckBox3" min="-2" max="-2" attributes="0"/>
               <EmptySpace type="separate" max="-2" attributes="0"/>
-              <Group type="103" groupAlignment="1" attributes="0">
-                  <Group type="102" attributes="0">
-                      <Component id="jButton1" min="-2" max="-2" attributes="0"/>
-                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
-                      <Component id="progBar" pref="25" max="32767" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="progBar" pref="23" max="32767" attributes="1"/>
+                  <Group type="103" alignment="0" groupAlignment="3" attributes="0">
+                      <Component id="jButton1" alignment="3" max="32767" attributes="1"/>
+                      <Component id="cancelButton" alignment="3" max="32767" attributes="1"/>
                   </Group>
-                  <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
               </Group>
               <EmptySpace max="-2" attributes="0"/>
           </Group>
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportFilter.java b/Report/src/org/sleuthkit/autopsy/report/reportFilter.java
index 2ecee61ef0ac45db7a92b31cf311daf1dbeeb6d1..f3404291f03e8e401ceab46d47d1914264f63117 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportFilter.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportFilter.java
@@ -106,26 +106,28 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
         layout.setHorizontalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             .addGroup(layout.createSequentialGroup()
+                .addGap(38, 38, 38)
                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                     .addGroup(layout.createSequentialGroup()
-                        .addGap(28, 28, 28)
                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                             .addComponent(jCheckBox3)
                             .addGroup(layout.createSequentialGroup()
                                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                     .addComponent(jCheckBox2)
-                                    .addComponent(jCheckBox1)
-                                    .addComponent(cancelButton))
+                                    .addComponent(jCheckBox1))
                                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                     .addComponent(jCheckBox5)
-                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                                        .addComponent(jCheckBox4)
-                                        .addComponent(progBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE))))))
+                                    .addComponent(jCheckBox4))))
+                        .addGap(69, 69, 69))
                     .addGroup(layout.createSequentialGroup()
-                        .addGap(106, 106, 106)
-                        .addComponent(jButton1)))
-                .addContainerGap(108, Short.MAX_VALUE))
+                        .addComponent(jButton1)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE)
+                        .addComponent(cancelButton)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(progBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(42, 42, 42)))
+                .addContainerGap())
         );
         layout.setVerticalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -141,12 +143,11 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
                 .addGap(18, 18, 18)
                 .addComponent(jCheckBox3)
                 .addGap(18, 18, 18)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addGroup(layout.createSequentialGroup()
-                        .addComponent(jButton1)
-                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
-                        .addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE))
-                    .addComponent(cancelButton))
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)
+                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                        .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                 .addContainerGap())
         );
     }// </editor-fold>//GEN-END:initComponents
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportHTML.java b/Report/src/org/sleuthkit/autopsy/report/reportHTML.java
index 4c764d06e0b873f3af05a066f1f8e0e31eb92a9a..350ac7300d5d376c4739f0617f20000d1b6d237f 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportHTML.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportHTML.java
@@ -5,7 +5,6 @@
 package org.sleuthkit.autopsy.report;
 
 import java.io.BufferedWriter;
-import java.io.File;
 import java.io.FileWriter;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -13,13 +12,16 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.ingest.IngestManager;
 import org.sleuthkit.datamodel.BlackboardArtifact;
 import org.sleuthkit.datamodel.BlackboardAttribute;
 import org.sleuthkit.datamodel.FsContent;
 import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.TskData;
 
 /**
  *
@@ -31,16 +33,65 @@ public class reportHTML {
     public static StringBuilder formatted_Report = new StringBuilder();
     public static String htmlPath = "";
 public reportHTML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> report, reportFilter rr){
-            
+    
+    //This is literally a terrible way to count up all the types of artifacts, and doesn't include any added ones. 
+    //Unlike the XML report, which is dynamic, this is formatted and needs to be redone later instead of being hardcoded.
+   
+      int countGen = 0;
+      int countWebBookmark = 0;
+      int countWebCookie = 0;
+      int countWebHistory = 0;
+      int countWebDownload = 0;
+      int countRecentObjects = 0;
+      int countTrackPoint = 0;
+      int countInstalled = 0;
+      int countKeyword = 0;
+      int countHash = 0;
+      for (Entry<BlackboardArtifact,ArrayList<BlackboardAttribute>> entry : report.entrySet()) {
+                    if(entry.getKey().getArtifactTypeID() == 1){  
+                        countGen++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 2){
+                        countWebBookmark++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 3){
+
+                        countWebCookie++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 4){
+
+                        countWebHistory++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 5){
+                         countWebDownload++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 6){
+                         countRecentObjects++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 7){
+                         countTrackPoint++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 8){
+                         countInstalled++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 9){
+                         countKeyword++;
+                    }
+                    if(entry.getKey().getArtifactTypeID() == 10){
+                         countHash++;
+                    } 
+    }
             
         try{
+            
+             String ingestwarning = "<h2 style=\"color: red;\">Warning, this report was run before ingest services completed!</h2>";
              Case currentCase = Case.getCurrentCase(); // get the most updated case
              SleuthkitCase skCase = currentCase.getSleuthkitCase();
              String caseName = currentCase.getName();
-             String rrpath = System.getProperty("user.dir");
-             rrpath = rrpath.substring(0, rrpath.length()-14);
-             rrpath = rrpath + "autopsy\\thirdparty\\";
              Integer imagecount = currentCase.getImageIDs().length;
+             Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
+             Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
+             int reportsize = report.size();
              Integer filesystemcount = currentCase.getRootObjectsCount();
              DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
              DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
@@ -68,20 +119,27 @@ public reportHTML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> re
             // Add summary information now
            
             formatted_Report.append("<h1>Report for Case: ").append(caseName).append("</h1>");
+            if(IngestManager.getDefault().isIngestRunning())
+            {
+                formatted_Report.append(ingestwarning);
+            }
             formatted_Report.append("<h2>Case Summary</h2><p>HTML Report Generated by <strong>Autopsy 3</strong> on ").append(datetime).append("<br /><ul>");
             formatted_Report.append("<li># of Images: ").append(imagecount).append("</li>");
             formatted_Report.append("<li>FileSystems: ").append(filesystemcount).append("</li>");
-            String tableHeader = "<table><thead><tr><th>Artifact ID</th><th>Name</th><th>Size</th><th>Attribute</th><th>Value</th></tr></thead><tbody>";
-             StringBuilder nodeGen = new StringBuilder("<h3>General Information</h3>" + tableHeader);
-             StringBuilder nodeWebBookmark =  new StringBuilder("<h3>Web Bookmarks</h3>" + tableHeader);
-             StringBuilder nodeWebCookie =  new StringBuilder("<h3>Web Cookies</h3>" + tableHeader);
-             StringBuilder nodeWebHistory =  new StringBuilder("<h3>Web History</h3>" + tableHeader);
-             StringBuilder nodeWebDownload =  new StringBuilder("<h3>Web Downloads</h3>" + tableHeader);
-             StringBuilder nodeRecentObjects =  new StringBuilder("<h3>Recent Documents</h3>" + tableHeader);
-             StringBuilder nodeTrackPoint =  new StringBuilder("<h3>Track Points</h3>" + tableHeader);
-             StringBuilder nodeInstalled =  new StringBuilder("<h3>Installed Programs</h3>" + tableHeader);
-             StringBuilder nodeKeyword =  new StringBuilder("<h3>Keyword Search Hits</h3>" + tableHeader);
-             StringBuilder nodeHash =  new StringBuilder("<h3>Hashset Hits</h3>" + tableHeader);
+            formatted_Report.append("<li># of Files: ").append(totalfiles.toString()).append("</li>");
+            formatted_Report.append("<li># of Dirs: ").append(totaldirs.toString()).append("</li>");
+            formatted_Report.append("<li># of Artifacts: ").append(reportsize).append("</li>");
+            String tableHeader = "<table><thead><tr>";
+             StringBuilder nodeGen = new StringBuilder("<h3>General Information (").append(countGen).append(")</h3>").append(tableHeader).append("<th>Attribute</th><th>Value</th></tr></thead><tbody>");
+             StringBuilder nodeWebBookmark =  new StringBuilder("<h3>Web Bookmarks (").append(countWebBookmark).append(")</h3>").append(tableHeader).append("<th>URL</th><th>Title</th><th>Program</th></tr></thead><tbody>");
+             StringBuilder nodeWebCookie =  new StringBuilder("<h3>Web Cookies (").append(countWebCookie).append(")</h3>").append(tableHeader).append("<th>URL</th><th>Date</th><th>Name</th><th>Value</th><th>Program</th></tr></thead><tbody>");
+             StringBuilder nodeWebHistory =  new StringBuilder("<h3>Web History (").append(countWebHistory).append(")</h3>").append(tableHeader).append("<th>URL</th><th>Date</th><th>Referrer</th><th>Title</th><th>Program</th></tr></thead><tbody>");
+             StringBuilder nodeWebDownload =  new StringBuilder("<h3>Web Downloads (").append(countWebDownload).append(")</h3>").append(tableHeader).append("<th>File</th><th>Source</th><th>Time</th><th>Program</th></tr></thead><tbody>");
+             StringBuilder nodeRecentObjects =  new StringBuilder("<h3>Recent Documents (").append(countRecentObjects).append(")</h3>").append(tableHeader).append("<th>Artifact ID</th><th>Name</th><th>Size</th><th>Name</th><th>Path</th></tr></thead><tbody>");
+             StringBuilder nodeTrackPoint =  new StringBuilder("<h3>Track Points (").append(countTrackPoint).append(")</h3>").append(tableHeader).append("<th>Artifact ID</th><th>Name</th><th>Size</th><th>Attribute</th><th>Value</th></tr></thead><tbody>");
+             StringBuilder nodeInstalled =  new StringBuilder("<h3>Installed Programs (").append(countInstalled).append(")</h3>").append(tableHeader).append("<th>Artifact ID</th><th>Name</th><th>Size</th><th>Attribute</th><th>Value</th></tr></thead><tbody>");
+             StringBuilder nodeKeyword =  new StringBuilder("<h3>Keyword Search Hits (").append(countKeyword).append(")</h3>");
+             StringBuilder nodeHash =  new StringBuilder("<h3>Hashset Hits (").append(countHash).append(")</h3>").append(tableHeader).append("<th>Artifact ID</th><th>Name</th><th>Size</th><th>Hashset Name</th></tr></thead><tbody>");
             
              for (Entry<BlackboardArtifact,ArrayList<BlackboardAttribute>> entry : report.entrySet()) {
                  if(reportFilter.cancel == true){
@@ -95,64 +153,103 @@ public reportHTML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> re
            
                 Long filesize = file.getSize();
                 
-               
-                
-                    // Get all the attributes for this guy
+                 
+                 TreeMap<Integer, String> attributes = new TreeMap<Integer,String>();
+                    // Get all the attributes, line them up to be added.
                      for (BlackboardAttribute tempatt : entry.getValue())
                          {
-                              if(reportFilter.cancel == true){
+                             if(reportFilter.cancel == true){
                                  break;
                                  }
-                          artifact.append("<tr><td>").append(objId.toString());
-                           artifact.append("</td><td><strong>").append(file.getName().toString()).append("</strong></td>");
-                            //artifact.append("Path: ").append(file.getParentPath());
-                            artifact.append("<td>").append(filesize.toString()).append("</td>");    
-                          StringBuilder attribute = new StringBuilder("<td>").append(tempatt.getAttributeTypeDisplayName()).append("</td>");
-                          attribute.append("<td>").append(tempatt.getValueString()).append("</td></tr>");
-                          //attribute.append("<li style=\"list-style-type: none;\"> Context:  ").append(tempatt.getContext()).append("</li>");
                           
-                          artifact.append(attribute);
+                         int type = tempatt.getAttributeTypeID();
+                         String value = tempatt.getValueString();
+                          attributes.put(type, value);
                           cc++;
                          }
-                    //artifact.append("</tr>");
+                     
+                    
                     if(entry.getKey().getArtifactTypeID() == 1){  
+                        
+                        artifact.append("</tr>");
                         nodeGen.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 2){
+                        artifact.append("<tr><td>").append(attributes.get(1)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(3)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(4)).append("</td>");
+                        artifact.append("</tr>");
                         nodeWebBookmark.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 3){
-
+                        artifact.append("<tr><td>").append(attributes.get(1)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(2)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(3)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(6)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(4)).append("</td>");
+                        artifact.append("</tr>");
                         nodeWebCookie.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 4){
-
+                        artifact.append("<tr><td>").append(attributes.get(1)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(2)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(32)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(3)).append("</td>");
+                        artifact.append("<td>").append(attributes.get(4)).append("</td>");
+                        artifact.append("</tr>");
                         nodeWebHistory.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 5){
+                         artifact.append("<tr><td>").append(attributes.get(8)).append("</td>");
+                         artifact.append("<td>").append(attributes.get(1)).append("</td>");  
+                         artifact.append("<td>").append(attributes.get(2)).append("</td>");  
+                         artifact.append("<td>").append(attributes.get(4)).append("</td>");   
+                         artifact.append("</tr>");
                          nodeWebDownload.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 6){
+                         artifact.append("<tr><td>").append(objId.toString());
+                         artifact.append("</td><td><strong>").append(file.getName().toString()).append("</strong></td>");
+                         artifact.append("<td>").append(filesize.toString()).append("</td>");  
+                         artifact.append("</tr>");
                          nodeRecentObjects.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 7){
+                         artifact.append("<tr><td>").append(objId.toString());
+                         artifact.append("</td><td><strong>").append(file.getName().toString()).append("</strong></td>");
+                         artifact.append("<td>").append(filesize.toString()).append("</td>");  
+                         artifact.append("</tr>");
                          nodeTrackPoint.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 8){
+                         artifact.append("<tr><td>").append(objId.toString());
+                         artifact.append("</td><td><strong>").append(file.getName().toString()).append("</strong></td>");
+                         artifact.append("<td>").append(filesize.toString()).append("</td>");  
+                         artifact.append("</tr>");
                          nodeInstalled.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 9){
-                         nodeKeyword.append(artifact);
+                         
+                       //  artifact.append("<table><thead><tr><th>Artifact ID</th><th>Name</th><th>Size</th>");
+                         
+                     //    artifact.append("</tr></table>");
+                     //    nodeKeyword.append(artifact);
                     }
                     if(entry.getKey().getArtifactTypeID() == 10){
+                         artifact.append("<tr><td>").append(objId.toString());
+                         artifact.append("</td><td><strong>").append(file.getName().toString()).append("</strong></td>");
+                         artifact.append("<td>").append(filesize.toString()).append("</td>");  
+                         //artifact.append("<td>").append(attributes.get(31)).append("</td>");
+                         artifact.append("<td>").append(attributes.get(30)).append("</td>");
+                         artifact.append("</tr>");
                          nodeHash.append(artifact);
                     } 
                     cc++;
                      rr.progBarSet(cc);
              }
             //Add them back in order
-            formatted_Report.append(nodeGen);
-            formatted_Report.append("</tbody></table>");
+            //formatted_Report.append(nodeGen);
+           // formatted_Report.append("</tbody></table>");
             formatted_Report.append(nodeWebBookmark);
             formatted_Report.append("</tbody></table>");
             formatted_Report.append(nodeWebCookie);
@@ -163,19 +260,25 @@ public reportHTML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> re
             formatted_Report.append("</tbody></table>");
             formatted_Report.append(nodeRecentObjects);
             formatted_Report.append("</tbody></table>");
-            formatted_Report.append(nodeTrackPoint);
-            formatted_Report.append("</tbody></table>");
+           // formatted_Report.append(nodeTrackPoint);
+            //formatted_Report.append("</tbody></table>");
             formatted_Report.append(nodeInstalled);
-            formatted_Report.append("</tbody></table>");
+            formatted_Report.append("</tbody></table>");           
             formatted_Report.append(nodeKeyword);
-            formatted_Report.append("</tbody></table>");
+            if(countKeyword > 0){
+            report keywords = new report();
+            formatted_Report.append(keywords.getGroupedKeywordHit());
+            // "<table><thead><tr><th>Artifact ID</th><th>Name</th><th>Size</th>
+           // formatted_Report.append("</tbody></table>");
+            }
+            
             formatted_Report.append(nodeHash); 
             formatted_Report.append("</tbody></table>");
             //end of master loop
             
                 formatted_Report.append("</div></div></body></html>");
                 
-                  htmlPath = currentCase.getCaseDirectory()+"/Temp/" + caseName + "-" + datenotime + ".html";
+                  htmlPath = currentCase.getCaseDirectory()+"/Reports/" + caseName + "-" + datenotime + ".html";
                    BufferedWriter out = new BufferedWriter(new FileWriter(htmlPath));
                    out.write(formatted_Report.toString());
                    
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportInterface.java b/Report/src/org/sleuthkit/autopsy/report/reportInterface.java
index d94b62e943f36000be37a9db6551b4e136f38ad3..ba8f3ef6f117d81b0d88a929ce91980f5c68ea11 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportInterface.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportInterface.java
@@ -22,4 +22,5 @@ public interface reportInterface{
     public HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> getRecentObject();
     public HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> getHashHit();
     public HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> getKeywordHit();
+    public String getGroupedKeywordHit();
 }
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanel.form b/Report/src/org/sleuthkit/autopsy/report/reportPanel.form
index 2f20df384e97caba177bf860dfc628503046de2d..39a8765e768ae30f9903db87e5081531b2d552c1 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportPanel.form
+++ b/Report/src/org/sleuthkit/autopsy/report/reportPanel.form
@@ -7,6 +7,9 @@
     <Component class="javax.swing.JOptionPane" name="jOptionPane1">
     </Component>
   </NonVisualComponents>
+  <Properties>
+    <Property name="focusTraversalPolicyProvider" type="boolean" value="true"/>
+  </Properties>
   <AccessibilityProperties>
     <Property name="AccessibleContext.accessibleName" type="java.lang.String" value=""/>
     <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.RADVisualComponent$AccessibleParentEditor">
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanel.java b/Report/src/org/sleuthkit/autopsy/report/reportPanel.java
index c32603aa97c1978127298497f0a92099cc728771..c03e38ccfe4fc2d5f67d9bfa6b911d1818381764 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportPanel.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportPanel.java
@@ -10,9 +10,11 @@
  */
 package org.sleuthkit.autopsy.report;
 import java.awt.event.ActionListener;
+import java.io.BufferedWriter;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.IOException;
-import javax.swing.filechooser.FileFilter;
+import org.jdom.output.XMLOutputter;
 
 /**
  *
@@ -42,6 +44,8 @@ private void initComponents() {
         jButton1 = new javax.swing.JButton();
         saveReport = new javax.swing.JButton();
 
+        setFocusTraversalPolicyProvider(true);
+
         jEditorPane1.setContentType(org.openide.util.NbBundle.getMessage(reportPanel.class, "reportPanel.jEditorPane1.contentType")); // NOI18N
         jEditorPane1.setEditable(false);
         jScrollPane1.setViewportView(jEditorPane1);
@@ -121,13 +125,19 @@ private void saveReportAction(){
     
     private void exportReport(String path){
         
-        path = reportUtils.changeExtension(path, ".html");
+       String htmlpath = reportUtils.changeExtension(path, ".html");
+       String xmlpath = reportUtils.changeExtension(path, ".xml");
          try {
-                  FileOutputStream out = new FileOutputStream(path);
+                  FileOutputStream out = new FileOutputStream(htmlpath);
                   out.write(reportHTML.formatted_Report.toString().getBytes());
                   out.flush();
                   out.close();
                   
+                  FileOutputStream xmlout = new FileOutputStream(xmlpath);
+                  XMLOutputter serializer = new XMLOutputter();
+                  serializer.output(reportXML.xmldoc, xmlout);
+                  xmlout.flush();
+                  xmlout.close();
                    jOptionPane1.showMessageDialog(this, "Report has been successfully saved!");
                 }
             catch (IOException e) {
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java b/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java
index a329131c0a4c381381b67d801cca393e26f98cc7..9d3dc3f8c537071d325b6b0f2ec6c4a76cc42c72 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java
@@ -97,7 +97,7 @@ public void actionPerformed(ActionEvent e) {
             // add the panel to the popup window
             popUpWindow.add(panel);
             popUpWindow.pack();
-            popUpWindow.setResizable(false);
+            popUpWindow.setResizable(true);
         
             // set the location of the popUp Window on the center of the screen
             Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
@@ -107,7 +107,7 @@ public void actionPerformed(ActionEvent e) {
          
             popUpWindow.setVisible(true);
             rr.progBarDone();
-            // add the command to close the window to the button on the Case Properties form / panel
+           
          }
         } catch (Exception ex) {
             Log.get(reportFilterAction.class).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
diff --git a/Report/src/org/sleuthkit/autopsy/report/reportXML.java b/Report/src/org/sleuthkit/autopsy/report/reportXML.java
index 87aeacb691ec28de3c5e376f6b1d4e16a0ca1a2e..6a25b35ba8a0a0887725420b41de883f95883649 100644
--- a/Report/src/org/sleuthkit/autopsy/report/reportXML.java
+++ b/Report/src/org/sleuthkit/autopsy/report/reportXML.java
@@ -19,6 +19,7 @@
 import org.jdom.Element;
 import org.jdom.output.XMLOutputter;
 import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.ingest.IngestManager;
 import org.sleuthkit.datamodel.BlackboardArtifact;
 import org.sleuthkit.datamodel.BlackboardAttribute;
 import org.sleuthkit.datamodel.Content;
@@ -27,8 +28,9 @@
 import org.sleuthkit.datamodel.File;
 import org.sleuthkit.datamodel.Image;
 import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.TskData;
 public class reportXML {
-    
+    public static Document xmldoc = new Document();
     public reportXML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> report, reportFilter rr){
         try{
          Case currentCase = Case.getCurrentCase(); // get the most updated case
@@ -36,8 +38,10 @@ public reportXML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> rep
          String caseName = currentCase.getName();
          Integer imagecount = currentCase.getImageIDs().length;
          Integer filesystemcount = currentCase.getRootObjectsCount();
+         Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
+         Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
          Element root = new Element("Case");
-         Document xmldoc = new Document(root);
+         xmldoc = new Document(root);
          DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
          DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
          Date date = new Date();
@@ -47,9 +51,15 @@ public reportXML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> rep
          root.addContent(comment);
          //Create summary node involving how many of each type
          Element summary = new Element("Summary");
+          if(IngestManager.getDefault().isIngestRunning())
+            {
+              summary.addContent(new Element("Warning").setText("Report was run before ingest services completed!"));
+            }
          summary.addContent(new Element("Name").setText(caseName));
          summary.addContent(new Element("Total-Images").setText(imagecount.toString()));
          summary.addContent(new Element("Total-FileSystems").setText(filesystemcount.toString()));
+         summary.addContent(new Element("Total-Files").setText(totalfiles.toString()));
+         summary.addContent(new Element("Total-Directories").setText(totaldirs.toString()));
          root.addContent(summary);
          //generate the nodes for each of the types so we can use them later
          Element nodeGen = new Element("General-Information");
@@ -145,7 +155,7 @@ public reportXML (HashMap<BlackboardArtifact,ArrayList<BlackboardAttribute>> rep
             root.addContent(nodeHash); 
          
             try {
-                  FileOutputStream out = new FileOutputStream(currentCase.getCaseDirectory()+"/Temp/" + caseName + "-" + datenotime + ".xml");
+                  FileOutputStream out = new FileOutputStream(currentCase.getCaseDirectory()+"/Reports/" + caseName + "-" + datenotime + ".xml");
                   XMLOutputter serializer = new XMLOutputter();
                   serializer.output(xmldoc, out);
                   out.flush();