diff --git a/Case/build.xml b/Case/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0cb0a367c5fc8f5e49a0dfce16592217666cb895
--- /dev/null
+++ b/Case/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.casemodule" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.casemodule.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard1_Help.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard1_Help.png
new file mode 100644
index 0000000000000000000000000000000000000000..d67d332c8e9dbfc49a6f851a945b2eac85ca5d36
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard1_Help.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard2_Help.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard2_Help.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9ce8ef80be10edfbcd59f82d4db440b0ead8648
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard2_Help.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard3_Help.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard3_Help.png
new file mode 100644
index 0000000000000000000000000000000000000000..876d5a789fe1d39d21e361f51d4896f7f86b665a
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/AddImageWizard3_Help.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/Autopsy_overview.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/Autopsy_overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2d854b0ba2fafb10f88b908aafc8f9af592a6a8
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/Autopsy_overview.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/CasePropertiesHelp.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/CasePropertiesHelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..04c1cdb0bb50fbbcda13d4242aef118230c3193f
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/CasePropertiesHelp.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/NewCaseWizardHelp.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/NewCaseWizardHelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f86132d9a8c03b86d7432ecde31a9da1381dd259
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/NewCaseWizardHelp.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html
new file mode 100644
index 0000000000000000000000000000000000000000..e941cd4eaab5440395a612bdcd9fb275c16bcad5
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html
@@ -0,0 +1,51 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>About Image</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Images</h2>
+        <p>
+            In Autopsy, an "Image" refers to the "Disk Image". Before an image can be analyzed, it must be added to a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.
+        </p>
+        <p>Autopsy creates a database for each image that it imports.  This database is a SQLite database and it contains all of the file system metadata from the image. When adding an image, it will take a little bit of time to populate the database. The database is stored in the case directory, but the image will stay in its original location.</p>
+        
+        <h2>Supported Formats</h2>
+        <p>
+            Currently, Autopsy only supports these formats of image:
+            <ul type="circle">
+                <li>Raw Single (For example: *.img, *.dd, etc)</li>
+                <li>Raw Split (For example: *.001, *.002, *.aa, *.ab, etc)</li>
+                <li>EnCase (For example: *.e01, *e02, etc)</li>
+            </ul>
+
+        <h2>Adding an Image</h2>
+        <p>
+            To see how to add image to the current opened case, click <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">here</a>.
+        </p>
+
+        <h2>Removing an Image</h2>
+        <p>
+            You can remove an image in the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/caseProperties.html">Case Properties</a> window.
+        </p>
+
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage-icon.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a36d4714ac9db8a3888ab2610bef2ab0cfbb6b7c
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage-icon.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage.html
new file mode 100644
index 0000000000000000000000000000000000000000..327a299e5215330a0f0c628fcd199e61cbd20808
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/addImage.html
@@ -0,0 +1,45 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Adding An Image</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Adding An Image</h2>
+        <p>
+            There are several ways to add an image to the currently opened case:
+            <ul type="circle">
+                <li>Go to "File" and select "Add Image..." </li>
+                <li>Select the <img src="addImage-icon.png" alt="Add Image Icon" /> icon on the toolbar</li>
+            </ul>
+
+        <p>
+            After that, a "Add Image" wizard dialog will show up. Then follow these following steps:</p>
+        <ul>
+            <li>Select "Image Type", then enter the "Image Path" to the image that you want to analyze (you can also use the "Browse" button to browse the location of your image). Also specify the timezone that you want. When everything is completed, press "Next" button.<br><br>
+            &nbsp; &nbsp; <img src="AddImageWizard1_Help.png" alt="Add Image Wizard Panel 1 Help" /> </li>
+            <li>Autopsy needs to analyze the image to populate its database with file system metadata. If you have configured hash databases, you will be given the option of looking up files in the hash database during the ingest.  Press the "Create Database" button to create the database. When the database creation process is done, you can press the "Next" button.<br><br>
+            &nbsp; &nbsp; <img src="AddImageWizard2_Help.png" alt="Add Image Wizard Panel 2 Help" /> </li>
+            <li>After the database is created, the image can be analyzed.  You will be given the option to add another image or start the analysis. <br><br>
+            &nbsp; &nbsp; <img src="AddImageWizard3_Help.png" alt="Add Image Wizard Panel 3 Help" /> </li>
+        </ul>
+        <p>Note that Autopsy will store the path to the image in its configuration file.  If the image moves, then Autopsy will give an error because it can't find the image file.
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/caseProperties.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/caseProperties.html
new file mode 100644
index 0000000000000000000000000000000000000000..4ce021926ddfa8987df99c1cbf32cba1163648e0
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/caseProperties.html
@@ -0,0 +1,48 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Case Properties Window</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Case Properties Window</h2>
+        <p>
+            Case Properties Window is the window where you can check some information about the currently opened case (case name, case creation date, case directory, and images in this case.
+            <br><br>
+            In this window, you can also do the following things:
+        <ul>
+            <li>Change/update the case name</li>
+            <li>Delete the current case</li>
+        <li>Remove image(s) from the current case</li>
+            </ul>
+
+        </p>
+        <h2>How to Open Case Properties Window</h2>
+        <p>
+            To open the "Case Properties" window, go to "File" and then select "Case Properties..." <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's an example of the "Case Properties" window: <br>
+            <img src="CasePropertiesHelp.png" alt="Case Properties Help" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..83243973f6c732ca5bac69be369657e08750289d
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html
@@ -0,0 +1,50 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>About Cases</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Cases</h2>
+        <p>
+            In Autopsy, a "case" is a container concept for a set of <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a>.  The set of images could be from multiple drives in a single computer or from multiple computers. When you make a case, it will create a directory to hold all of the information.  The directory will contain a configuration file, some databases, and some other information.
+        </p>
+
+        <h2>Creating a Case</h2>
+        <p>
+            Refer to the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/createNewCase.html">Creating a Case</a> page for more details.
+        </p>
+
+        <h2>Opening a Case</h2>
+        <p>
+            There are three ways to open a case:
+            <ul>
+                <li>Go to "File" and then select "Open Case..."</li>
+                <li>Select the <img src="open-icon.png" alt="Open Case Icon" /> icon on the toolbar</li>
+                <li>Press "Ctrl + O" on the keyboard</li>
+            </ul>
+        <p>
+            After that, a File Chooser dialog will show up. Then select a ".aut" file that you previously created.  It will be in the case folder.
+        </p>
+            
+        <h2>What's Next?</h2>
+        <p>After you create a case, you can <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/addImage.html">add an image</a> to the case. </p>
+        <p>If you want to view case details or edit some case information, use the <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/caseProperties.html">Case Properties</a> window.    
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-hs.xml b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-hs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..916e9d147e11fcabefecc8fc8017bd25309a7d1e
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-hs.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN" "http://java.sun.com/products/javahelp/helpset_2_0.dtd">
+<helpset version="2.0">
+    <title>Case Help</title>
+    <maps>
+        <homeID>org.sleuthkit.autopsy.casemodule.about</homeID>
+        <mapref location="casemodule-map.xml"/>
+    </maps>
+    <view mergetype="javax.help.AppendMerge">
+        <name>TOC</name>
+        <label>Table of Contents</label>
+        <type>javax.help.TOCView</type>
+        <data>casemodule-toc.xml</data>
+    </view>
+    <view mergetype="javax.help.AppendMerge">
+        <name>Index</name>
+        <label>Index</label>
+        <type>javax.help.IndexView</type>
+        <data>casemodule-idx.xml</data>
+    </view>
+    <view>
+        <name>Search</name>
+        <label>Search</label>
+        <type>javax.help.SearchView</type>
+        <data engine="com.sun.java.help.search.DefaultSearchEngine">JavaHelpSearch</data>
+    </view>
+</helpset>
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-idx.xml b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-idx.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7646264f4685982976069c782465e65da3e300a6
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-idx.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd">
+<index version="2.0">
+    <indexitem text="Overview" target="org.sleuthkit.autopsy.casemodule.overview"/>
+    <indexitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
+    <indexitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
+    <indexitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
+    <indexitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
+    <indexitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
+    <indexitem text="Hash Database Management" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>
+</index>
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-map.xml b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-map.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4a55d337ed92573a09fd43c16ccc8f7cdc74fff3
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE map PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN" "http://java.sun.com/products/javahelp/map_2_0.dtd">
+<map version="2.0">
+    <mapID target="org.sleuthkit.autopsy.casemodule.overview" url="overview.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.about" url="casemodule-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.how-to-create-case" url="createNewCase.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.image-about" url="aboutImage.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.add-image" url="addImage.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.caseproperties" url="caseProperties.html"/>
+    <mapID target="org.sleuthkit.autopsy.casemodule.hashdbmgmt" url="hashDbMgmt.html"/>
+</map>
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-toc.xml b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-toc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7c5be4fe0ff2887458e5d1c9013d3bd1ecf51cab
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/casemodule-toc.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE toc PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN" "http://java.sun.com/products/javahelp/toc_2_0.dtd">
+<toc version="2.0">
+    <tocitem text="Overview" target="org.sleuthkit.autopsy.casemodule.overview"/>
+    <tocitem text="Case Management">
+       <tocitem text="Case">
+            <tocitem text="About Cases" target="org.sleuthkit.autopsy.casemodule.about"/>
+            <tocitem text="Creating a Case" target="org.sleuthkit.autopsy.casemodule.how-to-create-case"/>
+       </tocitem>
+       <tocitem text="Image">
+            <tocitem text="About Images" target="org.sleuthkit.autopsy.casemodule.image-about"/>
+            <tocitem text="Adding an Image" target="org.sleuthkit.autopsy.casemodule.add-image"/>
+       </tocitem>
+       <tocitem text="Case Properties Window" target="org.sleuthkit.autopsy.casemodule.caseproperties"/>
+       <tocitem text="Hash Database Management Window" target="org.sleuthkit.autopsy.casemodule.hashdbmgmt"/>
+    </tocitem>
+</toc>
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/createNewCase.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/createNewCase.html
new file mode 100644
index 0000000000000000000000000000000000000000..5c0eac84268b3d880dd96dbf7d529c29a879679c
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/createNewCase.html
@@ -0,0 +1,43 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Creating A Case</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Creating a Case</h2>
+        <p>
+            There are several ways to create a new case:
+            <ul type="circle">
+                <li>Go to "File" and select "New Case..." </li>
+                <li>Select the <img src="new-icon.png" alt="New Case Icon" /> icon on the toolbar</li>
+                <li>Press "Ctrl + N" on the keyboard</li>
+            </ul>
+    </p>
+    
+    <p>The "New Case" wizard dialog will open and you will need to enter the case name and base directory.  Each case will have its own directory and the path of the directory is created by combining the "base directory" with the "case name". If the directory already exists, you will need to either delete the existing directory or choose a different combination of names.
+    </p>
+    <h2>Example:</h2>
+        <p>
+            Here's an example of the "New Case" wizard dialog: <br>
+            <img src="NewCaseWizardHelp.png" alt="New Case Wizard Help" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html
new file mode 100644
index 0000000000000000000000000000000000000000..aa613a88aa8aabbeb09304572b371e3902417714
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/hashDbMgmt.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Hash Database Management</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Hash Database Management Window</h2>
+        <p>
+	The Hash Database Management window is where you can set and update your hash database information. Hash databases are used to identify files that are 'known'. 
+	<ul>
+	<li>Known good files are those that can be safely ignored.  This set of files frequently includes standard OS and application files. </li>
+	<li>Known bad files are those that should raise awareness.  This set will vary depending on the type of investigation, but common examples include contraband images and malware.</li>
+	</ul>
+        </p>
+
+	<p>Autopsy allows for a single known bad hash database to be set and the <a href="http://www.nsrl.nist.gov">NIST NSRL</a>.  Before they can be used, an index of them must exist.  
+	The index can be directly copied in or it can be created within Autopsy.  When you select the database from within this window, it will tell you if the index needs to be created. Autopsy 
+	uses the hash database management system from The Sleuth Kit. You can manually create an index using the 'hfind' command line tool.</p>
+
+	<p>Note that the NSRL contains hashes of 'known files' that may be good or bad depending on your perspective and investigation type. For example, the existence of a piece of financial software
+	may be interesting to your investigation and that software could be in the NSRL. Therefore, Autopsy treats files that are found in the NSRL as simplyi 'known' and does not specify good or bad. </p>
+
+	<p>To use the NSRL, you must concatenate all of the NSRLFile.txt files together. You can use 'cat' on a Unix system or from within Cygwin to do this.</p>
+
+        <p>The 'known bad' hash database can be in the hashkeeper, md5sum, or NSRL format.</p>
+        
+	<p>Autopsy uses hash databases when the image is added to the case.  Each file is hashed and looked up in the configured databases.  If the file is found in the NSRL, then it will be marked as 
+	'known' in the case database.  If it is found in the known bad hash database, it will be marked as 'known bad' in the case database. </p>
+
+	<p>You can see the lookup results in a couple of places.  In the <a href="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html">File Search</a> data explorer, there is an option to choose the 'known status'. From here, you can do a search to see all 'known bad' files. 
+	From here, you can also choose to ignore all 'known' files that were found in the NSRL. You can also see the status of the file in a column when the file is listed. </p>
+        
+	<p>Currently, you cannot reprocess a disk image with a new hash database after it has been added to a case.</p>
+
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/new-icon.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/new-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..14206340e177dc0d06327438ca11fcff38ef706f
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/new-icon.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/open-icon.png b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/open-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d16e51b68287b10e230b6f6a25efe30e7b7b1dee
Binary files /dev/null and b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/open-icon.png differ
diff --git a/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/overview.html b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/overview.html
new file mode 100644
index 0000000000000000000000000000000000000000..3b3716d90f44821a30c4a6f335e331b4630b4f1a
--- /dev/null
+++ b/Case/javahelp/org/sleuthkit/autopsy/casemodule/docs/overview.html
@@ -0,0 +1,45 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Overview</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Overview</h2>
+        <p>
+            Autopsy allows you to conduct a digital forensic investigation.  It is a graphical interface to The Sleuth Kit and other open source tools. This page outlines the basic concepts of the program. The remainder of the help guide is organized around these concepts.
+        </p>
+
+        <p>All data is organized around the concept of a <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-about.html">case</a>.  A case can have one or more disk <a href="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/aboutImage.html">images</a> loaded into it.</p>
+
+        <p>The main window has three major areas:
+        <ul>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataexplorer-about.html">Data Explorers</a> (area 4 in figure below): This area is where you go find major analysis functionality.  It allows you to start finding the relevant files.</li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html">Result Viewers</a> (area 5 in figure below): This area is where the files and directories that were found from the explorer window can be viewed. There are different formatting options for the files.</li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/datacontent-about.html">Content Viewers</a> (area 6 in figure below): This area is where file content can be viewed after they are selected from the Result Viewer area.</li>
+        </ul>
+        </p>
+        <p>The main take away from this should be that analysis techniques can be found on the left-hand side, the results are always listed in the upper right, and the file contents are displayed in the lower left.
+
+        <p>
+            <img src="Autopsy_overview.png" alt="Autopsy Overview Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/Case/manifest.mf b/Case/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..9398c0dfecbd324eca7fe57e4564b02fb406a65c
--- /dev/null
+++ b/Case/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.casemodule/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/casemodule/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/casemodule/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager, org.netbeans.api.javahelp.Help
+
diff --git a/Case/nbproject/build-impl.xml b/Case/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..974323e28a996b5a04afcfbe0c60159261b22f3d
--- /dev/null
+++ b/Case/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.casemodule-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/Case/nbproject/genfiles.properties b/Case/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..df5eed5cb564226ac5055314fefc0efda1b3e40a
--- /dev/null
+++ b/Case/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=163956d6
+build.xml.script.CRC32=601bc2ba
+build.xml.stylesheet.CRC32=a56c6a5b@1.46.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=163956d6
+nbproject/build-impl.xml.script.CRC32=65e93a36
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.2
diff --git a/Case/nbproject/platform.properties b/Case/nbproject/platform.properties
new file mode 100644
index 0000000000000000000000000000000000000000..66c6f5bea1735632fb221e6605e8180135aec9fd
--- /dev/null
+++ b/Case/nbproject/platform.properties
@@ -0,0 +1,17 @@
+cluster.path=\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    org.jdesktop.layout,\
+    org.netbeans.api.visual,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.favorites,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+nbplatform.active=default
diff --git a/Case/nbproject/project.properties b/Case/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..08a83eb5ccb09e8388c623fec01b072452031e7f
--- /dev/null
+++ b/Case/nbproject/project.properties
@@ -0,0 +1,4 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+javahelp.hs=casemodule-hs.xml
+spec.version.base=0.0
diff --git a/Case/nbproject/project.xml b/Case/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f27f490015b2f5d33ce198d553073b518dae78ba
--- /dev/null
+++ b/Case/nbproject/project.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.jdesktop.beansbinding</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.11.1.121</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.15.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.47.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.text</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <test-dependencies>
+                <test-type>
+                    <name>unit</name>
+                    <test-dependency>
+                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                </test-type>
+            </test-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.casemodule</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/Case/nbproject/suite.properties b/Case/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/Case/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ecd7912922b9df35ec15ba0b3d3e98a55ef0f3f
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageAction.java
@@ -0,0 +1,304 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.awt.Dialog;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.DialogDisplayer;
+import org.openide.WizardDescriptor;
+import org.openide.util.ChangeSupport;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
+
+/**
+ * The action to add an image to the current Case. This action should be disabled
+ * on creation and it will be enabled on new case creation or case opened.
+ *
+ * @author jantonius
+ */
+// TODO: need annotation because there's a "Lookup.getDefault().lookup(AddImageAction.class)"
+// used in AddImageWizardPanel1 (among other places). It really shouldn't be done like that.
+@ServiceProvider(service = AddImageAction.class)
+public final class AddImageAction extends CallableSystemAction implements Presenter.Toolbar {
+
+    // Keys into the WizardDescriptor properties that pass information between stages of the wizard
+    // <TYPE>: <DESCRIPTION>
+    // String: time zone that the image is from
+    static final String TIMEZONE_PROP = "timeZone";
+    // String[]: task to clean up the database file if wizard errors/is cancelled after it is created
+    static final String IMGPATHS_PROP = "imgPaths";
+    // CleanupTask: task to clean up the database file if wizard errors/is cancelled after it is created
+    static final String IMAGECLEANUPTASK_PROP = "finalFileCleanup";
+    // int: the next availble id for a new image
+    static final String IMAGEID_PROP = "imageId";
+    // AddImageProcess: the next availble id for a new image
+    static final String PROCESS_PROP = "process";
+
+
+    private WizardDescriptor wizardDescriptor;
+    private WizardDescriptor.Iterator<WizardDescriptor> iterator;
+    private Dialog dialog;
+    private JButton toolbarButton = new JButton();
+
+    /**
+     * The constructor for AddImageAction class
+     */
+    public AddImageAction() {
+        putValue(Action.NAME, NbBundle.getMessage(AddImageAction.class, "CTL_AddImage")); // set the action Name
+
+        // set the action for the toolbar button
+        toolbarButton.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                AddImageAction.this.actionPerformed(e);
+            }
+        });
+
+        this.setEnabled(false); // disable this action class
+    }
+
+    /**
+     * Pop-up the "Add Image" wizard panel.
+     * 
+     * @param e
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(AddImageAction.class);
+
+        iterator = new AddImageWizardIterator(this);
+        wizardDescriptor = new WizardDescriptor(iterator);
+        wizardDescriptor.setTitle("Add Image");
+        wizardDescriptor.putProperty(NAME, e);
+
+
+        if (dialog != null) {
+            dialog.setVisible(false); // hide the old one
+        }
+        dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
+        dialog.setVisible(true);
+        dialog.toFront();
+
+        boolean cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION;
+        // @@@ Why don't we commit and revert in the same general area????
+        if (!cancelled) {
+            // commit anything
+            try {
+                commitImage(wizardDescriptor);
+            } catch (Exception ex) {
+                // Log error/display warning
+                Logger logger = Logger.getLogger(AddImageAction.class.getName());
+                logger.log(Level.SEVERE, "Error adding image to case.", ex);
+            }
+        }
+        
+        // Do any cleanup that needs to happen (potentially: stopping the
+        //add-image process, reverting an image)
+        runCleanupTasks();
+    }
+
+    /**
+     * Commit the finished AddImageProcess, and cancel the CleanupTask that
+     * would have reverted it.
+     * @param settings property set to get AddImageProcess and CleanupTask from
+     * @throws Exception if commit or adding the image to the case failed
+     */
+    private void commitImage(WizardDescriptor settings) throws Exception {
+        
+        String[] imgPaths = (String[]) settings.getProperty(AddImageAction.IMGPATHS_PROP);
+        String timezone = settings.getProperty(AddImageAction.TIMEZONE_PROP).toString();
+        
+        AddImageProcess process = (AddImageProcess) settings.getProperty(PROCESS_PROP);
+        
+        try {
+            long imageId = process.commit();
+            Case.getCurrentCase().addImage(imgPaths, imageId, timezone);
+        } finally {
+            // Can't bail and revert image add after commit, so disable image cleanup
+            // task
+            CleanupTask cleanupImage = (CleanupTask) settings.getProperty(IMAGECLEANUPTASK_PROP);
+            cleanupImage.disable();
+        }
+    }
+
+    /**
+     * Closes the current dialog and wizard, and opens a new one. Used in the
+     * "Add another image" action on the last panel
+     */
+    public void restart() {
+        // Simulate clicking finish for the current dialog
+        wizardDescriptor.setValue(WizardDescriptor.FINISH_OPTION);
+        dialog.setVisible(false);
+
+
+        // let the previous call to AddImageAction.actionPerformed() finish up
+        // after the wizard, this will run when its it's done
+        SwingUtilities.invokeLater(new Runnable() {
+
+            @Override
+            public void run() {
+                actionPerformed(null);
+            }
+        });
+    }
+
+    /**
+     * This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
+     */
+    @Override
+    public void performAction() {
+    }
+
+    /**
+     * Gets the name of this action. This may be presented as an item in a menu.
+     *
+     * @return actionName
+     */
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(AddImageAction.class, "CTL_AddImage");
+    }
+
+    /**
+     * Gets the HelpCtx associated with implementing object
+     *
+     * @return HelpCtx or HelpCtx.DEFAULT_HELP
+     */
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    /**
+     * Returns the toolbar component of this action
+     * 
+     * @return component  the toolbar button
+     */
+    @Override
+    public Component getToolbarPresenter() {
+        ImageIcon icon = new ImageIcon(getClass().getResource("addImage-icon.png"));
+        toolbarButton.setIcon(icon);
+        return toolbarButton;
+    }
+
+    /**
+     * Set this action to be enabled/disabled
+     *
+     * @param value  whether to enable this action or not
+     */
+    @Override
+    public void setEnabled(boolean value) {
+        super.setEnabled(value);
+        toolbarButton.setEnabled(value);
+    }
+
+    /**
+     * Set the focus to the button of the given name on this wizard dialog.
+     *
+     * Note: the name of the buttons that available are "Next >", "< Back",
+     * "Cancel", and "Finish". If you change the name of any of those buttons,
+     * use the latest name instead.
+     *
+     * @param buttonText  the text of the button
+     */
+    public void requestFocusButton(String buttonText) {
+        // get all buttons on this wizard panel
+        Object[] wizardButtons = wizardDescriptor.getOptions();
+        for (int i = 0; i < wizardButtons.length; i++) {
+            JButton tempButton = (JButton) wizardButtons[i];
+            if (tempButton.getText().equals(buttonText)) {
+                tempButton.setDefaultCapable(true);
+                tempButton.requestFocus();
+            }
+        }
+    }
+    
+    /**
+     * Run and clear any cleanup tasks for wizard closing that might be
+     * registered. This should be run even when the wizard exits cleanly, so
+     * that no cleanup actions remain the next time the wizard is run.
+     */
+    private void runCleanupTasks() {
+        cleanupSupport.fireChange();
+    }
+    
+    ChangeSupport cleanupSupport = new ChangeSupport(this);
+
+    /**
+     * Instances of this class implement the cleanup() method to run cleanup
+     * code when the wizard exits.
+     * 
+     * After enable() has been called on an instance it will run once after the
+     * wizard closes (on both a cancel and a normal finish).
+     * 
+     * If disable() is called before the wizard exits, the task will not run.
+     */
+    abstract class CleanupTask implements ChangeListener {
+
+        @Override
+        public void stateChanged(ChangeEvent e) {
+            // fired by AddImageAction.runCleanupTasks() after the wizard closes 
+            try {
+                cleanup();
+            } catch (Exception ex) {
+                Logger logger = Logger.getLogger(this.getClass().getName());
+                logger.log(Level.WARNING, "Error cleaning up from wizard.", ex);
+            } finally {
+                disable(); // cleanup tasks should only run once.
+            }
+        }
+
+        /**
+         * Add task to the enabled list to run when the wizard closes.
+         */
+        public void enable() {
+            cleanupSupport.addChangeListener(this);
+        }
+
+        /**
+         * Performs cleanup action when called
+         * @throws Exception 
+         */
+        abstract void cleanup() throws Exception;
+
+        /**
+         * Remove task from the enabled list.
+         */
+        public void disable() {
+            cleanupSupport.removeChangeListener(this);
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form
new file mode 100644
index 0000000000000000000000000000000000000000..fad3b1db959dac87e2b5fe40ca8f19e15572e4c1
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.form
@@ -0,0 +1,205 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <NonVisualComponents>
+    <Component class="javax.swing.ButtonGroup" name="buttonGroup1">
+    </Component>
+  </NonVisualComponents>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="imgTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="10" pref="10" max="10" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="rawSplit" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="rawSingle" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="encase" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <Component id="multipleSelectLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="imgPathLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                      <Component id="imgPathTextField" pref="415" max="32767" attributes="1"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="imgPathBrowserButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Component id="imgInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="timeZoneLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
+                      <Component id="timeZoneComboBox" min="-2" pref="315" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="imgInfoLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
+              <Component id="imgTypeLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="rawSingle" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="rawSplit" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="encase" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="imgPathLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="imgPathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="imgPathBrowserButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="multipleSelectLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="1" attributes="0">
+                  <Component id="timeZoneLabel" min="-2" max="-2" attributes="0"/>
+                  <Component id="timeZoneComboBox" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace pref="26" max="32767" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JRadioButton" name="rawSingle">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.rawSingle.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="requestFocusEnabled" type="boolean" value="false"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rawSingleActionPerformed"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="10"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JRadioButton" name="rawSplit">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.rawSplit.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="requestFocusEnabled" type="boolean" value="false"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rawSplitActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgTypeLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.imgTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JRadioButton" name="encase">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.encase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="requestFocusEnabled" type="boolean" value="false"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="encaseActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgPathLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.imgPathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="multipleSelectLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.multipleSelectLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="imgPathTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.imgPathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="10"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JButton" name="imgPathBrowserButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.imgPathBrowserButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="imgPathBrowserButtonActionPerformed"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="this.imgPathBrowserButton.setDefaultCapable(true);&#xd;&#xa;this.imgPathBrowserButton.requestFocus();"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgInfoLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.imgInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+          <Color blue="33" green="0" red="ff" type="rgb"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JComboBox" name="timeZoneComboBox">
+      <Properties>
+        <Property name="maximumRowCount" type="int" value="30"/>
+        <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+          <StringArray count="0"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="timeZoneLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel1.timeZoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d9576184884ae7898e82b979f60efd119a07213
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel1.java
@@ -0,0 +1,493 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+import javax.swing.event.DocumentEvent;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.JFileChooser;
+import javax.swing.JPanel;
+import javax.swing.event.DocumentListener;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+
+/**
+ * The "Add Image" wizard panel 1. This class is used to design the "form" of
+ * the panel 1 for "Add Image" wizard panel.
+ *
+ * @author jantonius
+ */
+final class AddImageVisualPanel1 extends JPanel implements DocumentListener {
+
+    private JFileChooser fc = new JFileChooser();
+    private FileFilter filter;
+    private final String[] imgExt = {".img", ".dd"};
+    private final String imgDesc = "Raw Images (*.img, *.dd)";
+    private GeneralFilter imgFilter = new GeneralFilter(imgExt, imgDesc, false);
+    private final String[] splitExt = {".*\\.[0-9][0-9][0-9]", ".*\\.[a-z][a-z]"};
+    private final String splitDesc = "Split Part (*.001, *.002, etc)";
+    private GeneralFilter splitFilter = new GeneralFilter(splitExt, splitDesc, true);
+    private final String[] encasExt = {".*\\.e[0-9][0-9]", ".*\\.e[a-z][a-z]"};
+    private final String encaseDesc = "Encase Images (*.e01, *.eAA)";
+    private GeneralFilter encaseFilter = new GeneralFilter(encasExt, encaseDesc, true);
+    private boolean multi = false;
+    private AddImageWizardPanel1 wizPanel;
+
+    /**
+     * Creates new form AddImageVisualPanel1
+     * @param wizPanel corresponding WizardPanel to handle logic of wizard step
+     */
+    AddImageVisualPanel1(AddImageWizardPanel1 wizPanel) {
+        initComponents();
+        this.wizPanel = wizPanel;
+        fc.setDragEnabled(multi);
+        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+        fc.setMultiSelectionEnabled(multi);
+        fc.addChoosableFileFilter(imgFilter);
+        filter = imgFilter;
+        buttonGroup1.add(encase);
+        buttonGroup1.add(rawSingle);
+        buttonGroup1.add(rawSplit);
+        imgPathTextField.getDocument().addDocumentListener(this);
+        imgPathTextField.setText("");
+        jLabel1.setText("");
+        rawSingle.setSelected(true);
+        rawSplit.setSelected(false);
+        encase.setSelected(false);
+        createTimeZoneList();
+    }
+
+    /**
+     * Returns the name of the this panel. This name will be shown on the left
+     * panel of the "Add Image" wizard panel.
+     *
+     * @return name  the name of this panel
+     */
+    @Override
+    public String getName() {
+        return "Enter Image Information";
+    }
+
+    /**
+     * Gets the array of image paths from the Image Path Text Field.
+     *
+     * @return imagePaths  the array of image paths
+     */
+    public String[] getImagePaths() {
+        String[] imgPath = Case.convertImgPath(imgPathTextField.getText());
+        if (Case.checkMultiplePathExist(imgPath)) {
+            return imgPath;
+        } else {
+            return new String[0];
+        }
+    }
+
+    /**
+     * Gets the type of the image that's selected.
+     *
+     * @return imgType  the type of the image that selected
+     */
+    public String getImgType() {
+        if (rawSingle.isSelected()) {
+            return "Raw Single";
+        }
+        if (rawSplit.isSelected()) {
+            return "Raw Split";
+        }
+        if (encase.isSelected()) {
+            return "EnCase";
+        } else {
+            return "Nothing Selected";
+        }
+    }
+
+    /**
+     * Gets the time zone that selected on the drop down list.
+     *
+     * @return timeZone  the time zone that selected
+     */
+    public String getSelectedTimezone() {
+        String tz = timeZoneComboBox.getSelectedItem().toString();
+        return tz.substring(tz.indexOf(")") + 2).trim();
+    }
+
+    // add the timeZone list to the timeZoneComboBox
+    /**
+     * Creates the drop down list for the time zones and then makes the local
+     * machine time zones to be selected.
+     */
+    public void createTimeZoneList() {
+        // load and add all timezone
+        String[] ids = SimpleTimeZone.getAvailableIDs();
+        for (String id : ids) {
+            TimeZone zone = TimeZone.getTimeZone(id);
+            int offset = zone.getRawOffset() / 1000;
+            int hour = offset / 3600;
+            int minutes = (offset % 3600) / 60;
+            String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id);
+
+            /*
+            DateFormat dfm = new SimpleDateFormat("z");
+            dfm.setTimeZone(zone);
+            boolean hasDaylight = zone.useDaylightTime();
+            String first = dfm.format(new Date(2010, 1, 1));
+            String second = dfm.format(new Date(2011, 6, 6));
+            int mid = hour * -1;
+            String result = first + Integer.toString(mid);
+            if(hasDaylight){
+            result = result + second;
+            }
+            timeZoneComboBox.addItem(item + " (" + result + ")");
+             */
+            timeZoneComboBox.addItem(item);
+        }
+        // get the current timezone
+        TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
+        int thisOffset = thisTimeZone.getRawOffset() / 1000;
+        int thisHour = thisOffset / 3600;
+        int thisMinutes = (thisOffset % 3600) / 60;
+        String formatted = String.format("(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID());
+
+        // set the selected timezone
+        timeZoneComboBox.setSelectedItem(formatted);
+    }
+
+    /** 
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        buttonGroup1 = new javax.swing.ButtonGroup();
+        rawSingle = new javax.swing.JRadioButton();
+        rawSplit = new javax.swing.JRadioButton();
+        imgTypeLabel = new javax.swing.JLabel();
+        encase = new javax.swing.JRadioButton();
+        imgPathLabel = new javax.swing.JLabel();
+        multipleSelectLabel = new javax.swing.JLabel();
+        imgPathTextField = new javax.swing.JTextField();
+        imgPathBrowserButton = new javax.swing.JButton();
+        this.imgPathBrowserButton.setDefaultCapable(true);
+        this.imgPathBrowserButton.requestFocus();
+        imgInfoLabel = new javax.swing.JLabel();
+        jLabel1 = new javax.swing.JLabel();
+        timeZoneComboBox = new javax.swing.JComboBox();
+        timeZoneLabel = new javax.swing.JLabel();
+
+        org.openide.awt.Mnemonics.setLocalizedText(rawSingle, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.rawSingle.text")); // NOI18N
+        rawSingle.setRequestFocusEnabled(false);
+        rawSingle.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                rawSingleActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(rawSplit, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.rawSplit.text")); // NOI18N
+        rawSplit.setRequestFocusEnabled(false);
+        rawSplit.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                rawSplitActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(imgTypeLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.imgTypeLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(encase, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.encase.text")); // NOI18N
+        encase.setRequestFocusEnabled(false);
+        encase.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                encaseActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(imgPathLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.imgPathLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(multipleSelectLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.multipleSelectLabel.text")); // NOI18N
+
+        imgPathTextField.setText(org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.imgPathTextField.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(imgPathBrowserButton, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.imgPathBrowserButton.text")); // NOI18N
+        imgPathBrowserButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                imgPathBrowserButtonActionPerformed(evt);
+            }
+        });
+
+        imgInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 14));
+        org.openide.awt.Mnemonics.setLocalizedText(imgInfoLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.imgInfoLabel.text")); // NOI18N
+
+        jLabel1.setForeground(new java.awt.Color(255, 0, 51));
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.jLabel1.text")); // NOI18N
+
+        timeZoneComboBox.setMaximumRowCount(30);
+
+        org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel1.class, "AddImageVisualPanel1.timeZoneLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(imgTypeLabel)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(10, 10, 10)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(rawSplit)
+                            .addComponent(rawSingle)
+                            .addComponent(encase)))
+                    .addComponent(multipleSelectLabel)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(imgPathLabel)
+                        .addGap(18, 18, 18)
+                        .addComponent(imgPathTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 415, Short.MAX_VALUE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(imgPathBrowserButton))
+                    .addComponent(imgInfoLabel)
+                    .addComponent(jLabel1)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(timeZoneLabel)
+                        .addGap(10, 10, 10)
+                        .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 315, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(imgInfoLabel)
+                .addGap(19, 19, 19)
+                .addComponent(imgTypeLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(rawSingle)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(rawSplit)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(encase)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(imgPathLabel)
+                    .addComponent(imgPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(imgPathBrowserButton))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(multipleSelectLabel)
+                .addGap(18, 18, 18)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(timeZoneLabel)
+                    .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 26, Short.MAX_VALUE)
+                .addComponent(jLabel1)
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * When the "rawSingle" radio button is selected.
+     *
+     * @param evt  the action event
+     */
+    private void rawSingleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rawSingleActionPerformed
+        rawSingle.setSelected(true);
+        rawSplit.setSelected(false);
+        encase.setSelected(false);
+        multipleSelectLabel.setText("Single Image: Multiple Select Disabled");
+        filter = imgFilter;
+        multi = false;
+        this.updateUI(null);
+}//GEN-LAST:event_rawSingleActionPerformed
+
+    /**
+     * When the "rawSplit" radio button is selected.
+     *
+     * @param evt  the action event
+     */
+    private void rawSplitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rawSplitActionPerformed
+        rawSingle.setSelected(false);
+        rawSplit.setSelected(true);
+        encase.setSelected(false);
+        multipleSelectLabel.setText("Split Image: Multiple Select Enabled. Use Ctrl, Shift, "
+                + "or Drag to select multiple image parts");
+        filter = splitFilter;
+        multi = true;
+        updateUI(null);
+}//GEN-LAST:event_rawSplitActionPerformed
+
+    /**
+     * When the "encase" radio button is selected.
+     *
+     * @param evt  the action event
+     */
+    private void encaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_encaseActionPerformed
+        rawSingle.setSelected(false);
+        rawSplit.setSelected(false);
+        encase.setSelected(true);
+        multipleSelectLabel.setText("EnCase Image: Multiple Select Enabled. Use Ctrl, Shift, "
+                + "or Drag to select multiple image parts");
+        filter = encaseFilter;
+        multi = true;
+        updateUI(null);
+}//GEN-LAST:event_encaseActionPerformed
+
+    /**
+     * When the "Browse" button is pressed, open the file chooser window to
+     * select the images.
+     *
+     * @param evt  the action event
+     */
+    private void imgPathBrowserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_imgPathBrowserButtonActionPerformed
+        fc.resetChoosableFileFilters();
+        fc.addChoosableFileFilter(filter);
+        fc.setFileFilter(filter);
+        fc.setMultiSelectionEnabled(multi);
+        fc.setDragEnabled(multi);
+
+        // set the current directory of the FileChooser if the ImagePath Field is valid
+        File currentDir = new File(imgPathTextField.getText());
+        if (currentDir.exists()) {
+            fc.setCurrentDirectory(currentDir);
+        }
+
+        int retval = fc.showOpenDialog(this);
+        if (retval == JFileChooser.APPROVE_OPTION) {
+            File[] files = fc.getSelectedFiles();
+            String path = "";
+            if (multi) {
+                for (File file : files) {
+                    path = path + "\"" + file.getPath() + "\" ";
+                }
+                imgPathTextField.setText(path);
+            } else {
+                path = fc.getSelectedFile().getPath();
+                imgPathTextField.setText(path);
+            }
+        }
+}//GEN-LAST:event_imgPathBrowserButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.ButtonGroup buttonGroup1;
+    private javax.swing.JRadioButton encase;
+    private javax.swing.JLabel imgInfoLabel;
+    private javax.swing.JButton imgPathBrowserButton;
+    private javax.swing.JLabel imgPathLabel;
+    private static javax.swing.JTextField imgPathTextField;
+    private javax.swing.JLabel imgTypeLabel;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel multipleSelectLabel;
+    private static javax.swing.JRadioButton rawSingle;
+    private javax.swing.JRadioButton rawSplit;
+    private javax.swing.JComboBox timeZoneComboBox;
+    private javax.swing.JLabel timeZoneLabel;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Gives notification that there was an insert into the document.  The
+     * range given by the DocumentEvent bounds the freshly inserted region.
+     *
+     * @param e the document event
+     */
+    @Override
+    public void insertUpdate(DocumentEvent e) {
+        updateUI(e);
+    }
+
+    /**
+     * Gives notification that a portion of the document has been
+     * removed.  The range is given in terms of what the view last
+     * saw (that is, before updating sticky positions).
+     *
+     * @param e the document event
+     */
+    @Override
+    public void removeUpdate(DocumentEvent e) {
+        updateUI(e);
+    }
+
+    /**
+     * Gives notification that an attribute or set of attributes changed.
+     *
+     * @param e the document event
+     */
+    @Override
+    public void changedUpdate(DocumentEvent e) {
+        updateUI(e);
+    }
+
+    /**
+     * The "listener" that updates the UI of this panel based on the changes of
+     * fields on this panel. This is also the method to check whether all the
+     * fields on this panel are correctly filled and decides whether to enable
+     * the "Next" button or not.
+     * 
+     * @param e  the document event
+     */
+    public void updateUI(DocumentEvent e) {
+        String[] imgPath = Case.convertImgPath(imgPathTextField.getText());
+        boolean isExist = Case.checkMultiplePathExist(imgPath);
+        File imgFile = new File(imgPath[0]);
+
+        // check if the given paths exist and those are paths to image files
+        boolean isImagePath = true;
+        for (int i = 0; i < imgPath.length; i++) {
+            File tempImgFile = new File(imgPath[i]);
+            isImagePath = isImagePath && tempImgFile.exists() && !tempImgFile.isDirectory()
+                    && (imgFilter.accept(tempImgFile) || splitFilter.accept(tempImgFile)
+                    || encaseFilter.accept(tempImgFile));
+        }
+
+
+        if (isImagePath) {
+            Case currentCase = Case.getCurrentCase();
+            File dbFile = new File(currentCase.getCaseDirectory() + File.separator + imgFile.getName() + ".db");
+
+            if (dbFile.exists()) {
+                String dbExist = "This database already exists. Do you want to overwrite the database?";
+                NotifyDescriptor d = new NotifyDescriptor.Confirmation(dbExist, "Warning: Overwrite Database", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+                d.setValue(NotifyDescriptor.NO_OPTION);
+
+                isExist = false;
+
+                Object res = DialogDisplayer.getDefault().notify(d);
+                if (res != null && res == DialogDescriptor.YES_OPTION) {
+                    isExist = dbFile.delete();
+                    if (!isExist) {
+                        jLabel1.setText("*Database for this image is already created and it can't be deleted because it's being used.");
+                    }
+                }
+                if (res != null && res == DialogDescriptor.NO_OPTION) {
+                    jLabel1.setText("*Database for this image exist. Either delete it or select another image.");
+                }
+            }
+        } else {
+            isExist = false;
+        }
+
+        if (isExist) {
+            jLabel1.setText("");
+        }
+
+        this.wizPanel.enableNextButton(isExist);
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.form b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.form
new file mode 100644
index 0000000000000000000000000000000000000000..ddac189bc62c1681a0f7ddb586a0b651e3296cb1
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.form
@@ -0,0 +1,122 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="crDbLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Group type="102" alignment="0" attributes="0">
+                              <Component id="crDbButton" min="-2" max="-2" attributes="0"/>
+                              <EmptySpace min="189" pref="189" max="189" attributes="0"/>
+                          </Group>
+                          <Component id="jLabel5" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="crDbProgressBar" alignment="0" pref="292" max="32767" attributes="1"/>
+                      </Group>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="progressLabel" pref="272" max="32767" attributes="0"/>
+                  </Group>
+                  <Component id="jLabel1" alignment="0" min="-2" pref="552" max="-2" attributes="1"/>
+                  <Component id="lookupFilesCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="crDbLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="lookupFilesCheckBox" min="-2" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace min="-2" pref="80" max="-2" attributes="0"/>
+                      <Component id="progressLabel" min="-2" pref="12" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="crDbButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="30" max="-2" attributes="0"/>
+                      <Component id="jLabel5" min="-2" pref="14" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="crDbProgressBar" min="-2" pref="24" max="-2" attributes="1"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JProgressBar" name="crDbProgressBar">
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel5">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.jLabel5.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="crDbLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.crDbLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="progressLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.progressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="crDbButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.crDbButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="crDbButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="lookupFilesCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel2.lookupFilesCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.java
new file mode 100644
index 0000000000000000000000000000000000000000..8897c88e2288942cf3dfed787ae46de38b2f6ed1
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel2.java
@@ -0,0 +1,181 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Color;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JProgressBar;
+
+/**
+ * The "Add Image" wizard panel 2. Provides checkbox to enable indexing, button
+ * to start process, and progress bar.
+ */
+final class AddImageVisualPanel2 extends JPanel {
+
+    /** Creates new form AddImageVisualPanel2 */
+    AddImageVisualPanel2() {
+        initComponents();
+    }
+
+    /**
+     * Returns the name of the this panel. This name will be shown on the left
+     * panel of the "Add Image" wizard panel.
+     *
+     * @return name  the name of this panel
+     */
+    @Override
+    public String getName() {
+        return "Create Database";
+    }
+
+    public JButton getCrDbButton() {
+        return this.crDbButton;
+    }
+
+    public JProgressBar getCrDbProgressBar() {
+        return this.crDbProgressBar;
+    }
+
+    public JLabel getProgressLabel() {
+        return this.progressLabel;
+    }
+    
+    public JCheckBox getLookupFilesCheckbox() {
+        return this.lookupFilesCheckBox;
+    }
+
+    /**
+     * Changes the progress bar text and color.
+     *
+     * @param text   the text to be shown
+     * @param value  the current value of the progress bar
+     * @param color  the color of the progress bar text
+     */
+    public void changeProgressBarTextAndColor(String text, int value, Color color) {
+        progressLabel.setText(text);
+        progressLabel.setForeground(color);
+        crDbProgressBar.setValue(value);
+    }
+
+    /** 
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always 
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        crDbProgressBar = new javax.swing.JProgressBar();
+        jLabel5 = new javax.swing.JLabel();
+        crDbLabel = new javax.swing.JLabel();
+        progressLabel = new javax.swing.JLabel();
+        crDbButton = new javax.swing.JButton();
+        jLabel1 = new javax.swing.JLabel();
+        lookupFilesCheckBox = new javax.swing.JCheckBox();
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel5, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.jLabel5.text")); // NOI18N
+
+        crDbLabel.setFont(new java.awt.Font("Tahoma", 1, 14));
+        org.openide.awt.Mnemonics.setLocalizedText(crDbLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.crDbLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.progressLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(crDbButton, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.crDbButton.text")); // NOI18N
+        crDbButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                crDbButtonActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.jLabel1.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(lookupFilesCheckBox, org.openide.util.NbBundle.getMessage(AddImageVisualPanel2.class, "AddImageVisualPanel2.lookupFilesCheckBox.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(crDbLabel)
+                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addGroup(layout.createSequentialGroup()
+                                        .addComponent(crDbButton)
+                                        .addGap(189, 189, 189))
+                                    .addComponent(jLabel5)
+                                    .addComponent(crDbProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 272, Short.MAX_VALUE))
+                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 552, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addContainerGap())
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(lookupFilesCheckBox)
+                        .addContainerGap(407, Short.MAX_VALUE))))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(crDbLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(lookupFilesCheckBox)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(80, 80, 80)
+                        .addComponent(progressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(crDbButton)
+                        .addGap(30, 30, 30)
+                        .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(crDbProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * When the "Create Database" button is press. It starts the database
+     * creation process, disables the "Create Database" and "Back" button, and
+     * sets the progress bar text.
+     *
+     * @param evt  the action event
+     */
+    private void crDbButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_crDbButtonActionPerformed
+    }//GEN-LAST:event_crDbButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton crDbButton;
+    private javax.swing.JLabel crDbLabel;
+    private javax.swing.JProgressBar crDbProgressBar;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel5;
+    private javax.swing.JCheckBox lookupFilesCheckBox;
+    private javax.swing.JLabel progressLabel;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.form b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.form
new file mode 100644
index 0000000000000000000000000000000000000000..0cb69a29ae3b8fe96e922a24faeaffdc1fca2503
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.form
@@ -0,0 +1,73 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="addImgButton" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Component id="crDbLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Component id="jLabel1" alignment="0" min="-2" pref="549" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="crDbLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
+              <Component id="addImgButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="54" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JButton" name="addImgButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel3.addImgButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addImgButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="crDbLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel3.crDbLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageVisualPanel3.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.java
new file mode 100644
index 0000000000000000000000000000000000000000..53575433536766471e7ea52034bc16e544d42ff0
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageVisualPanel3.java
@@ -0,0 +1,114 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import javax.swing.JPanel;
+import org.openide.util.Lookup;
+
+/**
+ * The "Add Image" wizard panel 3. This class is used to design the "form" of
+ * the panel 3 for "Add Image" wizard panel.
+ *
+ * @author jantonius
+ */
+final class AddImageVisualPanel3 extends JPanel {
+
+    /** Creates new form AddImageVisualPanel3 */
+    AddImageVisualPanel3() {
+        initComponents();
+    }
+
+    /**
+     * Returns the name of the this panel. This name will be shown on the left
+     * panel of the "Add Image" wizard panel.
+     *
+     * @return name  the name of this panel
+     */
+    @Override
+    public String getName() {
+        return "Done";
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        addImgButton = new javax.swing.JButton();
+        crDbLabel = new javax.swing.JLabel();
+        jLabel1 = new javax.swing.JLabel();
+
+        org.openide.awt.Mnemonics.setLocalizedText(addImgButton, org.openide.util.NbBundle.getMessage(AddImageVisualPanel3.class, "AddImageVisualPanel3.addImgButton.text")); // NOI18N
+        addImgButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                addImgButtonActionPerformed(evt);
+            }
+        });
+
+        crDbLabel.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(crDbLabel, org.openide.util.NbBundle.getMessage(AddImageVisualPanel3.class, "AddImageVisualPanel3.crDbLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddImageVisualPanel3.class, "AddImageVisualPanel3.jLabel1.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(addImgButton)
+                    .addComponent(crDbLabel)
+                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 549, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(crDbLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(jLabel1)
+                .addGap(18, 18, 18)
+                .addComponent(addImgButton)
+                .addContainerGap(54, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * 
+     *
+     * @param evt  the action event
+     */
+    private void addImgButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addImgButtonActionPerformed
+        // restart the wizard
+        AddImageAction act = Lookup.getDefault().lookup(AddImageAction.class);
+        act.restart();
+    }//GEN-LAST:event_addImgButtonActionPerformed
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton addImgButton;
+    private javax.swing.JLabel crDbLabel;
+    private javax.swing.JLabel jLabel1;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c571a43787ac9bc0b5f0d663a84fb7efd1e9fa63
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java
@@ -0,0 +1,166 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+
+/**
+ * The iterator class for the "Add Image" wizard panel. This class is used to
+ * iterate on the sequence of panels of the "Add Image" wizard panel.
+ */
+class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescriptor> {
+
+    private int index = 0;
+    private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
+    private AddImageAction action;
+
+    AddImageWizardIterator(AddImageAction action) {
+        this.action = action;
+    }
+
+    /**
+     * Initialize panels representing individual wizard's steps and sets
+     * various properties for them influencing wizard appearance.
+     */
+    private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
+        if (panels == null) {
+            panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
+            panels.add(new AddImageWizardPanel1());
+            panels.add(new AddImageWizardPanel2(action));
+            panels.add(new AddImageWizardPanel3());
+
+            String[] steps = new String[panels.size()];
+            for (int i = 0; i < panels.size(); i++) {
+                Component c = panels.get(i).getComponent();
+                // Default step name to component name of panel.
+                steps[i] = c.getName();
+                if (c instanceof JComponent) { // assume Swing components
+                    JComponent jc = (JComponent) c;
+                    // Sets step number of a component
+                    // TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
+                    jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
+                    // Sets steps names for a panel
+                    jc.putClientProperty("WizardPanel_contentData", steps);
+                    // Turn on subtitle creation on each step
+                    jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
+                    // Show steps on the left side with the image on the background
+                    jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
+                    // Turn on numbering of all steps
+                    jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
+                }
+            }
+        }
+        return panels;
+    }
+
+    /**
+     * Returns the index of the current panel.
+     * Note: 0 = panel 1, 1 = panel 2, etc
+     *
+     * @return index  the current panel index
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Gets the current panel.
+     *
+     * @return panel  the current panel
+     */
+    @Override
+    public WizardDescriptor.Panel<WizardDescriptor> current() {
+        if (panels != null) {
+            return panels.get(index);
+        } else {
+            return getPanels().get(index);
+        }
+    }
+
+    /**
+     * Gets the name of the current panel.
+     *
+     * @return name  the name of the current panel
+     */
+    @Override
+    public String name() {
+        return "Step " + Integer.toString(index + 1) + " of " + getPanels().size();
+    }
+
+    /**
+     * Tests whether there is a next panel.
+     * 
+     * @return boolean  true if it has next panel, false if not
+     */
+    @Override
+    public boolean hasNext() {
+        return index < getPanels().size() - 1;
+    }
+
+    /**
+     * Tests whether there is a previous panel.
+     *
+     * @return boolean  true if it has previous panel, false if not
+     */
+    @Override
+    // disable the previous button on all panels
+    public boolean hasPrevious() {
+        return index > 0;
+    }
+
+    /**
+     * Moves to the next panel. I.e. increment its index, need not actually
+     * change any GUI itself.
+     */
+    @Override
+    public void nextPanel() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+        index++;
+    }
+
+    /**
+     * Moves to the previous panel. I.e. decrement its index, need not actually
+     * change any GUI itself.
+     */
+    @Override
+    public void previousPanel() {
+        if (!hasPrevious()) {
+            throw new NoSuchElementException();
+        }
+        index--;
+    }
+
+    // If nothing unusual changes in the middle of the wizard, simply:
+    @Override
+    public void addChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void removeChangeListener(ChangeListener l) {
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java
new file mode 100644
index 0000000000000000000000000000000000000000..71b2d619ac67683ea24970c74691bc6f9b74ab9d
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel1.java
@@ -0,0 +1,189 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
+/**
+ * The "Add Image" wizard panel1 handling the logic of selecting image file(s)
+ * to add to Case, and pick the time zone.
+ */
+class AddImageWizardPanel1 implements WizardDescriptor.Panel<WizardDescriptor>, PropertyChangeListener {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private AddImageVisualPanel1 component;
+    private boolean isNextEnable = false;
+
+    /**
+     * Get the visual component for the panel. In this template, the component
+     * is kept separate. This can be more efficient: if the wizard is created
+     * but never displayed, or not all panels are displayed, it is better to
+     * create only those which really need to be visible.
+     *
+     * @return component  the UI component of this wizard panel
+     */
+    @Override
+    public AddImageVisualPanel1 getComponent() {
+        if (component == null) {
+            component = new AddImageVisualPanel1(this);
+        }
+        component.addPropertyChangeListener(this);
+        return component;
+    }
+
+    /**
+     * Help for this panel. When the panel is active, this is used as the help
+     * for the wizard dialog.
+     *
+     * @return HelpCtx.DEFAULT_HELP  the help for this panel
+     */
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx(SampleWizardPanel1.class);
+    }
+
+    /**
+     * Tests whether the panel is finished and it is safe to proceed to the next
+     * one. If the panel is valid, the "Next" button will be enabled.
+     *
+     * @return boolean  true if all the fields are correctly filled, false otherwise
+     */
+    @Override
+    public boolean isValid() {
+
+        // set the focus to the next button of the wizard dialog if it's enabled
+        if(isNextEnable){
+            Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton("Next >");
+        }
+
+        return isNextEnable;
+    }
+
+    /**
+     * Enable the "Next" button and fireChangeEvent to update the GUI
+     *
+     * @param isEnabled  true if next button can be enabled, false otherwise
+     */
+    public void enableNextButton(boolean isEnabled){
+        isNextEnable = isEnabled;
+        fireChangeEvent();
+    }
+
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+
+    /**
+     * Adds a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to add
+     */
+    @Override
+    public final void addChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.add(l);
+        }
+    }
+
+    /**
+     * Removes a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to move
+     */
+    @Override
+    public final void removeChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.remove(l);
+        }
+    }
+
+    /**
+     * This method is auto-generated. It seems that this method is used to listen
+     * to any change in this wizard panel.
+     */
+    protected final void fireChangeEvent() {
+        Iterator<ChangeListener> it;
+        synchronized (listeners) {
+            it = new HashSet<ChangeListener>(listeners).iterator();
+        }
+        ChangeEvent ev = new ChangeEvent(this);
+        while (it.hasNext()) {
+            it.next().stateChanged(ev);
+        }
+    }
+     
+
+    // You can use a settings object to keep track of state. Normally the
+    // settings object will be the WizardDescriptor, so you can use
+    // WizardDescriptor.getProperty & putProperty to store information entered
+    // by the user.
+
+    /**
+     * Provides the wizard panel with the current data--either the default data
+     * or already-modified settings, if the user used the previous and/or next
+     * buttons. This method can be called multiple times on one instance of
+     * WizardDescriptor.Panel.
+     *s
+     * @param settings  the setting to be read from
+     */
+    @Override
+    public void readSettings(WizardDescriptor settings) {
+    }
+
+    /**
+     * Provides the wizard panel with the opportunity to update the settings
+     * with its current customized state. Rather than updating its settings
+     * with every change in the GUI, it should collect them, and then only save
+     * them when requested to by this method. This method can be called multiple
+     * times on one instance of WizardDescriptor.Panel.
+     *
+     * @param settings  the setting to be stored to
+     */
+    @Override
+    public void storeSettings(WizardDescriptor settings) {
+        settings.putProperty(AddImageAction.IMGPATHS_PROP, getComponent().getImagePaths());
+        settings.putProperty(AddImageAction.TIMEZONE_PROP, getComponent().getSelectedTimezone()); // store the timezone
+    }
+
+
+    /**
+     * The "listener" for any property change in this panel. Any property changes
+     * will invoke the "fireChangeEvent()" method.
+     *
+     * @param evt  the property change event
+     */
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        fireChangeEvent();
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java
new file mode 100644
index 0000000000000000000000000000000000000000..478d5edaeea0928df3516653f35873cb57e2726d
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel2.java
@@ -0,0 +1,379 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JCheckBox;
+import javax.swing.JProgressBar;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+import org.sleuthkit.autopsy.hashdatabase.HashDbSettings;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.SleuthkitCase;
+import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * The "Add Image" wizard panel2. Handles processing the image in a worker
+ * thread, and any errors that may occur during the add process.
+ */
+class AddImageWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
+
+    // the paths of the image files to be added
+    private String[] imgPaths;
+    // the time zone where the image is added
+    private String timeZone;
+    
+    // paths to any set hash lookup databases (can be null)
+    private String NSRLPath, knownBadPath;
+
+    // task that will clean up the created database file if the wizard is cancelled before it finishes
+    private AddImageAction.CleanupTask cleanupImage; // initialized to null in readSettings()
+
+    // flag to control the availiablity of next action
+    private boolean imgAdded; // initalized to false in readSettings()
+
+    private AddImageProcess process;
+    private AddImgTask addImageTask; 
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private AddImageVisualPanel2 component;
+    private AddImageAction action;
+
+    AddImageWizardPanel2(AddImageAction action) {
+        this.action = action;
+    }
+
+    /**
+     * Get the visual component for the panel. In this template, the component
+     * is kept separate. This can be more efficient: if the wizard is created
+     * but never displayed, or not all panels are displayed, it is better to
+     * create only those which really need to be visible.
+     *
+     * @return component  the UI component of this wizard panel
+     */
+    @Override
+    public AddImageVisualPanel2 getComponent() {
+        if (component == null) {
+            component = new AddImageVisualPanel2();
+            component.getCrDbButton().addActionListener(new CrDbButtonListener());
+        }
+        return component;
+    }
+
+    /**
+     * Help for this panel. When the panel is active, this is used as the help
+     * for the wizard dialog.
+     *
+     * @return HelpCtx.DEFAULT_HELP  the help for this panel
+     */
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    /**
+     * Tests whether the panel is finished and it is safe to proceed to the next
+     * one. If the panel is valid, the "Next" button will be enabled.
+     *
+     * @return boolean  true if can proceed to the next one, false otherwise
+     */
+    @Override
+    public boolean isValid() {
+        // set the focus to the next button of the wizard dialog if it's enabled
+        if (imgAdded) {
+            Lookup.getDefault().lookup(AddImageAction.class).requestFocusButton("Next >");
+        }
+
+        return imgAdded;
+    }
+
+    class CrDbButtonListener implements ActionListener {
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            startAddImage();
+        }
+    }
+
+    /**
+     * Creates the database and adds the image to the XML configuration file.
+     *
+     */
+    private void startAddImage() {
+        component.getCrDbButton().setEnabled(false);
+        component.getCrDbProgressBar().setIndeterminate(true);
+        component.changeProgressBarTextAndColor("*Adding the image may take some time for large images.", 0, Color.black);
+
+        addImageTask = new AddImgTask();
+        addImageTask.execute();
+    }
+
+    /**
+     * Sets the isDbCreated variable in this class and also invoke 
+     * fireChangeEvent() method.
+     *
+     * @param created  whether the database already created or not
+     */
+    private void setDbCreated(Boolean created) {
+        imgAdded = created;
+        fireChangeEvent();
+    }
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+
+    /**
+     * Adds a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to add
+     */
+    @Override
+    public final void addChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.add(l);
+        }
+    }
+
+    /**
+     * Removes a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to move
+     */
+    @Override
+    public final void removeChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.remove(l);
+        }
+    }
+
+    /**
+     * This method is auto-generated. It seems that this method is used to listen
+     * to any change in this wizard panel.
+     */
+    protected final void fireChangeEvent() {
+        Iterator<ChangeListener> it;
+        synchronized (listeners) {
+            it = new HashSet<ChangeListener>(listeners).iterator();
+        }
+        ChangeEvent ev = new ChangeEvent(this);
+        while (it.hasNext()) {
+            it.next().stateChanged(ev);
+        }
+    }
+
+
+    /**
+     * Load the image locations from the WizardDescriptor settings object, and
+     * the
+     *
+     * @param settings  the setting to be read from
+     */
+    @Override
+    public void readSettings(WizardDescriptor settings) {
+        cleanupImage = null;
+        imgAdded = false;
+        imgPaths = (String[]) settings.getProperty(AddImageAction.IMGPATHS_PROP);
+        timeZone = settings.getProperty(AddImageAction.TIMEZONE_PROP).toString();
+
+        // If the user went back after the image was processed, it will be replaced so its cleanup task should be executed & removed
+        AddImageAction.CleanupTask oldImageCleanup = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP);
+        if (oldImageCleanup != null) {
+            try {
+                oldImageCleanup.cleanup();
+            } catch (Exception ex) {
+                Logger logger = Logger.getLogger(AddImageWizardPanel2.class.getName());
+                logger.log(Level.WARNING, "Error removing previously added image", ex);
+            } finally {
+                oldImageCleanup.disable();
+            }
+        }
+
+        component.changeProgressBarTextAndColor("", 0, Color.black);
+        component.getCrDbButton().setEnabled(true);
+        
+        
+        // Load hash database settings
+        this.NSRLPath = null;
+        this.knownBadPath = null;
+        
+        try {
+            HashDbSettings hashDbs = Autopsy.getHashDbSettings();
+            this.NSRLPath = hashDbs.getNSRLDatabasePath();
+            this.knownBadPath = hashDbs.getKnownBadDatabasePath();
+        } catch (IOException ex) {
+            Log.get(AddImageWizardPanel2.class).log(Level.WARNING, "Couldn't get hash database settings.", ex);
+        }
+        JCheckBox lookupFilesCheckbox = component.getLookupFilesCheckbox();
+        lookupFilesCheckbox.setSelected(false);
+        lookupFilesCheckbox.setEnabled(this.NSRLPath != null || this.knownBadPath != null);
+    }
+
+    /**
+     *
+     * @param settings  the setting to be stored to
+     */
+    @Override
+    public void storeSettings(WizardDescriptor settings) {
+        
+        // Store process so it can be committed if wizard finishes
+        settings.putProperty(AddImageAction.PROCESS_PROP, process);
+        
+        // Need to make the cleanup accessible to the finished wizard so it can
+        // be cancelled if all goes well, and availble if we return to this
+        // panel so the the previously added image can be reverted
+        settings.putProperty(AddImageAction.IMAGECLEANUPTASK_PROP, cleanupImage);
+    }
+
+    /**
+     * Thread that will make the JNI call to ingest the image. 
+     */
+    private class AddImgTask extends SwingWorker<Integer, Integer> {
+        private JProgressBar progressBar;
+        private JCheckBox lookupFilesCheckbox;
+        private Case currentCase;
+
+        // true if the process was requested to stop
+        private boolean interrupted = false;
+
+        protected AddImgTask() {
+            this.progressBar = getComponent().getCrDbProgressBar();
+            this.lookupFilesCheckbox = getComponent().getLookupFilesCheckbox();
+            currentCase = Case.getCurrentCase();
+        }
+
+        /**
+         * Starts the addImage process, but does not commit the results. 
+         * 
+         * @return
+         * @throws Exception 
+         */
+        @Override
+        protected Integer doInBackground() throws Exception {
+            this.setProgress(0);
+            
+            // Add a cleanup task to interupt the backgroud process if the
+            // wizard exits while the background process is running.
+            AddImageAction.CleanupTask cancelledWhileRunning = action.new CleanupTask() {
+                @Override
+                void cleanup() throws Exception {
+                    addImageTask.interrupt();
+                }
+            };
+            
+            SleuthkitCase skCase = currentCase.getSleuthkitCase();
+            skCase.clearLookupDatabases();
+            
+            if (lookupFilesCheckbox.isSelected()) {
+                if (NSRLPath != null) {
+                    skCase.setNSRLDatabase(NSRLPath);
+                }
+                
+                if (knownBadPath != null) {
+                    skCase.setKnownBadDatabase(knownBadPath);
+                }
+            }
+
+            try {
+                process = currentCase.makeAddImageProcess(Case.convertTimeZone(timeZone));
+                cancelledWhileRunning.enable();
+                process.run(imgPaths);
+            } catch (TskException ex) {
+                throw ex;
+            } finally {
+                // process is over, doesn't need to be dealt with if cancel happens
+                cancelledWhileRunning.disable();
+            }
+            this.setProgress(100);
+            return 0;
+        }
+
+
+
+        /**
+         * 
+         * (called by EventDispatch Thread after doInBackground finishes)
+         */
+        @Override
+        protected void done() {
+            progressBar.setIndeterminate(false);
+
+            // attempt actions that might fail and force the process to stop
+            try {
+                // get() will throw any expetions that were thrown in the background task
+                get();
+                if (interrupted) {
+                    process.revert();
+                    return;
+                }
+                
+                // When everything happens without an error:
+                
+                // the add-image process needs to be reverted if the wizard doesn't finish
+                cleanupImage = action.new CleanupTask() {
+                    @Override
+                    void cleanup() throws Exception {
+                        process.revert();
+                    }
+                };
+                cleanupImage.enable();
+
+                getComponent().changeProgressBarTextAndColor("*Image added.", 100, Color.black); // complete progress bar
+                
+                // Get attention for the process finish
+                java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
+                SwingUtilities.getWindowAncestor(getComponent()).toFront();
+                
+                setDbCreated(true);
+
+            } catch (Exception ex) {
+                getComponent().changeProgressBarTextAndColor("*Failed to add image.", 0, Color.black); // set error message
+
+                // Log error/display warning
+                Logger logger = Logger.getLogger(AddImgTask.class.getName());
+                logger.log(Level.SEVERE, "Error adding image to case", ex);
+            }
+        }
+
+        void interrupt() throws Exception {
+            interrupted = true;
+            try {
+                process.stop();
+            } catch (TskException ex) {
+                throw new Exception("Error stopping add-image process.", ex);
+            }
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel3.java b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel3.java
new file mode 100644
index 0000000000000000000000000000000000000000..f999115e44d76c5f57397af22d39bd44599c94e7
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/AddImageWizardPanel3.java
@@ -0,0 +1,157 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+/**
+ * The "Add Image" wizard panel3. No major functionality, just presents the
+ * options to finish/cancel image-add or to add another image.
+ */
+class AddImageWizardPanel3 implements WizardDescriptor.Panel<WizardDescriptor> {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private Component component;
+
+    /**
+     * Get the visual component for the panel. In this template, the component
+     * is kept separate. This can be more efficient: if the wizard is created
+     * but never displayed, or not all panels are displayed, it is better to
+     * create only those which really need to be visible.
+     *
+     * @return component  the UI component of this wizard panel
+     */
+    @Override
+    public Component getComponent() {
+        if (component == null) {
+            component = new AddImageVisualPanel3();
+        }
+        return component;
+    }
+
+    /**
+     * Help for this panel. When the panel is active, this is used as the help
+     * for the wizard dialog.
+     *
+     * @return HelpCtx.DEFAULT_HELP  the help for this panel
+     */
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx(SampleWizardPanel1.class);
+    }
+
+    /**
+     * Tests whether the panel is finished. If the panel is valid, the "Finish"
+     * button will be enabled.
+     *
+     * @return true  the finish button should be always enabled at this point
+     */
+    @Override
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return true;
+        // If it depends on some condition (form filled out...), then:
+        // return someCondition();
+        // and when this condition changes (last form field filled in...) then:
+        // fireChangeEvent();
+        // and uncomment the complicated stuff below.
+    }
+
+    /**
+     * Adds a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to add
+     */
+    @Override
+    public final void addChangeListener(ChangeListener l) {
+    }
+
+    /**
+     * Removes a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to move
+     */
+    @Override
+    public final void removeChangeListener(ChangeListener l) {
+    }
+    
+    /*
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+    public final void addChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.add(l);
+    }
+    }
+    public final void removeChangeListener(ChangeListener l) {
+    synchronized (listeners) {
+    listeners.remove(l);
+    }
+    }
+    protected final void fireChangeEvent() {
+    Iterator<ChangeListener> it;
+    synchronized (listeners) {
+    it = new HashSet<ChangeListener>(listeners).iterator();
+    }
+    ChangeEvent ev = new ChangeEvent(this);
+    while (it.hasNext()) {
+    it.next().stateChanged(ev);
+    }
+    }
+     */
+
+    // You can use a settings object to keep track of state. Normally the
+    // settings object will be the WizardDescriptor, so you can use
+    // WizardDescriptor.getProperty & putProperty to store information entered
+    // by the user.
+
+    /**
+     * Provides the wizard panel with the current data--either the default data
+     * or already-modified settings, if the user used the previous and/or next
+     * buttons. This method can be called multiple times on one instance of
+     * WizardDescriptor.Panel.
+     *
+     * @param settings  the setting to be read from
+     */
+    @Override
+    public void readSettings(WizardDescriptor settings) {
+    }
+
+    /**
+     * Provides the wizard panel with the opportunity to update the settings
+     * with its current customized state. Rather than updating its settings
+     * with every change in the GUI, it should collect them, and then only save
+     * them when requested to by this method. This method can be called multiple
+     * times on one instance of WizardDescriptor.Panel.
+     *
+     * @param settings  the setting to be stored to
+     */
+    @Override
+    public void storeSettings(WizardDescriptor settings) {
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy.java b/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy.java
new file mode 100644
index 0000000000000000000000000000000000000000..95bc01e3e47c30d1e9e9ffe074cb68b32c41ae35
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy.java
@@ -0,0 +1,70 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.File;
+import java.io.IOException;
+import org.sleuthkit.autopsy.hashdatabase.HashDbSettings;
+import org.sleuthkit.datamodel.SleuthkitJNI;
+
+/**
+ * Class to consolidate application-wide settings.
+ */
+public class Autopsy {
+    private final static String propFilePath = System.getProperty("netbeans.user") + File.separator + "autopsy.properties";
+    private static boolean verboseLogging = false;
+    
+    /**
+     * Gets the property file where the user properties such as Recent Cases
+     * and selected Hash Databases are stored.
+     * @return A new file handle
+     */
+    public static File getPropertyFile() {
+        return new File(propFilePath);
+    }
+    
+    /**
+     * Get the hash database settings as read from the property file.
+     * @return A new hash database settings object.
+     * @throws IOException if the property file can't be found
+     */
+    public static HashDbSettings getHashDbSettings() throws IOException {
+        return new HashDbSettings(getPropertyFile());
+    }
+
+    /**
+     * Activate verbose logging for Sleuth Kit
+     */
+    public static void startVerboseLogging() {
+        verboseLogging = true;
+        String logPath = System.getProperty("netbeans.user") + File.separator + "sleuthkit.txt";
+        
+        SleuthkitJNI.startVerboseLogging(logPath);
+    }
+    
+    /**
+     * Checks if verbose logging has been enabled.
+     * @return true if verbose logging has been enabled.
+     */
+    public static boolean verboseLoggingIsSet() {
+        return verboseLogging;
+    }
+    
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy_logo.gif b/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy_logo.gif
new file mode 100644
index 0000000000000000000000000000000000000000..42cc5033142f00d0f3f5af368ed447588e95c491
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/Autopsy_logo.gif differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d7d06b1e085105b96f7bce71ba356abb23257470
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/Bundle.properties
@@ -0,0 +1,115 @@
+CTL_AddImage=Add Image...
+CTL_CaseAction=Case
+CTL_CaseCloseAct=Close Case
+CTL_CaseNewAction=New Case...
+CTL_CaseOpenActionOld=Open Case(old)...
+CTL_CasePropertiesAction=Case Properties...
+CTL_CaseTopComponent=Case Window
+CTL_NewCaseAct=New Case(Old)...
+CTL_OpenAction=Open Case...
+CTL_RecentCases=Recent Cases
+CTL_CaseDeleteAction=Delete Case
+CTL_SaveCaseAction=Save Case
+CTL_testAction=test
+CTL_testTopComponent=test Window
+HINT_CaseTopComponent=This is a Case window
+HINT_testTopComponent=This is a test window
+Menu/File/org-sleuthkit-autopsy-casemodule-CaseCloseAct.shadow=
+Menu/File/org-sleuthkit-autopsy-casemodule-OpenAction.shadow=Open Case
+OpenIDE-Module-Name=Case
+CaseVisualPanel1.jLabel1.text=Name
+CaseVisualPanel1.jLabel2.text=Image Path:
+CaseVisualPanel1.jLabel3.text=Database Path:
+CaseTopComponent.jLabel1.text=Name
+CaseVisualPanel1.NameField.text=
+CaseVisualPanel1.ImgPath.text=
+CaseVisualPanel1.DbPath.text=
+CaseTopComponent.jLabel2.text=Image Path
+CaseTopComponent.jLabel3.text=DB Path
+CaseVisualPanel1.ImgPathBrowserButton.text=Browse
+CaseVisualPanel1.DbPathBrowserButton.text=Browse
+NewCaseVisualPanel1.jLabel1.text=Name
+NewCaseVisualPanel1.jTextField1.text=
+NewCaseVisualPanel1.jLabel2.text=Image Type:
+NewCaseVisualPanel1.jRadioButton1.text=Raw Single .img .dd
+NewCaseVisualPanel1.jRadioButton2.text=Raw Split .001 .002 etc
+NewCaseVisualPanel1.jRadioButton3.text=Encase .e01
+NewCaseVisualPanel1.nameLabel.text_1=Name
+NewCaseVisualPanel1.NameField.text_1=
+NewCaseVisualPanel1.TypeLabel.text_1=Image Type:
+NewCaseVisualPanel1.rawSingleRadio.text_1=Raw Single .img .dd
+NewCaseVisualPanel1.rawSplitRadio.text_1=Raw Split .001 .002 etc
+NewCaseVisualPanel1.encaseRadio.text_1=EnCase .e01
+NewCaseVisualPanel2.jLabel1.text=Image Path:
+NewCaseVisualPanel2.jLabel2.text=DataBase Path:
+NewCaseVisualPanel2.descriptionText.text=variable text
+NewCaseVisualPanel2.ImgBrowserButton.text=Browse
+NewCaseVisualPanel2.DcBrowserButton.text=Browse
+NewCaseVisualPanel2.ImagePathField.text=
+NewCaseVisualPanel2.DbPathField.text=
+CaseVisualPanel1.jLabel4.text=Image Type:
+CaseVisualPanel1.rawSingle.text=Raw Single .img .dd
+CaseVisualPanel1.rawSplit.text=Raw Split .001 .002 etc
+CaseVisualPanel1.encase.text=EnCase .e01 .e02 etc
+CaseVisualPanel1.multipleSelectLabel.text=Single Image: Multiple Select Disabled
+CaseVisualPanel1.jLabel5.text=If a database has not already been loaded / created for the chosen image use this button: (could take a few minutes)
+CaseVisualPanel1.ProgressLabel.text=
+CaseVisualPanel1.createDbButton.text=Create Database
+NewCaseVisualPanel1.jLabel1.text_1=Enter New Case Information:
+NewCaseVisualPanel1.caseNameLabel.text_1=Case Name:
+NewCaseVisualPanel1.caseDirLabel.text=Base Directory:
+NewCaseVisualPanel1.caseDirBrowseButton.text=Browse
+NewCaseVisualPanel1.caseNameTextField.text_1=
+NewCaseVisualPanel1.jLabel2.text_1=Case data will be stored in the following directory:
+NewCaseVisualPanel1.caseParentDirTextField.text=
+NewCaseVisualPanel1.caseDirTextField.text_1=
+CasePropertiesForm.caseDirLabel.text=Case Directory:
+CasePropertiesForm.crDateLabel.text=Created Date:
+CasePropertiesForm.caseNameLabel.text=Case Name:
+CasePropertiesForm.crDateTextField.text=
+CasePropertiesForm.caseNameTextField.text=
+CasePropertiesForm.updateCaseNameButton.text=Update
+CasePropertiesForm.casePropLabel.text=Case Information
+CasePropertiesForm.genInfoLabel.text=General Information
+CasePropertiesForm.imgInfoLabel.text=Images Information
+CasePropertiesForm.OKButton.text=OK
+CasePropertiesForm.deleteCaseButton.text=Delete Case
+CueBannerPanel.autopsyLogo.text=
+CueBannerPanel.createNewLabel.text=Create New Case
+CueBannerPanel.autopsyLabel.text=Autopsy
+CueBannerPanel.welcomeLabel.text=Welcome to
+CueBannerPanel.openLabel.text=Open Existing Case
+CueBannerPanel.startupCheckBox.text=Don't show on startup again
+CueBannerPanel.closeButton.text=Close
+CueBannerPanel.openRecentLabel.text=Open Recent Case
+CueBannerPanel.newCaseButton.text=
+CueBannerPanel.openCaseButton.text=
+CueBannerPanel.openRecentButton.text=
+OpenRecentCasePanel.cancelButton.text=Cancel
+OpenRecentCasePanel.jLabel1.text=Recent Cases
+AddImageVisualPanel1.imgInfoLabel.text=Enter Disk Image Information:
+AddImageVisualPanel2.crDbLabel.text=Adding Image
+AddImageVisualPanel2.jLabel5.text=Processing Image and Adding to Database :
+AddImageVisualPanel2.crDbButton.text=Process Image
+AddImageVisualPanel2.progressLabel.text=
+AddImageVisualPanel2.jLabel1.text=<html> We will now analyze the disk image to extract volume and file system data and populate a local database. This may <br>take a while on large images. </html>
+AddImageVisualPanel3.addImgButton.text=Add Another Image
+AddImageVisualPanel3.crDbLabel.text=Finish or Add More Images
+AddImageVisualPanel3.jLabel1.text=Image successfully processed and added to the case. You can add another image or return to the case.
+AddImageVisualPanel1.jLabel1.text=
+AddImageVisualPanel1.timeZoneLabel.text=Please select your timezone:
+AddImageVisualPanel1.rawSingle.text=Raw Single (*.img, *.dd, etc)
+AddImageVisualPanel1.rawSplit.text=Raw Split (*.001, *.002, *.aa, *.ab, etc)
+AddImageVisualPanel1.imgTypeLabel.text=Image Type:
+AddImageVisualPanel1.multipleSelectLabel.text=Single Image: Multiple Select Disabled
+AddImageVisualPanel1.imgPathTextField.text=
+AddImageVisualPanel1.encase.text=EnCase (*.e01, *.e02, etc)
+AddImageVisualPanel1.imgPathLabel.text=Image Path:
+AddImageVisualPanel1.imgPathBrowserButton.text=Browse
+NewJPanel.jLabel1.text=
+NewJPanel.jLabel2.text=NSRL Index
+NewJPanel.jLabel5.text=The NSRL index is used to idenify "known" files.
+NewJPanel.jFormattedTextField1.text=jFormattedTextField1
+NewJPanel.jButton1.text=Rename
+NewJPanel.jLabel4.text=Database:
+AddImageVisualPanel2.lookupFilesCheckBox.text=Lookup files in hash databases
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/ButtonColumn.java b/Case/src/org/sleuthkit/autopsy/casemodule/ButtonColumn.java
new file mode 100644
index 0000000000000000000000000000000000000000..24f67b48f4720047244e3204f30874b3e764151e
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/ButtonColumn.java
@@ -0,0 +1,232 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+/**
+ * @author jantonius
+ *
+ * Taken from: http://tips4java.wordpress.com/2009/07/12/table-button-column/
+ * Note: everything is the same, except I edited the buttonName
+ */
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.table.*;
+
+/**
+ *  The ButtonColumn class provides a renderer and an editor that looks like a
+ *  JButton. The renderer and editor will then be used for a specified column
+ *  in the table. The TableModel will contain the String to be displayed on
+ *  the button.
+ *
+ *  The button can be invoked by a mouse click or by pressing the space bar
+ *  when the cell has focus. Optionally a mnemonic can be set to invoke the
+ *  button. When the button is invoked the provided Action is invoked. The
+ *  source of the Action will be the table. The action command will contain
+ *  the model row number of the button that was clicked.
+ *
+ */
+class ButtonColumn extends AbstractCellEditor
+	implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
+{
+	private JTable table;
+	private Action action;
+	private int mnemonic;
+	private Border originalBorder;
+	private Border focusBorder;
+
+	private JButton renderButton;
+	private JButton editButton;
+	private String text;
+	private boolean isButtonColumnEditor;
+
+        String buttonName;
+        
+
+	/**
+	 *  Create the ButtonColumn to be used as a renderer and editor. The
+	 *  renderer and editor will automatically be installed on the TableColumn
+	 *  of the specified column.
+	 *
+	 *  @param table the table containing the button renderer/editor
+	 *  @param action the Action to be invoked when the button is invoked
+         *  @param column the column to which the button renderer/editor is added
+         *  @param buttonName  text displayed on the button
+	 */
+	ButtonColumn(JTable table, Action action, int column, String buttonName)
+	{
+		this.table = table;
+		this.action = action;
+                this.buttonName = buttonName;
+
+		renderButton = new JButton();
+		editButton = new JButton();
+		editButton.setFocusPainted( false );
+		editButton.addActionListener( this );
+		originalBorder = editButton.getBorder();
+		setFocusBorder( new LineBorder(Color.BLUE) );
+
+		TableColumnModel columnModel = table.getColumnModel();
+		columnModel.getColumn(column).setCellRenderer( this );
+		columnModel.getColumn(column).setCellEditor( this );
+		table.addMouseListener( this );
+	}
+
+
+	/**
+	 *  Get foreground color of the button when the cell has focus
+	 *
+	 *  @return the foreground color
+	 */
+	public Border getFocusBorder()
+	{
+		return focusBorder;
+	}
+
+	/**
+	 *  The foreground color of the button when the cell has focus
+	 *
+	 *  @param focusBorder the foreground color
+	 */
+	public void setFocusBorder(Border focusBorder)
+	{
+		this.focusBorder = focusBorder;
+		editButton.setBorder( focusBorder );
+	}
+
+	public int getMnemonic()
+	{
+		return mnemonic;
+	}
+
+	/**
+	 *  The mnemonic to activate the button when the cell has focus
+	 *
+	 *  @param mnemonic the mnemonic
+	 */
+	public void setMnemonic(int mnemonic)
+	{
+		this.mnemonic = mnemonic;
+		renderButton.setMnemonic(mnemonic);
+		editButton.setMnemonic(mnemonic);
+	}
+
+	@Override
+	public Component getTableCellEditorComponent(
+		JTable table, Object value, boolean isSelected, int row, int column)
+	{
+		text = (value == null) ? "" : value.toString();
+		editButton.setText( text );
+		return editButton;
+	}
+
+	@Override
+	public Object getCellEditorValue()
+	{
+		return text;
+	}
+
+//
+//  Implement TableCellRenderer interface
+//
+    @Override
+	public Component getTableCellRendererComponent(
+		JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
+	{
+		if (isSelected)
+		{
+			renderButton.setForeground(table.getSelectionForeground());
+	 		renderButton.setBackground(table.getSelectionBackground());
+		}
+		else
+		{
+			renderButton.setForeground(table.getForeground());
+			renderButton.setBackground(UIManager.getColor("Button.background"));
+		}
+
+		if (hasFocus)
+		{
+			renderButton.setBorder( focusBorder );
+		}
+		else
+		{
+			renderButton.setBorder( originalBorder );
+		}
+
+		//renderButton.setText( (value == null) ? "" : value.toString() );
+                renderButton.setText(buttonName);
+		return renderButton;
+	}
+
+//
+//  Implement ActionListener interface
+//
+    /*
+     *	The button has been pressed. Stop editing and invoke the custom Action
+     */
+    @Override
+	public void actionPerformed(ActionEvent e)
+	{
+		int row = table.convertRowIndexToModel( table.getEditingRow() );
+		fireEditingStopped();
+
+		//  Invoke the Action
+
+		ActionEvent event = new ActionEvent(
+			table,
+			ActionEvent.ACTION_PERFORMED,
+			"" + row);
+		action.actionPerformed(event);
+	}
+
+//
+//  Implement MouseListener interface
+//
+    /*
+     *  When the mouse is pressed the editor is invoked. If you then then drag
+     *  the mouse to another cell before releasing it, the editor is still
+     *  active. Make sure editing is stopped when the mouse is released.
+     */
+    @Override
+    public void mousePressed(MouseEvent e)
+    {
+    	if (table.isEditing()
+		&&  table.getCellEditor() == this)
+			isButtonColumnEditor = true;
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e)
+    {
+    	if (isButtonColumnEditor
+    	&&  table.isEditing())
+    		table.getCellEditor().stopCellEditing();
+
+		isButtonColumnEditor = false;
+    }
+
+    @Override
+    public void mouseClicked(MouseEvent e) {}
+    @Override
+    public void mouseEntered(MouseEvent e) {}
+    @Override
+    public void mouseExited(MouseEvent e) {}
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/Case.java b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ebf16e6e028f5825e2c3f9e917d638d6883bce2
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -0,0 +1,852 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Frame;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.Lookup;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.SystemAction;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.*;
+import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
+
+/**
+ * Class to store the case information
+ */
+public class Case {
+    // change the CTL_MainWindow_Title in Bundle.properties as well if you change this value
+    private static final String autopsyVer = "3.0.0b1"; // current version of autopsy. Changed it when the version is changed
+    private static final String appName = "Autopsy " + autopsyVer;
+
+    /**
+     * Property name that indicates the name of the current case has changed.
+     * Fired with the case is renamed, and when the current case is
+     * opened/closed/changed. The value is a String: the name of the case.
+     * The empty string ("") is used for no open case.
+     */
+    public static final String CASE_NAME = "caseName";
+    /**
+     * Property name that indicates a new image has been added to the current
+     * case. The new value is the newly-added instance of Image, and the old
+     * value is always null.
+     */
+    public static final String CASE_ADD_IMAGE = "addImages";
+    /**
+     * Property name that indicates an image has been removed from the current
+     * case. The "old value" is the (int) image ID of the image that was
+     * removed, the new value is the instance of the Image.
+     */
+    public static final String CASE_DEL_IMAGE = "removeImages";
+    /**
+     * Property name that indicates the currently open case has changed.
+     * The new value is the instance of the opened Case, or null if there is no
+     * open case.
+     * The old value is the instance of the closed Case, or null if there was no
+     * open case.
+     */
+    public static final String CASE_CURRENT_CASE = "currentCase";
+    /**
+     * Name for the property that determines whether to show the dialog at
+     * startup
+     */
+    static final String propStartup = "LBL_StartupDialog";
+    private static Properties properties = new Properties();
+
+    // pcs is initialized in CaseListener constructor
+    private static PropertyChangeSupport pcs;
+    private static PropertyChangeListener caseListener = new CaseListener();
+
+    
+    private String name;
+    private String configFilePath;
+    private XMLCaseManagement xmlcm;
+    private SleuthkitCase db;
+
+
+
+    // Track the current case (only set with changeCase() method)
+    private static Case currentCase = null;
+
+    /**
+     * Constructor for the Case class
+     */
+    private Case(String name, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db) {
+        this.name = name;
+        this.configFilePath = configFilePath;
+        this.xmlcm = xmlcm;
+        this.db = db;
+    }
+
+    /**
+     * Gets the currently opened case, if there is one.
+     *
+     * @return the current open case
+     * @throws IllegalStateException if there is no case open.
+     */
+    public static Case getCurrentCase() {
+        if (currentCase != null) {
+            return currentCase;
+        } else {
+            throw new IllegalStateException("Can't get the current case; there is no case open!");
+        }
+    }
+
+
+
+    /**
+     * Updates the current case to the given case and fires off
+     * the appropriate property-change
+     * @param newCase the new current case
+     */
+    private static void changeCase(Case newCase) {
+
+        Case oldCase = Case.currentCase;
+        Case.currentCase = null;
+
+        String oldCaseName = oldCase != null ? oldCase.name : "";
+        pcs.firePropertyChange(CASE_CURRENT_CASE, oldCase, null);
+        pcs.firePropertyChange(CASE_NAME, oldCaseName, "");
+
+        if (newCase != null) {
+            currentCase = newCase;
+
+            pcs.firePropertyChange(CASE_CURRENT_CASE, null, currentCase);
+            //TODO: This will fire off a bunch of stuff in CaseListener.propertyChange()
+            // that should probably be migrated into here
+            
+            pcs.firePropertyChange(CASE_NAME, "", currentCase.name);
+            RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
+        }
+    }
+
+    
+    
+    AddImageProcess makeAddImageProcess(String timezone) {
+        return this.db.makeAddImageProcess(timezone);
+    }
+    
+    /**
+     * Creates a new case (create the XML config file and the directory)
+     * 
+     * @param caseDir  the base directory where the configuration file is saved
+     * @param caseName  the name of case
+     */
+    static void create(String caseDir, String caseName) throws Exception {
+        Log.get(Case.class).log(Level.INFO, "Creating new case.\ncaseDir: {0}\ncaseName: {1}", new Object[] {caseDir, caseName});
+
+        String configFilePath = caseDir + File.separator + caseName + ".aut";
+        
+        XMLCaseManagement xmlcm = new XMLCaseManagement();
+        xmlcm.create(caseDir, caseName); // create a new XML config file
+        xmlcm.writeFile();
+        
+        String dbPath = caseDir + File.separator + "autopsy.db";
+        SleuthkitCase db = SleuthkitCase.newCase(dbPath);
+
+        Case newCase = new Case(caseName, configFilePath, xmlcm, db);
+        
+        changeCase(newCase);
+    }
+
+    /**
+     * Opens the existing case (open the XML config file)
+     *
+     * @param configFilePath  the path of the configuration file that's opened
+     * @throws Exception
+     */
+     static void open(String configFilePath) throws Exception {
+        Log.get(Case.class).log(Level.INFO, "Opening case.\nconfigFilePath: {0}", configFilePath);
+
+        try {
+            XMLCaseManagement xmlcm = new XMLCaseManagement();
+
+            xmlcm.open(configFilePath); // open and load the config file to the document handler in the XML class
+            xmlcm.writeFile(); // write any changes to the config file
+
+            String caseName =  xmlcm.getCaseName();
+            // if the caseName is "", case / config file can't be opened
+            if (caseName.equals("")) {
+                throw new Exception("Case name is blank.");
+            }
+            
+            String caseDir = xmlcm.getCaseDirectory();
+            String dbPath = caseDir + File.separator + "autopsy.db";
+            SleuthkitCase db = SleuthkitCase.openCase(dbPath);
+            
+            Case openedCase = new Case(caseName, configFilePath, xmlcm, db);
+            
+            changeCase(openedCase);
+
+        } catch (Exception ex) {
+            // close the previous case if there's any
+            CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class);
+            closeCase.actionPerformed(null);
+            throw ex;
+        }
+    }
+
+    /**
+     * Adds the image to the current case after it has been added to the DB
+     *
+     * @param imgPaths  the paths of the image that being added
+     * @param imgId  the ID of the image that being added
+     * @param timeZone  the timeZone of the image where it's added
+     */
+    void addImage(String[] imgPaths, long imgId, String timeZone) throws Exception {
+        Log.get(this.getClass()).log(Level.INFO, "Adding image to Case.  imgPaths: {0}  ID: {1} TimeZone: {2}", new Object[]{Arrays.toString(imgPaths), imgId, timeZone});
+
+        try {
+            xmlcm.addImage(imgPaths, imgId, timeZone); // add the image to the document handler in the XML class and to the config file
+            xmlcm.writeFile(); // write any changes to the config file
+            Image newImage = db.getImageById(imgId);
+            pcs.firePropertyChange(CASE_ADD_IMAGE, null, newImage); // the new value is the instance of the image
+        } catch (Exception ex) {
+            // throw an error here
+            throw ex;
+        }
+    }
+    
+    /**
+     * Get the underlying SleuthkitCase instance from the Sleuth Kit bindings
+     * library.
+     * @return
+     */
+    public SleuthkitCase getSleuthkitCase() {
+        return this.db;
+    }
+
+    /**
+     * Closes this case. This methods close the xml and clear all the fields.
+     */
+    void closeCase() throws Exception {
+        changeCase(null);
+
+        try {
+            this.xmlcm.close(); // close the xmlcm
+            this.db.close();
+        } catch (Exception e) {
+            throw new Exception("Error while trying to close the current case.", e);
+        }
+    }
+
+    /**
+     * Delete this case. This methods delete all folders and files of this case.
+     */
+    boolean deleteCase(File caseDir) {
+        Log.get(this.getClass()).log(Level.FINE, "Deleting case.\ncaseDir: {0}", caseDir);
+        
+        try {
+            
+            xmlcm.close(); // close the xmlcm
+            boolean result = deleteCaseDirectory(caseDir); // delete the directory
+            
+            RecentCases.getInstance().removeRecentCase(this.name, this.configFilePath); // remove it from the recent case
+            Case.changeCase(null);
+            return result;
+        } catch (Exception ex) {
+            // TODO: change to using exceptions instead of return value.
+            // throw an error here
+            Logger logger = Logger.getLogger(Case.class.getName());
+            logger.log(Level.SEVERE, "Error deleting the current case.", ex);
+            return false;
+        }
+    }
+
+    /**
+     * Updates the case name.
+     *
+     * @param oldCaseName  the old case name that wants to be updated
+     * @param oldPath  the old path that wants to be updated
+     * @param newCaseName  the new case name
+     * @param newPath  the new path
+     */
+    void updateCaseName(String oldCaseName, String oldPath, String newCaseName, String newPath) throws Exception {
+        try {
+            xmlcm.setCaseName(newCaseName); // set the case
+            name = newCaseName; // change the local value
+            RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case
+
+            pcs.firePropertyChange(CASE_NAME, oldCaseName, newCaseName);
+        } catch (Exception e) {
+            throw new Exception("Error while trying to update the case name.", e);
+        }
+    }
+
+// Not dealing with removing images for now.
+//    /**
+//     * Removes the image from this case
+//     *
+//     * @param givenID    the ID of the image to be removed
+//     * @param givenPath  the path of the image to be removed
+//     */
+//    void removeImage(int givenID, String givenPath) throws Exception {
+//        Log.get(this.getClass()).log(Level.FINE, "Removing image.\ngivenID: {0}\ngivenPath: {1}", new Object[] {givenID, givenPath});
+//        
+//        String[] tempPaths = xmlcm.getImageSet(givenID);
+//        String tempDb = xmlcm.getImageSetDbPath(givenID);
+//
+//        if (tempPaths[0].equals(givenPath)) {
+//            xmlcm.removeImageSet(givenID); // make the changes in the config file
+//            try {
+//                xmlcm.writeFile();
+//            } catch (Exception ex) {
+//                throw new Exception("Error while trying to remove the image from this case.", ex);
+//            }
+//
+//            Image img = imageIdToData.get(givenID).image; // save the image that we want to delete temporarily
+//
+//            imageIdToData.remove(givenID);
+//
+//            pcs.firePropertyChange(CASE_DEL_IMAGE, givenID, img); // the old value is the image ID that removed, the new value is the instance of the image
+//
+//            img.getSleuthkit().closeConnection(); // to make sure that we close the connection
+//
+//            // need to remove the database as well??
+//            File database = new File(tempDb);
+//            boolean test = database.delete(); // delete the database of the image that we remove
+//            if (!test) {
+//                database.deleteOnExit(); // delete on exit if the delete is not successful
+//            }
+//        } else {
+//            // throw an error here
+//            Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Couldn't remove image.", new Exception("Couldn't find the image in this case."));
+//        }
+//    }
+    
+
+    /**
+     * Checks whether there is a current case open.
+     *
+     * @return True if a case is open.
+     */
+    public static boolean existsCurrentCase() {
+        return currentCase != null;
+    }
+
+    /**
+     * Uses the given path to store it as the configuration file path
+     *
+     * @param givenPath  the given config file path
+     */
+    private void setConfigFilePath(String givenPath) {
+        configFilePath = givenPath;
+    }
+
+    /**
+     *  Get the config file path in the given path
+     *
+     * @return configFilePath  the path of the configuration file
+     */
+    String getConfigFilePath() {
+        return configFilePath;
+    }
+
+    /**
+     * Returns the current version of Autopsy
+     * @return autopsyVer
+     */
+    public static String getAutopsyVersion() {
+        return autopsyVer;
+    }
+
+    /**
+     * Gets the application name
+     * @return appName
+     */
+    public static String getAppName() {
+        return appName;
+    }
+
+    /**
+     * Gets the case name
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the case directory path
+     * @return caseDirectoryPath
+     */
+    public String getCaseDirectory() {
+        if (xmlcm == null) {
+            return "";
+        } else {
+            return xmlcm.getCaseDirectory();
+        }
+    }
+
+    /**
+     * Gets the full path to the temp directory of this case
+     * @return tempDirectoryPath
+     */
+    public String getTempDirectory() {
+        if (xmlcm == null) {
+            return "";
+        } else {
+            return xmlcm.getTempDir();
+        }
+    }
+
+    /**
+     * get the created date of this case
+     * @return case creation date
+     */
+    public String getCreatedDate() {
+        if (xmlcm == null) {
+            return "";
+        } else {
+            return xmlcm.getCreatedDate();
+        }
+    }
+
+
+    /**
+     * get the PropertyChangeSupport of this class
+     * @return PropertyChangeSupport
+     */
+    public static PropertyChangeSupport getPropertyChangeSupport() {
+        return pcs;
+    }
+    
+    
+    String[] getImagePaths(int imgID) {
+        return xmlcm.getImageSet(imgID);
+    }
+    
+    /**
+     * get all the image id in this case
+     * @return imageIDs
+     */
+    public int[] getImageIDs() {
+        if (xmlcm == null) {
+            return new int[0];
+        } else {
+            return xmlcm.getImageIDs();
+        }
+    }
+
+    /**
+     * Count the root objects.
+     * @return The number of total root objects in this case.
+     */
+    public int getRootObjectsCount() {
+        return getRootObjects().size();
+    }
+    
+    /**
+     * Get the data model Content objects in the root of this case's hierarchy.
+     * @return a list of the root objects
+     */
+    public List<Content> getRootObjects() {
+        try {
+            return db.getRootObjects();
+        } catch (TskException ex) {
+            throw new RuntimeException("Error getting root objects.", ex);
+        }
+    }
+
+    /**
+     * Gets the time zone(s) of the image(s) in this case. 
+     *
+     * @return time zones  the set of time zones
+     */
+    public Set<TimeZone> getTimeZone() {
+        if (xmlcm == null) {
+            return new HashSet<TimeZone>();
+        } else {
+            return xmlcm.getTimeZone();
+        }
+    }
+
+    public static synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+        pcs.addPropertyChangeListener(listener);
+    }
+
+    public static synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+        pcs.removePropertyChangeListener(listener);
+    }
+
+    /**
+     * convert the image Path to array string
+     * @param imgPath   the image path
+     * @return imgPath  the converted image path
+     */
+    public static String[] convertImgPath(String imgPath) {
+        String[] result;
+        String unsplitPaths = imgPath;
+        int count = 0;
+
+        for (int i = 0; i < unsplitPaths.length(); i++) {
+            if (unsplitPaths.charAt(i) == '\"') {
+                count++;
+            }
+        }
+
+        if (count != 0) {
+            result = new String[count / 2];
+            int start = 0;
+            int current = 0;
+            for (int i = 0; i < count / 2; i++) {
+                while (unsplitPaths.charAt(current) != '\"') {
+                    current++;
+                }
+                start = current;
+                current++;
+                while (unsplitPaths.charAt(current) != '\"') {
+                    current++;
+                }
+                result[i] = unsplitPaths.substring(start + 1, current);
+                current++;
+            }
+        } else {
+            result = new String[1];
+            result[0] = unsplitPaths;
+        }
+
+        return result;
+    }
+
+    /**
+     * Check if all the images from the given image path exist.
+     * @param imgPaths  the image paths
+     * @return isExist  whether the multiple paths exist
+     */
+    public static boolean checkMultiplePathExist(String[] imgPaths) {
+        boolean result = false;
+        int totalLength = imgPaths.length;
+        if (totalLength > 0) {
+            result = true;
+            for (int i = 0; i < totalLength; i++) {
+                if (new File(imgPaths[i]).exists()) {
+                    result = result && true;
+                } else {
+                    result = result && false;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Convert the Java timezone ID to the "formatted" string that can be
+     * accepted by the C/C++ code.
+     * Example: "America/New_York" converted to "EST5EDT", etc
+     *
+     * @param timezoneID
+     * @return
+     */
+    public static String convertTimeZone(String timezoneID) {
+        String result = "";
+
+        TimeZone zone = TimeZone.getTimeZone(timezoneID);
+        int offset = zone.getRawOffset() / 1000;
+        int hour = offset / 3600;
+
+        DateFormat dfm = new SimpleDateFormat("z");
+        dfm.setTimeZone(zone);
+        boolean hasDaylight = zone.useDaylightTime();
+        String first = dfm.format(new Date(2010, 1, 1)).substring(0, 3); // make it only 3 letters code
+        String second = dfm.format(new Date(2011, 6, 6)).substring(0, 3); // make it only 3 letters code
+        int mid = hour * -1;
+        result = first + Integer.toString(mid);
+        if (hasDaylight) {
+            result = result + second;
+        }
+
+        return result;
+    }
+
+    /* The methods below are used to manage the case directories (creating, checking, deleting, etc) */
+    /**
+     * to create the case directory
+     * @param caseDir   the case directory path
+     * @param caseName  the case name
+     * @return boolean  whether the case directory is successfully created or not
+     */
+    static boolean createCaseDirectory(String caseDir, String caseName) {
+        boolean result = false;
+
+        try {
+            result = (new File(caseDir)).mkdirs(); // create root case Directory
+
+            // create the folders inside the case directory
+            result = result && (new File(caseDir + File.separator + XMLCaseManagement.EXPORT_FOLDER_RELPATH)).mkdir()
+                    && (new File(caseDir + File.separator + XMLCaseManagement.LOG_FOLDER_RELPATH)).mkdir()
+                    && (new File(caseDir + File.separator + XMLCaseManagement.TEMP_FOLDER_RELPATH)).mkdir();
+
+            return result;
+        } catch (Exception e) {
+            // TODO: change to use execptions instead of return values for error handling
+            return false;
+        }
+    }
+
+    /**
+     * delete the given case directory
+     * @param casePath  the case path
+     * @return boolean  whether the case directory is successfully deleted or not
+     */
+    static boolean deleteCaseDirectory(File casePath) {
+        if (casePath.exists()) {
+            File[] files = casePath.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isDirectory()) {
+                    deleteCaseDirectory(files[i]);
+                } else {
+                    files[i].delete();
+                }
+            }
+        }
+        return (casePath.delete());
+    }
+
+    /**
+     * Invoke the creation of startup dialog window.
+     */
+    static public void invokeStartupDialog() {
+        boolean showDialog = true;
+        String propFilePath = RecentCases.getPropertiesFilePath();
+
+        // before showing the startup dialog, check if it has been disabled or not by the user
+        try {
+            // try to load the property from the properties file in the home directory
+            InputStream inputStream = new FileInputStream(propFilePath);
+            //InputStream inputStream = getClass().getResourceAsStream("Case.properties"); // old variable (can be deleted if no longer needed)
+            properties.load(inputStream);
+
+            String temp = properties.getProperty(propStartup);
+            if (temp != null) {
+                showDialog = !temp.equals("false");
+            } else {
+                // if it's null, we have to write the properties
+
+                // update the properties
+                properties.setProperty(propStartup, "true");
+
+                // write the properties file
+                try {
+                    properties.store(new FileOutputStream(new File(RecentCases.getPropertiesFilePath())), "");
+                } catch (Exception ex) {
+                    Logger.getLogger(Case.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex);
+                }
+            }
+        } catch (Exception ex) {
+            // if cannot load it, we create a new properties file without any data inside it
+            properties.setProperty(propStartup, "true");
+
+            try {
+                // create the directory and property file to store it
+                File output = new File(propFilePath);
+
+                // if the properties file doesn't exist, we create a new one.
+                if (!output.exists()) {
+                    File parent = new File(output.getParent());
+                    if (!parent.exists()) {
+                        parent.mkdirs(); // create the parent directory if it doesn't exist
+                    }
+                    output.createNewFile(); // create the properties file
+                    FileOutputStream fos = new FileOutputStream(output);
+                    properties.store(fos, "");
+                } // if the output exist, we just add the properties
+                else {
+                    properties.setProperty(propStartup, "true");
+
+                    // write the properties file
+                    try {
+                        properties.store(new FileOutputStream(new File(RecentCases.getPropertiesFilePath())), "");
+                    } catch (Exception ex3) {
+                        Logger.getLogger(Case.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex3);
+                    }
+                }
+            } catch (Exception ex2) {
+                Logger.getLogger(Case.class.getName()).log(Level.WARNING, "Error: Could not create the property file.", ex2);
+            }
+        }
+
+        if (showDialog) {
+            StartupWindow.getInstance().display();
+        }
+    }
+
+
+
+    /**
+     * Call if there are no images in the case. Displays
+     * a dialog offering to add one.
+     */
+    private void noRootObjectsNotification() throws TskException {
+        NotifyDescriptor nd = new NotifyDescriptor(
+                "This case contains no images. Would you like to add one?",
+                "No images in case", NotifyDescriptor.YES_NO_OPTION,
+                NotifyDescriptor.INFORMATION_MESSAGE,
+                null,
+                NotifyDescriptor.YES_OPTION);
+        if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION) {
+            Lookup.getDefault().lookup(AddImageAction.class).actionPerformed(null);
+        }
+    }
+
+    /**
+     * Get the properties.
+     *
+     * @return properties
+     */
+    public Properties getProperties() {
+        return properties;
+    }
+
+    /**
+     * Checks if a String is a valid case name
+     * @param caseName the candidate String
+     * @return true if the candidate String is a valid case name
+     */
+    static public boolean isValidName(String caseName) {
+        return !(caseName.contains("\\") || caseName.contains("/") || caseName.contains(":")
+                    || caseName.contains("*") || caseName.contains("?") || caseName.contains("\"")
+                    || caseName.contains("<") || caseName.contains(">") || caseName.contains("|"));
+    }
+    
+    static private void clearTempFolder() {
+        File tempFolder = new File(currentCase.getTempDirectory());
+        if (tempFolder.isDirectory()) {
+            File[] files = tempFolder.listFiles();
+            if (files.length > 0) {
+                for (int i = 0; i < files.length; i++) {
+                    if (files[i].isDirectory()) {
+                        deleteCaseDirectory(files[i]);
+                    } else {
+                        files[i].delete();
+                    }
+                }
+            }
+        }
+    }
+
+    private static class CaseListener implements PropertyChangeListener {
+
+        CaseListener() {
+            pcs = new PropertyChangeSupport(this);
+            pcs.addPropertyChangeListener(this);
+        }
+
+        @Override
+        public void propertyChange(PropertyChangeEvent evt) {
+            String changed = evt.getPropertyName();
+            Object oldValue = evt.getOldValue();
+            Object newValue = evt.getNewValue();
+
+
+            if (changed.equals(Case.CASE_CURRENT_CASE)) {
+                try {
+                    if (newValue != null) { // new case is open
+                        Case newCase = (Case) newValue;
+
+                        // clear the temp folder when the case is created / opened
+                        Case.clearTempFolder();
+
+                        // enable these menus
+                        CallableSystemAction.get(AddImageAction.class).setEnabled(true);
+                        CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
+                        CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
+                        CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
+
+                        if (newCase.getRootObjectsCount() > 0) {
+                            // open all top components
+                            CoreComponentControl.openCoreWindows();
+                        } else {
+                            // close all top components
+                            CoreComponentControl.closeCoreWindows();
+                            // notify user
+                            newCase.noRootObjectsNotification();
+                        }
+                    } else { // case is closed
+                        // disable these menus
+                        CallableSystemAction.get(AddImageAction.class).setEnabled(false); // Add Image menu
+                        CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
+                        CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
+                        CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
+
+                        // close all top components
+                        CoreComponentControl.closeCoreWindows();
+
+                        Frame f = WindowManager.getDefault().getMainWindow();
+                        f.setTitle(Case.getAppName()); // set the window name to just application name
+                    }
+                } catch (TskException ex) {
+                    Log.get(CaseListener.class).log(Level.WARNING, "Error handling change in current case.", ex);
+                }
+            }
+
+
+            // changed in the case name
+            if (changed.equals(Case.CASE_NAME)) {
+                String oldCaseName = oldValue.toString();
+                String newCaseName = newValue.toString();
+
+                // update case name
+                if (!newCaseName.equals("")) {
+                    Frame f = WindowManager.getDefault().getMainWindow();
+                    f.setTitle(newCaseName + " - " + Case.getAppName()); // set the window name to the new value
+                }
+            }
+
+            // if the image is added to the case
+            if (changed.equals(Case.CASE_ADD_IMAGE)) {
+                // open all top components
+                CoreComponentControl.openCoreWindows();
+            }
+
+            // if the image is removed from the case
+            if (changed.equals(Case.CASE_DEL_IMAGE)) {
+                // no more image left in this case
+                if (currentCase.getRootObjectsCount() == 0) {
+                    // close all top components
+                    CoreComponentControl.closeCoreWindows();
+                }
+
+            }
+
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdfa3be36b04e62d1e9a77820c9a9e4e13e5f668
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseCloseAction.java
@@ -0,0 +1,132 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The action to close the current Case. This class should be disabled on
+ * creation and it will be enabled on new case creation or case opened.
+ */
+public final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar{
+
+    JButton toolbarButton = new JButton();
+
+    /**
+     * The constructor for this class
+     */
+    public CaseCloseAction() {
+        putValue("iconBase", "org/sleuthkit/autopsy/images/close-icon.png"); // put the icon
+        putValue(Action.NAME, NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct")); // put the action Name
+
+        // set action of the toolbar button
+        toolbarButton.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                CaseCloseAction.this.actionPerformed(e);
+            }
+        });
+
+        this.setEnabled(false);
+    }
+
+    /**
+     * Closes the current opened case.
+     *
+     * @param e  the action event for this method
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        if (Case.existsCurrentCase() == false)
+            return;
+        
+        Case result = Case.getCurrentCase();
+        try {
+            result.closeCase();
+        } catch (Exception ex) {
+            Logger.getLogger(CaseCloseAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex);
+        }
+    }
+
+    /**
+     * This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
+     */
+    @Override
+    public void performAction() {
+    }
+
+    /**
+     * Gets the name of this action. This may be presented as an item in a menu.
+     *
+     * @return actionName
+     */
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(CaseCloseAction.class, "CTL_CaseCloseAct");
+    }
+
+    /**
+     * Gets the HelpCtx associated with implementing object
+     * 
+     * @return HelpCtx or HelpCtx.DEFAULT_HELP
+     */
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP; 
+    }
+
+    /**
+     * Returns the toolbar component of this action
+     *
+     * @return component  the toolbar button
+     */
+    @Override
+    public Component getToolbarPresenter() {
+        ImageIcon icon = new ImageIcon(getClass().getResource("close-icon.png"));
+        toolbarButton.setIcon(icon);
+        return toolbarButton;
+    }
+
+    /**
+     * Set this action to be enabled/disabled
+     *
+     * @param value  whether to enable this action or not
+     */
+    @Override
+    public void setEnabled(boolean value){
+        super.setEnabled(value);
+        toolbarButton.setEnabled(value);
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e94393e0d6754bb4847ee518fa428b61fc81678
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseConfigFileInterface.java
@@ -0,0 +1,42 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+/**
+ * NOTE: NOTHING ACTUALLY USES THIS
+ * 
+ * The interface for the classes that edit the case configuration file
+ */
+//TODO: check that this can just be deleted.
+interface CaseConfigFileInterface {
+    public void open(String conFilePath) throws Exception;  // opens the confiuation store (XML, DB...)
+    public void writeFile() throws Exception;            // writes out the configuration to store
+    public void close() throws Exception;                   // close and clear the document handler
+    public int[] getImageIDs() throws Exception;            // returns a list of image IDs and names
+    public int getNextImageID() throws Exception;           // returns the next free ID to be assigned to new image, and increments the internal counter
+
+    // all the get and set methods
+    public String getCaseName() throws Exception; // get the case name
+    public void setCaseName(String caseName) throws Exception; // set the case name
+
+    // public void getXXX(); // methods to get the case attributes
+    // public void setXXX(); // methods to set the case attributes
+
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..523b6c62493a7b45a97d6013f9030060b7a8d200
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseDeleteAction.java
@@ -0,0 +1,117 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Action;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The action to delete the current Case. This class should be disabled on
+ * creation and it will be enabled on new case creation or case opened.
+ */
+public final class CaseDeleteAction extends CallableSystemAction {
+
+    private JPanel caller; // for error handling
+
+    /**
+     * The constructor for this class
+     */
+    public CaseDeleteAction() {
+        putValue(Action.NAME, NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction")); // put the action Name
+        this.setEnabled(false);
+    }
+
+    /**
+     * Deletes the current opened case.
+     * @param e
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        Case currentCase = Case.getCurrentCase();
+        File configFile = new File(currentCase.getConfigFilePath());
+        File caseFolder = new File(configFile.getParent());
+        String caseName = currentCase.getName();
+        if(!caseFolder.exists()){
+            // throw an error
+            Logger logger = Logger.getLogger(CaseDeleteAction.class.getName());
+            logger.log(Level.WARNING, "Couldn't delete case.", new Exception("The case directory doesn't exist."));
+        }
+        else{
+            // show the confirmation first to close the current case and open the "New Case" wizard panel
+            String closeCurrentCase = "Are you sure want to close and delete this case? \n     Case Name: " + caseName + "\n     Case Directory: "+ caseFolder.getPath();
+            NotifyDescriptor d = new NotifyDescriptor.Confirmation(closeCurrentCase, "Warning: Closing the Current Case", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+            d.setValue(NotifyDescriptor.NO_OPTION);
+
+            Object res = DialogDisplayer.getDefault().notify(d);
+            if(res != null && res == DialogDescriptor.YES_OPTION){
+                boolean success = Case.getCurrentCase().deleteCase(caseFolder); // delete the current case
+
+                // show notification whether the case has been deleted or it failed to delete...
+                if(!success){
+                    JOptionPane.showMessageDialog(caller, "The delete action can't be fully completed because the folder or file in it is open by another program.\n \nClose the folder and file and try again or you can delete the case manually.", "Error: Folder In Use", JOptionPane.ERROR_MESSAGE); // throw an error
+                }
+                else{
+                    CasePropertiesAction.closeCasePropertiesWindow(); // because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case.
+                    JOptionPane.showMessageDialog(caller, "Case " + caseName + " has been deleted.");
+                }
+            }
+        }
+    }
+
+    /**
+     * This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
+     */
+    @Override
+    public void performAction() {
+        // Note: I use the actionPerformed above instead of this method
+    }
+
+    /**
+     * Gets the name of this action. This may be presented as an item in a menu.
+     * @return actionName
+     */
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(CaseDeleteAction.class, "CTL_CaseDeleteAction");
+    }
+
+    /**
+     * Gets the HelpCtx associated with implementing object
+     * @return HelpCtx or HelpCtx.DEFAULT_HELP
+     */
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseNewAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseNewAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..89d51ea2a8bf06a0672d6c382181d41095a0fff7
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseNewAction.java
@@ -0,0 +1,48 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import org.openide.util.actions.SystemAction;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The action to create a new case. This action class is always enabled.
+ *
+ * @author jantonius
+ */
+@ServiceProvider(service = CaseNewAction.class)
+public final class CaseNewAction implements ActionListener {
+
+    private NewCaseWizardAction wizard = SystemAction.get(NewCaseWizardAction.class);
+
+    /**
+     * Calls the "New Case" wizard panel action.
+     * @param e
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        wizard.performAction();
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..48ebfeb63916d91fd79f184157972ff83d815a1e
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CaseOpenAction.java
@@ -0,0 +1,86 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The action to open a existing case. This class is always enabled.
+ *
+ * @author jantonius
+ */
+@ServiceProvider(service = CaseOpenAction.class)
+public final class CaseOpenAction implements ActionListener {
+
+    JFileChooser fc = new JFileChooser();
+    GeneralFilter autFilter = new GeneralFilter(new String[]{".aut"}, "AUTOPSY File (*.aut)", false);
+
+    /** The constructor */
+    public CaseOpenAction() {
+        fc.setDragEnabled(false);
+        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+        fc.setMultiSelectionEnabled(false);
+        fc.addChoosableFileFilter(autFilter);
+    }
+
+    /**
+     * Pop-up the File Chooser to open the existing case (.aut file)
+     * 
+     * @param e  the action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+
+        int retval = fc.showOpenDialog((Component) e.getSource());
+        if (retval == JFileChooser.APPROVE_OPTION) {
+            String path = fc.getSelectedFile().getPath();
+
+            // check if the file exists
+            if (!new File(path).exists()) {
+                JOptionPane.showMessageDialog(null, "Error: File doesn't exist.", "Error", JOptionPane.ERROR_MESSAGE);
+                this.actionPerformed(e); // show the dialog box again
+            } else {
+                // try to close Startup window if there's one
+                try {
+                    StartupWindow.getInstance().close();
+                } catch (Exception ex) {
+                    // no need to show the error message to the user.
+                    // TODO: But maybe put the error message in the log in the future.
+                }
+                try {
+                    Case.open(path); // open the case
+                } catch (Exception ex) {
+                    Logger.getLogger(CaseOpenAction.class.getName()).log(Level.SEVERE, "Error opening case.", ex);
+                }
+            }
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a5235e7e95c955be3763da833915b7c801aa243
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesAction.java
@@ -0,0 +1,139 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.logging.Level;
+import javax.swing.Action;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The action to pop up the Case Properties Form window. By using this form,
+ * user can update the case properties (for example: updates the case name and
+ * removes the image from the current case)
+ *
+ * @author jantonius
+ */
+public final class CasePropertiesAction extends CallableSystemAction {
+
+    private static JDialog popUpWindow;
+
+    /**
+     * The CasePropertiesAction constructor
+     */
+    CasePropertiesAction() {
+        putValue(Action.NAME, NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction")); // put the action Name
+        this.setEnabled(false);
+    }
+
+    /**
+     * Pop-up the Case Properties Form window where user can change the case
+     * properties (example: update case name and remove the image from the case)
+     */
+    @Override
+    public void performAction() {
+        Log.noteAction(this.getClass());
+        
+        try {
+            // create the popUp window for it
+            String title = "Case Properties";
+            final JFrame frame = new JFrame(title);
+            popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
+
+
+            // get the information that needed
+            Case currentCase = Case.getCurrentCase();
+            String caseName = currentCase.getName();
+            String crDate = currentCase.getCreatedDate();
+            String caseDir = currentCase.getCaseDirectory();
+            int totalImage = currentCase.getRootObjectsCount();
+
+            // put the image paths information into hashmap
+            HashMap<Integer, String[]> imgPaths = new HashMap<Integer, String[]>();
+            int[] imgIDs = currentCase.getImageIDs();
+
+            for (int i = 0; i < totalImage; i++) {
+                int imgID = imgIDs[i];
+                String[] imagePaths = currentCase.getImagePaths(imgID);
+                if (imagePaths != null) {
+                    imgPaths.put(imgID, imagePaths);
+                }
+            }
+
+            // create the case properties form
+            CasePropertiesForm cpf = new CasePropertiesForm(currentCase, crDate, caseDir, imgPaths);
+
+            // add the command to close the window to the button on the Case Properties form / panel
+            cpf.setOKButtonActionListener(new ActionListener() {
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    popUpWindow.dispose();
+                }
+            });
+
+            // add the case properties form / panel to the popup window
+            popUpWindow.add(cpf);
+            popUpWindow.pack();
+            popUpWindow.setResizable(false);
+
+            // set the location of the popUp Window on the center of the screen
+            Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+            double w = popUpWindow.getSize().getWidth();
+            double h = popUpWindow.getSize().getHeight();
+            popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
+
+            popUpWindow.setVisible(true);
+        } catch (Exception ex) {
+            Log.get(CasePropertiesAction.class).log(Level.WARNING, "Error displaying Case Properties window.", ex);
+        }
+    }
+
+    /**
+     * Gets the name of this action. This may be presented as an item in a menu.
+     * @return actionName
+     */
+    @Override
+    public String getName() {
+        return NbBundle.getMessage(CasePropertiesAction.class, "CTL_CasePropertiesAction");
+    }
+
+    /**
+     * Gets the HelpCtx associated with implementing object
+     * @return HelpCtx or HelpCtx.DEFAULT_HELP
+     */
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    static void closeCasePropertiesWindow() {
+        popUpWindow.dispose();
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form
new file mode 100644
index 0000000000000000000000000000000000000000..a37c13a2baef2e6530f1e89a47bb669acd21fa2d
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.form
@@ -0,0 +1,254 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <NonVisualComponents>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="jTextArea1">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="rows" type="int" value="5"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </NonVisualComponents>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="casePropLabel" pref="440" max="32767" attributes="0"/>
+                          <Component id="genInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Group type="102" alignment="0" attributes="0">
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="caseDirLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="crDateLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="caseNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <EmptySpace type="separate" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="jScrollPane2" pref="246" max="32767" attributes="0"/>
+                                  <Component id="caseNameTextField" alignment="0" pref="246" max="32767" attributes="1"/>
+                                  <Component id="crDateTextField" alignment="0" pref="246" max="32767" attributes="1"/>
+                              </Group>
+                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                                  <Component id="updateCaseNameButton" max="32767" attributes="1"/>
+                                  <Component id="deleteCaseButton" alignment="0" max="32767" attributes="1"/>
+                              </Group>
+                          </Group>
+                          <Component id="imgInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="imagesTableScrollPane" alignment="0" pref="440" max="32767" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="-2" pref="191" max="-2" attributes="0"/>
+                      <Component id="OKButton" min="-2" pref="78" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="casePropLabel" min="-2" pref="33" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="genInfoLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="caseNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="caseNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="updateCaseNameButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="crDateLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="crDateTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="caseDirLabel" min="-2" max="-2" attributes="0"/>
+                          <Component id="jScrollPane2" min="-2" pref="40" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace min="-2" pref="39" max="-2" attributes="0"/>
+                      <Component id="imgInfoLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Component id="deleteCaseButton" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="imagesTableScrollPane" min="-2" pref="170" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="OKButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="17" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="casePropLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="24" style="1"/>
+        </Property>
+        <Property name="horizontalAlignment" type="int" value="0"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.casePropLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="caseNameLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="crDateLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.crDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="caseDirLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="crDateTextField">
+      <Properties>
+        <Property name="editable" type="boolean" value="false"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.crDateTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="caseNameTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.caseNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="updateCaseNameButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.updateCaseNameButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="updateCaseNameButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="genInfoLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.genInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgInfoLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.imgInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="OKButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.OKButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Container class="javax.swing.JScrollPane" name="imagesTableScrollPane">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTable" name="imagesTable">
+          <Properties>
+            <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
+              <Table columnCount="2" rowCount="0">
+                <Column editable="false" title="Path" type="java.lang.Object"/>
+                <Column editable="true" title="Remove" type="java.lang.Object"/>
+              </Table>
+            </Property>
+            <Property name="showHorizontalLines" type="boolean" value="false"/>
+            <Property name="showVerticalLines" type="boolean" value="false"/>
+            <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
+              <TableHeader reorderingAllowed="false" resizingAllowed="true"/>
+            </Property>
+            <Property name="updateSelectionOnSort" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane2">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="caseDirTextArea">
+          <Properties>
+            <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+              <Color blue="f0" green="f0" red="f0" type="rgb"/>
+            </Property>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="editable" type="boolean" value="false"/>
+            <Property name="rows" type="int" value="1"/>
+            <Property name="requestFocusEnabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="deleteCaseButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CasePropertiesForm.deleteCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteCaseButtonActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..44c5dbc8b0ceb28ea97d1e7880f8feefe60dbeb3
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CasePropertiesForm.java
@@ -0,0 +1,399 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * CasePropertiesForm.java
+ *
+ * Created on Mar 14, 2011, 1:48:20 PM
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.table.DefaultTableModel;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ * The form where user can change / update the properties of the current case.
+ *
+ * @author jantonius
+ */
+class CasePropertiesForm extends javax.swing.JPanel{
+
+    Case current = null;
+    private static JPanel caller;    // panel for error
+    
+    // Shrink a path to fit in targetLength (if necessary), by replaceing part
+    // of the path with "...". Ex: "C:\Users\bob\...\folder\other\Image.img"
+    private String shrinkPath(String path, int targetLength) {
+        if(path.length() > targetLength){
+            String fill = "...";
+            
+            int partsLength = targetLength - fill.length();
+            
+            String front = path.substring(0, partsLength/4);
+            int frontSep = front.lastIndexOf(File.separatorChar);
+            if (frontSep != -1) {
+                front = front.substring(0, frontSep+1);
+            }
+            
+            String back = path.substring(partsLength*3/4);
+            int backSep = back.indexOf(File.separatorChar);
+            if (backSep != -1) {
+                back = back.substring(backSep);
+            }
+            return back + fill + front;
+        } else {
+            return path;
+        }
+    }
+    
+    
+    /** Creates new form CasePropertiesForm */
+    CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Integer,String[]> imgPaths) {
+        initComponents();
+        caseNameTextField.setText(currentCase.getName());
+        crDateTextField.setText(crDate);
+        caseDirTextArea.setText(caseDir);
+
+        current = currentCase;
+
+        int totalImages = imgPaths.size();
+       
+        // create the headers and add all the rows
+        String[] headers = {"Path"};
+        String[][] rows = new String[totalImages][];
+        
+        int i = 0;
+        for(int key : imgPaths.keySet()){
+            String path = imgPaths.get(key)[0];
+            String shortenPath = shrinkPath(path, 70);
+            rows[i++] = new String[]{shortenPath};
+        }
+
+        // create the table inside with the imgPaths information
+        DefaultTableModel model = new DefaultTableModel(rows, headers)
+        {
+            @Override
+            // make the cells in the FileContentTable "read only"
+            public boolean isCellEditable(int row, int column){
+                return false;
+                //return column == lastColumn; // make the last column (Remove button), only the editable
+            }
+        };
+        imagesTable.setModel(model);
+        
+//        // set the size of the remove column
+//        TableColumn removeCol = imagesTable.getColumnModel().getColumn(lastColumn);
+//        removeCol.setPreferredWidth(75);
+//        removeCol.setMaxWidth(75);
+//        removeCol.setMinWidth(75);
+//        removeCol.setResizable(false);
+
+//        // create the delete action to remove the image from the current case
+//        Action delete = new AbstractAction()
+//        {
+//            @Override
+//            public void actionPerformed(ActionEvent e)
+//            {
+//                // get the image path
+//                JTable table = (JTable)e.getSource();
+//                int modelRow = Integer.valueOf(e.getActionCommand());
+//                String removeColumn = table.getValueAt(modelRow, lastColumn).toString();
+//                // get the image ID
+//                int selectedID = Integer.parseInt(removeColumn.substring(0, removeColumn.indexOf('|')));
+//                String imagePath = removeColumn.substring(removeColumn.indexOf('|') + 1);
+//
+//                // throw the confirmation first
+//                String confMsg = "Are you sure want to remove image \"" + imagePath + "\" from this case?";
+//                NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg, "Create directory", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+//                d.setValue(NotifyDescriptor.NO_OPTION);
+//
+//                Object res = DialogDisplayer.getDefault().notify(d);
+//                // if user select "Yes"
+//                if(res != null && res == DialogDescriptor.YES_OPTION){
+//                    // remove the image in the case class and in the xml config file
+//                    try {
+//                        current.removeImage(selectedID, imagePath);
+//                    } catch (Exception ex) {
+//                        Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: couldn't remove image.", ex);
+//                    }
+//                    // remove the row of the image path
+//                    ((DefaultTableModel)table.getModel()).removeRow(modelRow);
+//                }
+//            }
+//        };
+//
+//        ButtonColumn buttonColumn = new ButtonColumn(imagesTable, delete, 1, "Remove");
+//        buttonColumn.setMnemonic(KeyEvent.VK_D);
+    }
+
+    /** This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jTextArea1 = new javax.swing.JTextArea();
+        casePropLabel = new javax.swing.JLabel();
+        caseNameLabel = new javax.swing.JLabel();
+        crDateLabel = new javax.swing.JLabel();
+        caseDirLabel = new javax.swing.JLabel();
+        crDateTextField = new javax.swing.JTextField();
+        caseNameTextField = new javax.swing.JTextField();
+        updateCaseNameButton = new javax.swing.JButton();
+        genInfoLabel = new javax.swing.JLabel();
+        imgInfoLabel = new javax.swing.JLabel();
+        OKButton = new javax.swing.JButton();
+        imagesTableScrollPane = new javax.swing.JScrollPane();
+        imagesTable = new javax.swing.JTable();
+        jScrollPane2 = new javax.swing.JScrollPane();
+        caseDirTextArea = new javax.swing.JTextArea();
+        deleteCaseButton = new javax.swing.JButton();
+
+        jTextArea1.setColumns(20);
+        jTextArea1.setRows(5);
+        jScrollPane1.setViewportView(jTextArea1);
+
+        casePropLabel.setFont(new java.awt.Font("Tahoma", 1, 24));
+        casePropLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+        casePropLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.casePropLabel.text")); // NOI18N
+
+        caseNameLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameLabel.text")); // NOI18N
+
+        crDateLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.crDateLabel.text")); // NOI18N
+
+        caseDirLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseDirLabel.text")); // NOI18N
+
+        crDateTextField.setEditable(false);
+        crDateTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.crDateTextField.text")); // NOI18N
+
+        caseNameTextField.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.caseNameTextField.text")); // NOI18N
+
+        updateCaseNameButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.updateCaseNameButton.text")); // NOI18N
+        updateCaseNameButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                updateCaseNameButtonActionPerformed(evt);
+            }
+        });
+
+        genInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 14));
+        genInfoLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.genInfoLabel.text")); // NOI18N
+
+        imgInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 14));
+        imgInfoLabel.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.imgInfoLabel.text")); // NOI18N
+
+        OKButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.OKButton.text")); // NOI18N
+
+        imagesTable.setModel(new javax.swing.table.DefaultTableModel(
+            new Object [][] {
+
+            },
+            new String [] {
+                "Path", "Remove"
+            }
+        ) {
+            boolean[] canEdit = new boolean [] {
+                false, true
+            };
+
+            public boolean isCellEditable(int rowIndex, int columnIndex) {
+                return canEdit [columnIndex];
+            }
+        });
+        imagesTable.setShowHorizontalLines(false);
+        imagesTable.setShowVerticalLines(false);
+        imagesTable.getTableHeader().setReorderingAllowed(false);
+        imagesTable.setUpdateSelectionOnSort(false);
+        imagesTableScrollPane.setViewportView(imagesTable);
+
+        caseDirTextArea.setBackground(new java.awt.Color(240, 240, 240));
+        caseDirTextArea.setColumns(20);
+        caseDirTextArea.setEditable(false);
+        caseDirTextArea.setRows(1);
+        caseDirTextArea.setRequestFocusEnabled(false);
+        jScrollPane2.setViewportView(caseDirTextArea);
+
+        deleteCaseButton.setText(org.openide.util.NbBundle.getMessage(CasePropertiesForm.class, "CasePropertiesForm.deleteCaseButton.text")); // NOI18N
+        deleteCaseButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                deleteCaseButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addContainerGap()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(casePropLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)
+                            .addComponent(genInfoLabel)
+                            .addGroup(layout.createSequentialGroup()
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addComponent(caseDirLabel)
+                                    .addComponent(crDateLabel)
+                                    .addComponent(caseNameLabel))
+                                .addGap(18, 18, 18)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
+                                    .addComponent(caseNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
+                                    .addComponent(crDateTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                    .addComponent(updateCaseNameButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                    .addComponent(deleteCaseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                            .addComponent(imgInfoLabel)
+                            .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)))
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(191, 191, 191)
+                        .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(casePropLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(18, 18, 18)
+                .addComponent(genInfoLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(caseNameLabel)
+                    .addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(updateCaseNameButton))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(crDateLabel)
+                    .addComponent(crDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(caseDirLabel)
+                            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addGap(39, 39, 39)
+                        .addComponent(imgInfoLabel))
+                    .addComponent(deleteCaseButton))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(OKButton)
+                .addContainerGap(17, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * Updates the case name.
+     *
+     * @param evt  The action event
+     */
+    private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
+        String oldCaseName = Case.getCurrentCase().getName();
+        String newCaseName = caseNameTextField.getText();
+        //String oldPath = caseDirTextArea.getText() + File.separator + oldCaseName + ".aut";
+        //String newPath = caseDirTextArea.getText() + File.separator + newCaseName + ".aut";
+
+        // check if the old and new case name is not equal
+        if(!oldCaseName.equals(newCaseName)){
+
+            // check if the case name is empty
+            if(newCaseName.trim().equals("")){
+                JOptionPane.showMessageDialog(caller, "The caseName cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
+            }
+            else{
+                // check if case Name contain one of this following symbol:
+                //  \ / : * ? " < > |
+                if(newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":") ||
+                   newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"") ||
+                   newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")){
+                    String errorMsg = "The Case Name cannot contain any of this following symbol: \\ / : * ? \" < > |";
+                    JOptionPane.showMessageDialog(caller, errorMsg, "Error", JOptionPane.ERROR_MESSAGE);
+                }
+                else{
+                    // ask for the confirmation first
+                    String confMsg = "Are you sure want to update the case name from \"" + oldCaseName + "\" to \"" + newCaseName + "\"?";
+                    NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg, "Create directory", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+                    d.setValue(NotifyDescriptor.NO_OPTION);
+
+                    Object res = DialogDisplayer.getDefault().notify(d);
+                    if(res != null && res == DialogDescriptor.YES_OPTION){
+                        // if user select "Yes"
+                        String oldPath = current.getConfigFilePath();
+                        try {
+                            current.updateCaseName(oldCaseName, oldPath , newCaseName, oldPath);
+                        } catch (Exception ex) {
+                            Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex);
+                        }
+                    }
+                }
+            }
+        }
+    }//GEN-LAST:event_updateCaseNameButtonActionPerformed
+
+    private void deleteCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteCaseButtonActionPerformed
+        CallableSystemAction.get(CaseDeleteAction.class).actionPerformed(evt);
+    }//GEN-LAST:event_deleteCaseButtonActionPerformed
+
+
+    /**
+     * Sets the listener for the OK button
+     *
+     * @param e  The action listener
+     */
+    public void setOKButtonActionListener(ActionListener e){
+        OKButton.addActionListener(e);
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton OKButton;
+    private javax.swing.JLabel caseDirLabel;
+    private javax.swing.JTextArea caseDirTextArea;
+    private javax.swing.JLabel caseNameLabel;
+    private javax.swing.JTextField caseNameTextField;
+    private javax.swing.JLabel casePropLabel;
+    private javax.swing.JLabel crDateLabel;
+    private javax.swing.JTextField crDateTextField;
+    private javax.swing.JButton deleteCaseButton;
+    private javax.swing.JLabel genInfoLabel;
+    private javax.swing.JTable imagesTable;
+    private javax.swing.JScrollPane imagesTableScrollPane;
+    private javax.swing.JLabel imgInfoLabel;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JScrollPane jScrollPane2;
+    private javax.swing.JTextArea jTextArea1;
+    private javax.swing.JButton updateCaseNameButton;
+    // End of variables declaration//GEN-END:variables
+
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form b/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..99dabefd5886694e891eb953a91e7f7a50b50dad
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.form
@@ -0,0 +1,299 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="startupCheckBox" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace pref="345" max="32767" attributes="0"/>
+                      <Component id="closeButton" min="-2" pref="73" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="logoPanel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="editorPanel" max="32767" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="editorPanel" max="32767" attributes="0"/>
+                  <Component id="logoPanel" alignment="0" max="32767" attributes="0"/>
+              </Group>
+              <EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="1" attributes="0">
+                  <Component id="closeButton" alignment="1" min="-2" max="-2" attributes="0"/>
+                  <Component id="startupCheckBox" alignment="1" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JCheckBox" name="startupCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.startupCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="closeButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="closeButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Container class="javax.swing.JPanel" name="logoPanel">
+      <Properties>
+        <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+          <Color blue="ff" green="ff" red="ff" type="rgb"/>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace pref="13" max="32767" attributes="0"/>
+                  <Component id="autopsyLogo" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="55" max="-2" attributes="0"/>
+                  <Component id="autopsyLogo" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace pref="131" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="autopsyLogo">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/Autopsy_logo.gif"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.autopsyLogo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="this.autopsyLogo.setText(&quot;&quot;);"/>
+          </AuxValues>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="editorPanel">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="welcomeLabel" min="-2" max="-2" attributes="0"/>
+                      <Component id="autopsyLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="1" attributes="0">
+                              <Component id="openCaseButton" alignment="1" min="-2" max="-2" attributes="1"/>
+                              <Component id="newCaseButton" alignment="1" min="-2" max="-2" attributes="1"/>
+                              <Component id="openRecentButton" alignment="1" min="-2" pref="70" max="-2" attributes="1"/>
+                          </Group>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Component id="openLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="createNewLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="openRecentLabel" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                  </Group>
+                  <EmptySpace pref="124" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="welcomeLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="autopsyLabel" min="-2" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
+                          <Component id="newCaseButton" min="-2" pref="68" max="-2" attributes="0"/>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Component id="openCaseButton" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Component id="openRecentButton" min="-2" pref="67" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="17" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="1">
+                          <EmptySpace min="-2" pref="41" max="-2" attributes="0"/>
+                          <Component id="createNewLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="72" max="-2" attributes="0"/>
+                          <Component id="openLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace pref="70" max="32767" attributes="0"/>
+                          <Component id="openRecentLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="45" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="welcomeLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="18" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.welcomeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="autopsyLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="32" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.autopsyLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="this.autopsyLabel.setText(Case.getAppName());"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JButton" name="newCaseButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/new-icon.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.newCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+              <Connection code="null" type="code"/>
+            </Property>
+            <Property name="borderPainted" type="boolean" value="false"/>
+            <Property name="contentAreaFilled" type="boolean" value="false"/>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[70, 70]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newCaseButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="openCaseButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/open-icon.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openCaseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+              <Connection code="null" type="code"/>
+            </Property>
+            <Property name="borderPainted" type="boolean" value="false"/>
+            <Property name="contentAreaFilled" type="boolean" value="false"/>
+            <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+              <Insets value="[1, 1, 1, 1]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[70, 70]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openCaseButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="openRecentButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/casemodule/open-recent-icon.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openRecentButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+              <Connection code="null" type="code"/>
+            </Property>
+            <Property name="borderPainted" type="boolean" value="false"/>
+            <Property name="contentAreaFilled" type="boolean" value="false"/>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[70, 70]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openRecentButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JLabel" name="createNewLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="13" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.createNewLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="openLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="13" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="openRecentLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="13" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="CueBannerPanel.openRecentLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java b/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..4672933f191ed0e6a001b3785ce87b6ccf61efa9
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/CueBannerPanel.java
@@ -0,0 +1,333 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author jantonius
+ */
+public class CueBannerPanel extends javax.swing.JPanel {
+
+    final private static String title = "Open Recent Case";
+    final private static JFrame frame = new JFrame(title);
+    final static JDialog recentCasesWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
+
+    // for error handling
+    private static JPanel caller = new JPanel();
+    private String className = this.getClass().toString();
+
+    /** Creates new form CueBannerPanel */
+    public CueBannerPanel() {
+        initComponents();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        startupCheckBox = new javax.swing.JCheckBox();
+        closeButton = new javax.swing.JButton();
+        logoPanel = new javax.swing.JPanel();
+        autopsyLogo = new javax.swing.JLabel();
+        this.autopsyLogo.setText("");
+        editorPanel = new javax.swing.JPanel();
+        welcomeLabel = new javax.swing.JLabel();
+        autopsyLabel = new javax.swing.JLabel();
+        this.autopsyLabel.setText(Case.getAppName());
+        newCaseButton = new javax.swing.JButton();
+        openCaseButton = new javax.swing.JButton();
+        openRecentButton = new javax.swing.JButton();
+        createNewLabel = new javax.swing.JLabel();
+        openLabel = new javax.swing.JLabel();
+        openRecentLabel = new javax.swing.JLabel();
+
+        startupCheckBox.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.startupCheckBox.text")); // NOI18N
+
+        closeButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.closeButton.text")); // NOI18N
+        closeButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                closeButtonActionPerformed(evt);
+            }
+        });
+
+        logoPanel.setBackground(new java.awt.Color(255, 255, 255));
+
+        autopsyLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/Autopsy_logo.gif"))); // NOI18N
+        autopsyLogo.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.autopsyLogo.text")); // NOI18N
+
+        javax.swing.GroupLayout logoPanelLayout = new javax.swing.GroupLayout(logoPanel);
+        logoPanel.setLayout(logoPanelLayout);
+        logoPanelLayout.setHorizontalGroup(
+            logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(logoPanelLayout.createSequentialGroup()
+                .addContainerGap(13, Short.MAX_VALUE)
+                .addComponent(autopsyLogo)
+                .addContainerGap())
+        );
+        logoPanelLayout.setVerticalGroup(
+            logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(logoPanelLayout.createSequentialGroup()
+                .addGap(55, 55, 55)
+                .addComponent(autopsyLogo)
+                .addContainerGap(131, Short.MAX_VALUE))
+        );
+
+        welcomeLabel.setFont(new java.awt.Font("Tahoma", 1, 18));
+        welcomeLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.welcomeLabel.text")); // NOI18N
+
+        autopsyLabel.setFont(new java.awt.Font("Tahoma", 1, 32)); // NOI18N
+        autopsyLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.autopsyLabel.text")); // NOI18N
+
+        newCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/new-icon.png"))); // NOI18N
+        newCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.newCaseButton.text")); // NOI18N
+        newCaseButton.setBorder(null);
+        newCaseButton.setBorderPainted(false);
+        newCaseButton.setContentAreaFilled(false);
+        newCaseButton.setPreferredSize(new java.awt.Dimension(70, 70));
+        newCaseButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                newCaseButtonActionPerformed(evt);
+            }
+        });
+
+        openCaseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/open-icon.png"))); // NOI18N
+        openCaseButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openCaseButton.text")); // NOI18N
+        openCaseButton.setBorder(null);
+        openCaseButton.setBorderPainted(false);
+        openCaseButton.setContentAreaFilled(false);
+        openCaseButton.setMargin(new java.awt.Insets(1, 1, 1, 1));
+        openCaseButton.setPreferredSize(new java.awt.Dimension(70, 70));
+        openCaseButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                openCaseButtonActionPerformed(evt);
+            }
+        });
+
+        openRecentButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/casemodule/open-recent-icon.png"))); // NOI18N
+        openRecentButton.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openRecentButton.text")); // NOI18N
+        openRecentButton.setBorder(null);
+        openRecentButton.setBorderPainted(false);
+        openRecentButton.setContentAreaFilled(false);
+        openRecentButton.setPreferredSize(new java.awt.Dimension(70, 70));
+        openRecentButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                openRecentButtonActionPerformed(evt);
+            }
+        });
+
+        createNewLabel.setFont(new java.awt.Font("Tahoma", 0, 13));
+        createNewLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.createNewLabel.text")); // NOI18N
+
+        openLabel.setFont(new java.awt.Font("Tahoma", 0, 13));
+        openLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openLabel.text")); // NOI18N
+
+        openRecentLabel.setFont(new java.awt.Font("Tahoma", 0, 13));
+        openRecentLabel.setText(org.openide.util.NbBundle.getMessage(CueBannerPanel.class, "CueBannerPanel.openRecentLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout editorPanelLayout = new javax.swing.GroupLayout(editorPanel);
+        editorPanel.setLayout(editorPanelLayout);
+        editorPanelLayout.setHorizontalGroup(
+            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(editorPanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(welcomeLabel)
+                    .addComponent(autopsyLabel)
+                    .addGroup(editorPanelLayout.createSequentialGroup()
+                        .addGap(19, 19, 19)
+                        .addGroup(editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                            .addComponent(openCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                            .addComponent(newCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                            .addComponent(openRecentButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addGap(18, 18, 18)
+                        .addGroup(editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(openLabel)
+                            .addComponent(createNewLabel)
+                            .addComponent(openRecentLabel))))
+                .addContainerGap(124, Short.MAX_VALUE))
+        );
+        editorPanelLayout.setVerticalGroup(
+            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(editorPanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(welcomeLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(autopsyLabel)
+                .addGroup(editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(editorPanelLayout.createSequentialGroup()
+                        .addGap(18, 18, 18)
+                        .addComponent(newCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(18, 18, 18)
+                        .addComponent(openCaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(18, 18, 18)
+                        .addComponent(openRecentButton, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(17, 17, 17))
+                    .addGroup(editorPanelLayout.createSequentialGroup()
+                        .addGap(41, 41, 41)
+                        .addComponent(createNewLabel)
+                        .addGap(72, 72, 72)
+                        .addComponent(openLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 70, Short.MAX_VALUE)
+                        .addComponent(openRecentLabel)
+                        .addGap(45, 45, 45))))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(startupCheckBox)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 345, Short.MAX_VALUE)
+                        .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(editorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(editorPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .addGap(20, 20, 20)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(closeButton)
+                    .addComponent(startupCheckBox))
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void newCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newCaseButtonActionPerformed
+        Lookup.getDefault().lookup(CaseNewAction.class).actionPerformed(evt);
+    }//GEN-LAST:event_newCaseButtonActionPerformed
+
+    private void openCaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openCaseButtonActionPerformed
+        Lookup.getDefault().lookup(CaseOpenAction.class).actionPerformed(evt);
+    }//GEN-LAST:event_openCaseButtonActionPerformed
+
+    private void openRecentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRecentButtonActionPerformed
+
+        // open the recent cases dialog
+        Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+
+        // set the popUp window / JFrame
+        recentCasesWindow.setSize(750, 400);
+
+        int w = recentCasesWindow.getSize().width;
+        int h = recentCasesWindow.getSize().height;
+
+        // set the location of the popUp Window on the center of the screen
+        recentCasesWindow.setLocation((screenDimension.width - w)/2, (screenDimension.height - h)/2);
+
+        OpenRecentCasePanel welcomeWindow = new OpenRecentCasePanel();
+
+        // add the command to close the window to the button on the Volume Detail Panel
+        welcomeWindow.setCloseButtonActionListener( new ActionListener(){
+            @Override
+            public void actionPerformed(ActionEvent e){
+                recentCasesWindow.dispose();
+            }
+        });
+
+        recentCasesWindow.add(welcomeWindow);
+        recentCasesWindow.pack();
+        recentCasesWindow.setResizable(false);
+        recentCasesWindow.setVisible(true);
+    }//GEN-LAST:event_openRecentButtonActionPerformed
+
+    private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
+        if(this.startupCheckBox.isSelected()){
+            
+            Case current = Case.getCurrentCase();
+            Properties properties = current.getProperties();
+
+            // update the properties
+            properties.setProperty(current.propStartup, "false");
+
+            // write the properties file
+            try{
+                properties.store(new FileOutputStream(new File(RecentCases.getPropertiesFilePath())), "");
+            }
+            catch(Exception ex){
+                Logger.getLogger(this.className).log(Level.WARNING, "Error: Could not update the properties file.", ex);
+            }
+        }
+    }//GEN-LAST:event_closeButtonActionPerformed
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel autopsyLabel;
+    private javax.swing.JLabel autopsyLogo;
+    private javax.swing.JButton closeButton;
+    private javax.swing.JLabel createNewLabel;
+    private javax.swing.JPanel editorPanel;
+    private javax.swing.JPanel logoPanel;
+    private javax.swing.JButton newCaseButton;
+    private javax.swing.JButton openCaseButton;
+    private javax.swing.JLabel openLabel;
+    private javax.swing.JButton openRecentButton;
+    private javax.swing.JLabel openRecentLabel;
+    private javax.swing.JCheckBox startupCheckBox;
+    private javax.swing.JLabel welcomeLabel;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Sets the Close button action listener.
+     *
+     * @param e  the action listener
+     */
+    public void setCloseButtonActionListener(ActionListener e){
+        closeButton.addActionListener(e);
+    }
+
+    /**
+     * Close the open recent cases window.
+     */
+    public static void closeOpenRecentCasesWindow(){
+        //startupWindow.setVisible(false);
+        recentCasesWindow.dispose();
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/GeneralFilter.java b/Case/src/org/sleuthkit/autopsy/casemodule/GeneralFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..390a09beb6c51d15847fd0dbde99a27a83bc1cec
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/GeneralFilter.java
@@ -0,0 +1,84 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.File;
+import java.util.regex.Pattern;
+import javax.swing.filechooser.FileFilter;
+
+/**
+ * FileFilter helper class. Matches files based on extension
+ */
+public class GeneralFilter extends FileFilter{
+
+    String[] ext;
+    String desc;
+    boolean isMultiple; // whether the filter can accept multiple files.
+
+    public GeneralFilter(String[] ext, String desc, boolean isMultiple){
+        this.ext = ext;
+        this.desc = desc;
+        this.isMultiple = isMultiple;
+    }
+
+    /**
+     * Checks whether the given file is accepted by this filter.
+     *
+     * @param f         the given file
+     * @return boolean  return true if accepted, false otherwise
+     */
+    @Override
+    public boolean accept(File f) {
+        if(f.isDirectory()){
+            return true;
+        }
+        else{
+            Boolean result = false;
+            String name = f.getName().toLowerCase();
+
+            if(isMultiple){
+                for(int i = 0; i < ext.length; i++){
+                    String regex = ext[i];
+                    if (Pattern.matches(regex, name)){
+                        result = result || true;
+                    }
+                }
+            }
+            else{
+                for(int i = 0; i < ext.length; i++){
+                    if (name.endsWith(ext[i]))
+                        result = result || true;
+                }
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Returns the description of this file filter
+     *
+     * @return desc  return the description
+     */
+    @Override
+    public String getDescription() {
+        return desc;
+    }
+
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form
new file mode 100644
index 0000000000000000000000000000000000000000..1fb4b5286f5eab3dd39f330e16338388f099ae6e
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.form
@@ -0,0 +1,136 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Group type="103" groupAlignment="1" max="-2" attributes="0">
+                          <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Group type="102" alignment="0" attributes="0">
+                              <Component id="caseDirLabel" min="-2" max="-2" attributes="0"/>
+                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                              <Component id="caseParentDirTextField" min="-2" pref="296" max="-2" attributes="0"/>
+                          </Group>
+                          <Group type="102" alignment="0" attributes="0">
+                              <Component id="caseNameLabel" min="-2" max="-2" attributes="0"/>
+                              <EmptySpace min="-2" pref="26" max="-2" attributes="0"/>
+                              <Component id="caseNameTextField" min="-2" pref="296" max="-2" attributes="0"/>
+                          </Group>
+                          <Component id="caseDirTextField" alignment="0" min="-2" pref="380" max="-2" attributes="1"/>
+                      </Group>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="caseDirBrowseButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="caseNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="caseNameTextField" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="caseDirLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="caseParentDirTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="caseDirBrowseButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="caseDirTextField" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="32" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="14" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.jLabel1.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="caseNameLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseNameLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="caseDirLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseDirLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="caseNameTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseNameTextField.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="caseParentDirTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseParentDirTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="caseDirBrowseButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseDirBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="caseDirBrowseButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel2">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.jLabel2.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="caseDirTextField">
+      <Properties>
+        <Property name="editable" type="boolean" value="false"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="NewCaseVisualPanel1.caseDirTextField.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java
new file mode 100644
index 0000000000000000000000000000000000000000..111f3311344c8da79f7609b789ece51c0d464f0d
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseVisualPanel1.java
@@ -0,0 +1,251 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.io.File;
+import javax.swing.JFileChooser;
+import javax.swing.JPanel;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+/**
+ * The wizard panel for the new case creation.
+ *
+ * @author jantonius
+ */
+final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
+
+    private JFileChooser fc = new JFileChooser();
+    private NewCaseWizardPanel1 wizPanel;
+
+    NewCaseVisualPanel1(NewCaseWizardPanel1 wizPanel) {
+        initComponents();
+                this.wizPanel = wizPanel;
+        caseNameTextField.getDocument().addDocumentListener(this);
+        caseParentDirTextField.getDocument().addDocumentListener(this);
+    }
+
+    /**
+     * Returns the name of the this panel. This name will be shown on the left
+     * panel of the "New Case" wizard panel.
+     *
+     * @return name  the name of this panel
+     */
+    @Override
+    public String getName() {
+        return "Case Info";
+    }
+
+    /**
+     * Gets the case name that the user types on the case name text field.
+     *
+     * @return caseName  the case name from the case name text field
+     */
+    public String getCaseName(){
+        return this.caseNameTextField.getText();
+    }
+
+    /**
+     * Gets the base directory that the user typed on the base directory text field.
+     *
+     * @return baseDirectory  the base directory from the case dir text field
+     */
+    public String getCaseParentDir(){
+        return this.caseParentDirTextField.getText();
+    }
+
+    /** This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jLabel1 = new javax.swing.JLabel();
+        caseNameLabel = new javax.swing.JLabel();
+        caseDirLabel = new javax.swing.JLabel();
+        caseNameTextField = new javax.swing.JTextField();
+        caseParentDirTextField = new javax.swing.JTextField();
+        caseDirBrowseButton = new javax.swing.JButton();
+        jLabel2 = new javax.swing.JLabel();
+        caseDirTextField = new javax.swing.JTextField();
+
+        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 14));
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.jLabel1.text_1")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(caseNameLabel, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseNameLabel.text_1")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(caseDirLabel, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseDirLabel.text")); // NOI18N
+
+        caseNameTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseNameTextField.text_1")); // NOI18N
+
+        caseParentDirTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseParentDirTextField.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(caseDirBrowseButton, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseDirBrowseButton.text")); // NOI18N
+        caseDirBrowseButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                caseDirBrowseButtonActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.jLabel2.text_1")); // NOI18N
+
+        caseDirTextField.setEditable(false);
+        caseDirTextField.setText(org.openide.util.NbBundle.getMessage(NewCaseVisualPanel1.class, "NewCaseVisualPanel1.caseDirTextField.text_1")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jLabel2)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+                            .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+                                .addComponent(caseDirLabel)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(caseParentDirTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE))
+                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+                                .addComponent(caseNameLabel)
+                                .addGap(26, 26, 26)
+                                .addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 296, javax.swing.GroupLayout.PREFERRED_SIZE))
+                            .addComponent(caseDirTextField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 380, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(caseDirBrowseButton)))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(31, 31, 31)
+                .addComponent(jLabel1)
+                .addGap(18, 18, 18)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(caseNameLabel)
+                    .addComponent(caseNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(caseDirLabel)
+                    .addComponent(caseParentDirTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(caseDirBrowseButton))
+                .addGap(18, 18, 18)
+                .addComponent(jLabel2)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(caseDirTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(32, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * The action when the Browse button is pressed. The browse button will pop
+     * up the file chooser window to choose where the user wants to save the 
+     * case directory.
+     *
+     * @param evt  the action event
+     */
+    private void caseDirBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseDirBrowseButtonActionPerformed
+        // show the directory chooser where the case directory will be created
+        fc.setDragEnabled(false);
+        if(!caseParentDirTextField.getText().trim().equals("")){
+            fc.setSelectedFile(new File(caseParentDirTextField.getText()));
+        }
+        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+        //fc.setSelectedFile(new File("C:\\Program Files\\"));
+        //disableTextField(fc); // disable all the text field on the file chooser
+
+        int returnValue = fc.showSaveDialog((Component)evt.getSource());
+        if(returnValue == JFileChooser.APPROVE_OPTION){
+            String path = fc.getSelectedFile().getPath();
+            caseParentDirTextField.setText(path); // put the path to the textfield
+         }
+    }//GEN-LAST:event_caseDirBrowseButtonActionPerformed
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton caseDirBrowseButton;
+    private javax.swing.JLabel caseDirLabel;
+    private javax.swing.JTextField caseDirTextField;
+    private javax.swing.JLabel caseNameLabel;
+    private javax.swing.JTextField caseNameTextField;
+    private javax.swing.JTextField caseParentDirTextField;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Gives notification that there was an insert into the document.  The
+     * range given by the DocumentEvent bounds the freshly inserted region.
+     *
+     * @param e  the document event
+     */
+    @Override
+    public void insertUpdate(DocumentEvent e) {
+        this.wizPanel.fireChangeEvent();
+        updateUI(e);
+    }
+
+    /**
+     * Gives notification that a portion of the document has been
+     * removed.  The range is given in terms of what the view last
+     * saw (that is, before updating sticky positions).
+     *
+     * @param e  the document event
+     */
+    @Override
+    public void removeUpdate(DocumentEvent e) {
+        this.wizPanel.fireChangeEvent();
+        updateUI(e);
+    }
+
+    /**
+     * Gives notification that an attribute or set of attributes changed.
+     *
+     * @param e  the document event
+     */
+    @Override
+    public void changedUpdate(DocumentEvent e) {
+        this.wizPanel.fireChangeEvent();
+        updateUI(e);
+    }
+
+    /**
+     * The "listener" that listens when the fields in this form are updated.
+     * This method is used to determine when to enable / disable the "Finish" button.
+     *
+     * @param e  the document event
+     */
+    public void updateUI(DocumentEvent e) {
+
+        String caseName = this.caseNameTextField.getText();
+        String caseDir = this.caseParentDirTextField.getText();
+
+        if(!caseName.equals("") && !caseDir.equals("")){
+            caseDirTextField.setText( caseDir + File.separator + caseName);
+            wizPanel.setIsFinish(true);
+        }
+        else{
+            caseDirTextField.setText("");
+            wizPanel.setIsFinish(false);
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e07f6fbd2b1d1a4c1c070e50e64b824c62a8e28
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardAction.java
@@ -0,0 +1,157 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Component;
+import java.awt.Dialog;
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JComponent;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.SystemAction;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * Action to open the New Case wizard.
+ */
+public final class NewCaseWizardAction extends CallableSystemAction {
+
+    private WizardDescriptor.Panel[] panels;
+
+    @Override
+    public void performAction() {
+        Log.noteAction(this.getClass());
+
+
+        // there's a case open
+        if (Case.existsCurrentCase()) {
+            // show the confirmation first to close the current case and open the "New Case" wizard panel
+            String closeCurrentCase = "Do you want to save and close this case and proceed with the new case creation?";
+            NotifyDescriptor d = new NotifyDescriptor.Confirmation(closeCurrentCase, "Warning: Closing the Current Case", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+            d.setValue(NotifyDescriptor.NO_OPTION);
+
+            Object res = DialogDisplayer.getDefault().notify(d);
+            if (res != null && res == DialogDescriptor.YES_OPTION) {
+                try {
+                    Case.getCurrentCase().closeCase(); // close the current case
+                    newCaseAction(); // start the new case creation process
+                } catch (Exception ex) {
+                    Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex);
+                }
+            }
+        } else {
+            newCaseAction();
+        }
+    }
+
+    /**
+     * The method to perform new case creation
+     */
+    private void newCaseAction() {
+        WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
+        // {0} will be replaced by WizardDesriptor.Panel.getComponent().getName()
+        wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
+        wizardDescriptor.setTitle("New Case Information");
+        Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
+        dialog.setVisible(true);
+        dialog.toFront();
+
+
+        boolean finished = wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION; // check if it finishes (it's not cancelled)
+        boolean isCancelled = wizardDescriptor.getValue() == WizardDescriptor.CANCEL_OPTION; // check if the "Cancel" button is pressed
+
+        // if the finish button is pressed (not cancelled)
+        if (finished) {
+            // nothing to do, the Add Image dialog will pop up on its own because we've just opened a case with no images
+        }
+
+        // if Cancel button is pressed
+        if (isCancelled) {
+            // if there's case opened, close the case
+            if (Case.existsCurrentCase()) {
+                // close the previous case if there's any
+                CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class);
+                closeCase.actionPerformed(null);
+            }
+        }
+        panels = null; // reset the panel
+    }
+
+    /**
+     * Initialize panels representing individual wizard's steps and sets
+     * various properties for them influencing wizard appearance.
+     */
+    private WizardDescriptor.Panel[] getPanels() {
+        if (panels == null) {
+            panels = new WizardDescriptor.Panel[]{
+                        new NewCaseWizardPanel1()
+                    };
+            String[] steps = new String[panels.length];
+            for (int i = 0; i < panels.length; i++) {
+                Component c = panels[i].getComponent();
+                // Default step name to component name of panel. Mainly useful
+                // for getting the name of the target chooser to appear in the
+                // list of steps.
+                steps[i] = c.getName();
+                if (c instanceof JComponent) { // assume Swing components
+                    JComponent jc = (JComponent) c;
+                    // Sets step number of a component
+                    // TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
+                    jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
+                    // Sets steps names for a panel
+                    jc.putClientProperty("WizardPanel_contentData", steps);
+                    // Turn on subtitle creation on each step
+                    jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
+                    // Show steps on the left side with the image on the background
+                    jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
+                    // Turn on numbering of all steps
+                    jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
+                }
+            }
+        }
+        return panels;
+    }
+
+    @Override
+    public String getName() {
+        return "New Case Wizard";
+    }
+
+    @Override
+    public String iconResource() {
+        return null;
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java
new file mode 100644
index 0000000000000000000000000000000000000000..b28724dabe1acaf9a0287594af1a865c935c5c55
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/NewCaseWizardPanel1.java
@@ -0,0 +1,278 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.WizardDescriptor;
+import org.openide.WizardValidationException;
+import org.openide.util.HelpCtx;
+
+/**
+ * The "New Case" wizard panel with a component on it. This class represents 
+ * data of wizard step. It defers creation and initialization of UI component
+ * of wizard panel into getComponent() method.
+ *
+ * @author jantonius
+ */
+class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDescriptor> {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private NewCaseVisualPanel1 component;
+    private Boolean isFinish = false;
+
+    /**
+     * Get the visual component for the panel. In this template, the component
+     * is kept separate. This can be more efficient: if the wizard is created
+     * but never displayed, or not all panels are displayed, it is better to
+     * create only those which really need to be visible.
+     *
+     * @return component  the UI component of this wizard panel
+     */
+    @Override
+    public NewCaseVisualPanel1 getComponent() {
+        if (component == null) {
+            component = new NewCaseVisualPanel1(this);
+        }
+        return component;
+    }
+
+    /**
+     * Help for this panel. When the panel is active, this is used as the help
+     * for the wizard dialog.
+     * 
+     * @return HelpCtx.DEFAULT_HELP  the help for this panel
+     */
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx(SampleWizardPanel1.class);
+    }
+
+    /**
+     * Tests whether the panel is finished. If the panel is valid, the "Finish"
+     * button will be enabled.
+     *
+     * @return boolean  true if all the fields are correctly filled, false otherwise
+     */
+    @Override
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return isFinish;
+        // If it depends on some condition (form filled out...), then:
+        // return someCondition();
+        // and when this condition changes (last form field filled in...) then:
+        // fireChangeEvent();
+        // and uncomment the complicated stuff below.
+    }
+    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
+
+    /**
+     * Adds a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to add
+     */
+    @Override
+    public final void addChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.add(l);
+        }
+    }
+
+    /**
+     * Removes a listener to changes of the panel's validity.
+     *
+     * @param l  the change listener to move
+     */
+    @Override
+    public final void removeChangeListener(ChangeListener l) {
+        synchronized (listeners) {
+            listeners.remove(l);
+        }
+    }
+
+    /**
+     * This method is auto-generated. It seems that this method is used to listen
+     * to any change in this wizard panel.
+     */
+    protected final void fireChangeEvent() {
+        Iterator<ChangeListener> it;
+        synchronized (listeners) {
+            it = new HashSet<ChangeListener>(listeners).iterator();
+        }
+        ChangeEvent ev = new ChangeEvent(this);
+        while (it.hasNext()) {
+            it.next().stateChanged(ev);
+        }
+    }
+
+    /**
+     * Sets the isFinish variable in this class. isFinish variable is used to
+     * determine whether the Finish button should be disabled or not.
+     *
+     * @param isFinish  the given parameter (boolean)
+     */
+    public void setIsFinish(Boolean isFinish) {
+        this.isFinish = isFinish;
+        fireChangeEvent();
+    }
+
+    // You can use a settings object to keep track of state. Normally the
+    // settings object will be the WizardDescriptor, so you can use
+    // WizardDescriptor.getProperty & putProperty to store information entered
+    // by the user.
+    /**
+     * Provides the wizard panel with the current data--either the default data
+     * or already-modified settings, if the user used the previous and/or next
+     * buttons. This method can be called multiple times on one instance of
+     * WizardDescriptor.Panel.
+     * 
+     * @param settings  the setting to be read from
+     */
+    @Override
+    public void readSettings(WizardDescriptor settings) {
+    }
+
+    /**
+     * Provides the wizard panel with the opportunity to update the settings 
+     * with its current customized state. Rather than updating its settings
+     * with every change in the GUI, it should collect them, and then only save
+     * them when requested to by this method. This method can be called multiple
+     * times on one instance of WizardDescriptor.Panel.
+     *
+     * @param settings  the setting to be stored to
+     */
+    @Override
+    public void storeSettings(WizardDescriptor settings) {
+        settings.putProperty("caseName", getComponent().getCaseName());
+        settings.putProperty("caseParentDir", getComponent().getCaseParentDir());
+    }
+
+    @Override
+    public void validate() throws WizardValidationException {
+        String caseName = getComponent().getCaseName();
+        String caseParentDir = getComponent().getCaseParentDir();
+        String caseDirPath = caseParentDir + File.separator + caseName;
+
+        // check if case Name contain one of this following symbol:
+        //  \ / : * ? " < > |
+        if (!Case.isValidName(caseName)) {
+            String errorMsg = "The Case Name cannot contain any of this following symbol: \\ / : * ? \" < > |";
+            validationError(errorMsg);
+        } else {
+            // check if the directory exist
+            if (new File(caseDirPath).exists()) {
+                // throw a warning to enter new data or delete the existing directory
+                String errorMsg = "Case directory '" + caseDirPath + "' already exists.";
+                validationError(errorMsg);
+            } else {
+                // check if the "base" directory path is absolute
+                File baseDir = new File(caseParentDir);
+                if (baseDir.isAbsolute()) {
+                    // when the base directory doesn't exist
+                    if (!baseDir.exists()) {
+                        // get confirmation to create directory
+                        String confMsg = "The base directory \'" + caseParentDir + "\' doesn't exist. \n \n Do you want to make that directory?";
+                        NotifyDescriptor d2 = new NotifyDescriptor.Confirmation(confMsg, "Create directory", NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
+                        d2.setValue(NotifyDescriptor.NO_OPTION);
+
+                        Object res2 = DialogDisplayer.getDefault().notify(d2);
+                        if (res2 != null && res2 == DialogDescriptor.YES_OPTION) {
+                            // if user say yes
+                            try {
+                                createDirectory(caseDirPath, caseName);
+                            } catch (Exception ex) {
+                                String errorMsg = "Error: Couldn't create directory.";
+                                Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.WARNING, errorMsg, ex);
+                                validationError(errorMsg);
+                            }
+                        }
+                        if (res2 != null && res2 == DialogDescriptor.NO_OPTION) {
+                            // if user say no
+                            validationError("Prevented from creating base directory.");
+                        }
+                    } else {
+                        try {
+                            createDirectory(caseDirPath, caseName);
+                        } catch (Exception ex) {
+                            String errorMsg = "Error: Couldn't create directory.";
+                            Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.WARNING, errorMsg, ex);
+                            validationError(errorMsg);
+                        }
+                    }
+                } else {
+                    // throw a notification
+                    String errorMsg = "ERROR: The Base Directory that you entered is not valid.\nPlease enter a valid Base Directory.";
+                    validationError(errorMsg);
+                }
+            }
+        }
+    }
+
+
+    private void validationError(String errorMsg) throws WizardValidationException {
+        throw new WizardValidationException(this.getComponent(), errorMsg, null);
+    }
+
+        /*
+     * create the directory and create a new case
+     */
+    private void createDirectory(final String caseDirPath, final String caseName) throws Exception {
+        // try to create the directory with the case name in the choosen parent directory
+        boolean success = Case.createCaseDirectory(caseDirPath, caseName);
+
+        // check if the directory is successfully created
+        if (!success) {
+
+            // delete the folder if we already created the folder and the error shows up
+            if (new File(caseDirPath).exists()) {
+                Case.deleteCaseDirectory(new File(caseDirPath));
+            }
+
+            String errorMsg = "ERROR: Could not create the case directory. \nPlease enter a valid Case Name and Directory.";
+            validationError(errorMsg);
+        } // the new case directory is successfully created
+        else {
+            // try to close Startup window if there's one
+            try {
+                StartupWindow.getInstance().close();
+            } catch (Exception ex) {
+                Logger.getLogger(NewCaseWizardAction.class.getName()).log(Level.INFO, "Startup window didn't close as expected.", ex);
+
+            }
+
+            Case.create(caseDirPath, caseName); // create a new Case
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.form b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..217feeb9bf4c09622cb21cebc11c78e6f5651173
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.form
@@ -0,0 +1,99 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" attributes="0">
+                          <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="292" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="0">
+                          <Component id="imagesTableScrollPane" pref="470" max="32767" attributes="0"/>
+                          <EmptySpace max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="imagesTableScrollPane" min="-2" pref="170" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="OpenRecentCasePanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="cancelButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="OpenRecentCasePanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Container class="javax.swing.JScrollPane" name="imagesTableScrollPane">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTable" name="imagesTable">
+          <Properties>
+            <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
+              <Table columnCount="3" rowCount="0">
+                <Column editable="false" title="Case Name" type="java.lang.Object"/>
+                <Column editable="false" title="Path" type="java.lang.Object"/>
+                <Column editable="true" title="Open" type="java.lang.Object"/>
+              </Table>
+            </Property>
+            <Property name="showHorizontalLines" type="boolean" value="false"/>
+            <Property name="showVerticalLines" type="boolean" value="false"/>
+            <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
+              <TableHeader reorderingAllowed="false" resizingAllowed="true"/>
+            </Property>
+            <Property name="updateSelectionOnSort" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f0fc0903f748b90b541ce16cd5ae23784f44cc2
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/OpenRecentCasePanel.java
@@ -0,0 +1,213 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
+
+/**
+ * Panel show from the splash dialog that shows recent cases and allows them
+ * to be opened.
+ */
+class OpenRecentCasePanel extends javax.swing.JPanel {
+
+    static String[] caseName;
+    static String[] casePaths;
+    
+    OpenRecentCasePanel() {
+        initComponents();
+
+        caseName = RecentCases.getInstance().getRecentCaseNames();
+        casePaths = RecentCases.getInstance().getRecentCasePaths();
+        int totalRecentCases = RecentCases.getInstance().getTotalRecentCases();
+
+        // create the headers and add all the rows
+        String[] headers = {"Case Name", "Path", "Open"};
+        String[][] rows = new String[totalRecentCases][];
+        final int lastColumn = headers.length - 1;
+
+        for(int i = 0; i < totalRecentCases; i++){
+            String path = casePaths[i];
+            String shortenPath = path;
+            if(path.length() > 50){
+                shortenPath = shortenPath.substring(0, 10 + shortenPath.substring(10).indexOf(File.separator) + 1) + "..." +
+                        shortenPath.substring((shortenPath.length() - 20) + shortenPath.substring(shortenPath.length() - 20).indexOf(File.separator));
+            }
+            String[] thisRow = {caseName[i], shortenPath, path};
+            rows[i] = thisRow;
+            //model.insertRow(i, row);
+        }
+
+        // create the table inside with the imgPaths information
+        DefaultTableModel model = new DefaultTableModel(rows, headers)
+        {
+            @Override
+            // make the cells in the FileContentTable "read only"
+            public boolean isCellEditable(int row, int column){
+                return column == lastColumn; // make the last column (Remove button), only the editable
+            }
+        };
+        imagesTable.setModel(model);
+
+        // set the size of the remove column
+        TableColumn removeCol = imagesTable.getColumnModel().getColumn(lastColumn);
+        removeCol.setPreferredWidth(75);
+        removeCol.setMaxWidth(75);
+        removeCol.setMinWidth(75);
+        removeCol.setResizable(false);
+
+        // create the delete action to remove the image from the current case
+        Action open = new AbstractAction()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                // get the image path
+                JTable table = (JTable)e.getSource();
+                int modelRow = Integer.valueOf(e.getActionCommand());
+                String removeColumn = table.getValueAt(modelRow, lastColumn).toString();
+
+                // try to close Startup and openRecentCase window if they exist
+                try{
+                    StartupWindow.getInstance().close();
+                    CueBannerPanel.closeOpenRecentCasesWindow();
+                }
+                catch(Exception ex){
+                    // no need to show the error message to the user.
+                    //TODO: But maybe put the error message in the log in the future.
+                }
+
+                // Open the recent cases
+                try {
+                    Case.open(removeColumn); // open the case
+                } catch (Exception ex) {
+                    Logger.getLogger(OpenRecentCasePanel.class.getName()).log(Level.WARNING, "Error: couldn't open case.", ex);
+                }
+            }
+        };
+
+        ButtonColumn buttonColumn = new ButtonColumn(imagesTable, open, lastColumn, "Open");
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jLabel1 = new javax.swing.JLabel();
+        cancelButton = new javax.swing.JButton();
+        imagesTableScrollPane = new javax.swing.JScrollPane();
+        imagesTable = new javax.swing.JTable();
+
+        jLabel1.setText(org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.jLabel1.text")); // NOI18N
+
+        cancelButton.setText(org.openide.util.NbBundle.getMessage(OpenRecentCasePanel.class, "OpenRecentCasePanel.cancelButton.text")); // NOI18N
+        cancelButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonActionPerformed(evt);
+            }
+        });
+
+        imagesTable.setModel(new javax.swing.table.DefaultTableModel(
+            new Object [][] {
+
+            },
+            new String [] {
+                "Case Name", "Path", "Open"
+            }
+        ) {
+            boolean[] canEdit = new boolean [] {
+                false, false, true
+            };
+
+            public boolean isCellEditable(int rowIndex, int columnIndex) {
+                return canEdit [columnIndex];
+            }
+        });
+        imagesTable.setShowHorizontalLines(false);
+        imagesTable.setShowVerticalLines(false);
+        imagesTable.getTableHeader().setReorderingAllowed(false);
+        imagesTable.setUpdateSelectionOnSort(false);
+        imagesTableScrollPane.setViewportView(imagesTable);
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                        .addGroup(layout.createSequentialGroup()
+                            .addComponent(jLabel1)
+                            .addGap(292, 292, 292))
+                        .addGroup(layout.createSequentialGroup()
+                            .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 470, Short.MAX_VALUE)
+                            .addContainerGap()))
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addComponent(cancelButton)
+                        .addContainerGap())))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jLabel1)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(imagesTableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(cancelButton)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
+        // TODO add your handling code here:
+    }//GEN-LAST:event_cancelButtonActionPerformed
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton cancelButton;
+    private javax.swing.JTable imagesTable;
+    private javax.swing.JScrollPane imagesTableScrollPane;
+    private javax.swing.JLabel jLabel1;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Sets the Close button action listener.
+     *
+     * @param e  the action listener
+     */
+    public void setCloseButtonActionListener(ActionListener e){
+        this.cancelButton.addActionListener(e);
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/RecentCases.java b/Case/src/org/sleuthkit/autopsy/casemodule/RecentCases.java
new file mode 100644
index 0000000000000000000000000000000000000000..f91a9e8f96946393d68d2e44bbe7da3b4c7743db
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/RecentCases.java
@@ -0,0 +1,442 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JMenuItem;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+import org.sleuthkit.autopsy.logging.Log;
+import org.openide.filesystems.FileUtil;
+
+/**
+ * The action in this class is to clear the list of "Recent Cases".
+ * The constructor is called when the autopsy is running.
+ * All the method to create and modify the properties file are within this class
+ */
+public final class RecentCases extends CallableSystemAction implements Presenter.Menu {
+
+    static final int LENGTH = 5;
+    static final String NAME_PROP_KEY = "LBL_RecentCase_Name";
+    static final String PATH_PROP_KEY = "LBL_RecentCase_Path";
+    static final RecentCase BLANK_RECENTCASE = new RecentCase("", "");
+    // get the path of the case.properties file in the user directory
+    private final static String propFilePath = System.getProperty("netbeans.user") + File.separator + "autopsy.properties";
+
+    private final static RecentCases INSTANCE = new RecentCases();
+
+    private Properties properties;
+    private Deque<RecentCase> recentCases; // newest case is last case
+
+
+    /**
+     * Gets the instance of the RecentCases singleton.
+     *
+     * 
+     * @return INSTANCE  the RecentCases singleton
+     */
+    static public RecentCases getInstance() {
+        return INSTANCE;
+    }
+
+    static private Properties makeDefaults() {
+        Properties temp = new Properties();
+        for (int i = 0; i < LENGTH; i++) {
+            temp.setProperty(nameKey(i), "");
+            temp.setProperty(pathKey(i), "");
+        }
+
+        return temp;
+    }
+
+    /** the constructor */
+    private RecentCases() {
+        properties = new Properties(makeDefaults());
+        try {
+            // try to load all the recent cases from the properties file in the home directory
+            InputStream inputStream = new FileInputStream(propFilePath);
+            properties.load(inputStream);
+        } catch (Exception ignore) {
+            // if cannot load it, we create a new properties file without any data inside it
+            try {
+                // create the directory and property file to store it
+                File output = new File(propFilePath);
+                if (!output.exists()) {
+                    File parent = new File(output.getParent());
+                    if (!parent.exists()) {
+                        parent.mkdirs();
+                    }
+                    output.createNewFile();
+                    FileOutputStream fos = new FileOutputStream(output);
+                    properties.store(fos, "");
+                } else {
+                    // if the property file already exist, throw an error that says cannot load that file
+                    Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not load the property file.", new Exception("The properties file already exist and can't load that file."));
+                }
+            } catch (IOException ex2) {
+                Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not create the property file.", ex2);
+            }
+        }
+
+
+        // Load recentCases from properties
+        recentCases = new LinkedList<RecentCase>();
+
+        for (int i = 0; i < LENGTH; i++) {
+            final RecentCase rc = new RecentCase(getName(i), getPath(i));
+            if (!rc.equals(BLANK_RECENTCASE)) {
+                recentCases.add(rc);
+            }
+        }
+    }
+
+    private static void validateCaseIndex(int i) {
+        if (i < 0 || i >= LENGTH) {
+            throw new IllegalArgumentException("Recent case index " + i + " is out of range.");
+        }
+    }
+
+    private static String nameKey(int i) {
+        validateCaseIndex(i);
+        return NAME_PROP_KEY + Integer.toString(i + 1);
+    }
+
+    private static String pathKey(int i) {
+        validateCaseIndex(i);
+        return PATH_PROP_KEY + Integer.toString(i + 1);
+    }
+
+    private String getName(int i) {
+        return properties.getProperty(nameKey(i));
+    }
+
+    private String getPath(int i) {
+        return properties.getProperty(pathKey(i));
+    }
+
+    private void setName(int i, String name) {
+        properties.setProperty(nameKey(i), name);
+    }
+
+    private void setPath(int i, String path) {
+        properties.setProperty(pathKey(i), path);
+    }
+
+    private void setRecentCase(int i, RecentCase rc) {
+        setName(i, rc.name);
+        setPath(i, rc.path);
+    }
+
+    private static final class RecentCase {
+
+        String name, path;
+        
+        /**
+         * @param name The case name or "" if a blank placeholder case
+         * @param path A normalized path (via FileUtil.normalizePath(path)) or "" if a blank placeholder case
+         */
+        private RecentCase(String name, String path) {
+            this.name = name;
+            this.path = path;
+        }
+        
+        /**
+         * Used when creating RecentCases with external data. The path must be 
+         * normalized so that duplicate cases always have the same path.
+         * @param name The case name.
+         * @param unsafePath The (potentially un-normalized) case path.
+         * @return The created RecentCase.s
+         */
+        static RecentCase createSafe(String name, String unsafePath) {
+            return new RecentCase(name, FileUtil.normalizePath(unsafePath));
+        }
+
+        // netbeans autogenerated hashCode
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 13 * hash + (this.name != null ? this.name.hashCode() : 0);
+            hash = 13 * hash + (this.path != null ? this.path.hashCode() : 0);
+            return hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final RecentCase other = (RecentCase) obj;
+            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+                return false;
+            }
+            if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path)) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private void storeProperties() throws IOException {
+        properties.store(new FileOutputStream(new File(propFilePath)), "");
+    }
+
+    private void storeRecentCases() throws IOException {
+        int i = 0;
+
+        // store however many recent cases exist
+        for (RecentCase rc : recentCases) {
+            setRecentCase(i, rc);
+            i++;
+        }
+
+        // set the rest to blanks
+        while (i < LENGTH) {
+            setRecentCase(i, BLANK_RECENTCASE);
+            i++;
+        }
+
+        storeProperties();
+    }
+
+    /**
+     * Gets a menu item that can present this action in a JMenu.
+     *
+     * @return menuItem  the representation menu item for this action
+     */
+    @Override
+    public JMenuItem getMenuPresenter() {
+        return new UpdateRecentCases();
+    }
+
+    /**
+     * This action is used to clear all the recent cases menu options.
+     *
+     * @param e  the action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        UpdateRecentCases.hasRecentCase = false;
+
+        recentCases.clear();
+
+        try {
+            // clear the properties file
+            storeRecentCases();
+        } catch (Exception ex) {
+            Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not clear the properties file.", ex);
+        }
+    }
+
+    private void addRecentCase(RecentCase rc) {
+        // remove the case if it's already in the list
+        recentCases.remove(rc);
+                
+        // make space if it's needed
+        if (recentCases.size() == LENGTH) recentCases.remove();
+
+        recentCases.add(rc);
+    }
+
+    /**
+     * Adds a recent case to the top of the list. If the case is already in the
+     * list, it will be removed before the new entry is added. 
+     *
+     * @param name  the name of the recent case to be added
+     * @param unsafePath  the (potentially un-normalized) path of the case
+     * config file
+     */
+    public void addRecentCase(String name, String unsafePath) {
+        RecentCase rc = RecentCase.createSafe(name, unsafePath);
+
+        addRecentCase(rc);
+
+        this.getMenuPresenter().setVisible(true); // invoke the contructor again
+
+        try {
+            storeRecentCases();
+        } catch (Exception ex) {
+            Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex);
+        }
+    }
+
+    /**
+     * This method is used to update the name and path of a RecentCase.
+     *
+     * @param oldName  the old recent case name
+     * @param oldPath  the old recent case config file path
+     * @param newName  the new recent case name
+     * @param newPath  the new recent case config file path
+     * @throws Exception
+     */
+    public void updateRecentCase(String oldName, String oldPath, String newName, String newPath) throws Exception {
+        RecentCase oldRc = RecentCase.createSafe(oldName, oldPath);
+        RecentCase newRc = RecentCase.createSafe(newName, newPath);
+
+        // remove all instances of the old recent case
+        recentCases.removeAll(Arrays.asList(oldRc));
+
+        addRecentCase(newRc);
+
+        this.getMenuPresenter().setVisible(true); // invoke the contructor again
+
+        try {
+            storeRecentCases();
+        } catch (Exception ex) {
+            Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex);
+        }
+    }
+
+    /**
+     * Gets the total number of recent cases
+     *
+     * @return total  total number of recent cases
+     */
+    public int getTotalRecentCases() {
+        return recentCases.size();
+    }
+
+    /**
+     * This method is used to remove the selected name and path of the RecentCase
+     *
+     * @param name  the case name to be removed from the recent case
+     * @param path  the config file path to be removed from the recent case
+     */
+    public void removeRecentCase(String name, String path) {
+        RecentCase rc = RecentCase.createSafe(name, path);
+
+        // remove all instances of the old recent case
+        recentCases.removeAll(Arrays.asList(rc));
+
+
+        this.getMenuPresenter().setVisible(true); // invoke the contructor again
+
+        // write the properties file
+        try {
+            storeRecentCases();
+        } catch (Exception ex) {
+            Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, "Error: Could not update the properties file.", ex);
+        }
+    }
+
+    /**
+     * Gets the recent case names.
+     *
+     * @return caseNames An array String[LENGTH], newest case first, with any
+     * extra spots filled with ""
+     */
+    public String[] getRecentCaseNames() {
+        String[] caseNames = new String[LENGTH];
+
+        Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
+        int i = 0;
+        while (mostRecentFirst.hasNext()) {
+            caseNames[i] = mostRecentFirst.next().name;
+            i++;
+        }
+
+        while (i < caseNames.length) {
+            caseNames[i] = "";
+            i++;
+        }
+
+        return caseNames;
+    }
+
+    /**
+     * Gets the recent case paths.
+     *
+     * @return casePaths An array String[LENGTH], newest case first, with any
+     * extra spots filled with ""
+     */
+    public String[] getRecentCasePaths() {
+        String[] casePaths = new String[LENGTH];
+
+        Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
+        int i = 0;
+        while (mostRecentFirst.hasNext()) {
+            casePaths[i] = mostRecentFirst.next().path;
+            i++;
+        }
+
+        while (i < casePaths.length) {
+            casePaths[i] = "";
+            i++;
+        }
+
+        return casePaths;
+    }
+
+
+    // TODO: really shouldn't be done like this; need one common properties tracker
+    /**
+     * Gets the properties file paths.
+     *
+     * @return propertyPath
+     */
+    public static String getPropertiesFilePath() {
+        return propFilePath;
+    }
+
+    /**
+     * This method does nothing. Use the actionPerformed instead of this method.
+     */
+    @Override
+    public void performAction() {
+    }
+
+    /**
+     * Gets the name of this action. This may be presented as an item in a menu.
+     *
+     * @return actionName
+     */
+    @Override
+    public String getName() {
+        //return NbBundle.getMessage(RecentCases.class, "CTL_RecentCases");
+        return "Clear Recent Cases";
+    }
+
+    /**
+     * Gets the HelpCtx associated with implementing object
+     *
+     * @return HelpCtx or HelpCtx.DEFAULT_HELP
+     */
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/RecentItems.java b/Case/src/org/sleuthkit/autopsy/casemodule/RecentItems.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b944350dc63d97a98a6ed8c6c8f3950f0608d4f
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/RecentItems.java
@@ -0,0 +1,70 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * This class is used to add the action to the recent case menu item. When the
+ * the recent case menu is pressed, it should open that selected case.
+ */
+class RecentItems implements ActionListener {
+
+    String caseName;
+    String casePath;
+    private JPanel caller; // for error handling
+
+    /** the constructor */
+    public RecentItems(String caseName, String casePath){
+        this.caseName = caseName;
+        this.casePath = casePath;
+    }
+
+    /**
+     * Opens the recent case.
+     *
+     * @param e  the action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+        
+        // check if the file exists
+        if(caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())){
+            // throw an error here
+            JOptionPane.showMessageDialog(caller, "Error: Case doesn't exist.", "Error", JOptionPane.ERROR_MESSAGE);
+            RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
+        }
+        else {
+            try {
+                Case.open(casePath); // open the case
+            } catch (Exception ex) {
+                Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error: Couldn't open recent case.", ex);
+            }
+        }
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java b/Case/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java
new file mode 100644
index 0000000000000000000000000000000000000000..86f29c703bf1369b75a3a7d2f48dda5f9edf84f2
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java
@@ -0,0 +1,97 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+
+/**
+ * Displays 
+ */
+public final class StartupWindow extends JDialog {
+
+    private static StartupWindow instance;
+    private static final String TITLE = "Welcome";
+    private static Dimension DIMENSIONS = new Dimension(750, 400);
+
+    private StartupWindow(JFrame frame, String title, boolean isModal) {
+        super(frame, title, isModal);
+    }
+
+    /**
+     * Get the startup window
+     * @return the startup window singleton
+     */
+    public static synchronized StartupWindow getInstance() {
+        if (StartupWindow.instance == null) {
+            JFrame frame = new JFrame(TITLE);
+            boolean isModal = true;
+            StartupWindow.instance = new StartupWindow(frame, TITLE, isModal);
+        }
+
+
+        return instance;
+    }
+
+    /**
+     * Shows the startup window.
+     */
+    public void display() {
+
+        Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+
+        // set the popUp window / JFrame
+        setSize(DIMENSIONS);
+        int w = this.getSize().width;
+        int h = this.getSize().height;
+
+        // set the location of the popUp Window on the center of the screen
+        setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
+
+        CueBannerPanel welcomeWindow = new CueBannerPanel();
+
+        // add the command to close the window to the button on the Volume Detail Panel
+        welcomeWindow.setCloseButtonActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                close();
+            }
+        });
+
+        add(welcomeWindow);
+        pack();
+        setResizable(false);
+        setVisible(true);
+
+    }
+
+    /**
+     * Closes the startup window.
+     */
+    public void close() {
+        this.dispose();
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java b/Case/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e219fd5c0cafb56d74a3313db36f4d3fc2516db
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/UpdateRecentCases.java
@@ -0,0 +1,94 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.JSeparator;
+import org.openide.awt.DynamicMenuContent;
+import org.openide.util.actions.SystemAction;
+
+/**
+ * This class is used to change / update the list of recent cases dynamically.
+ */
+public class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
+
+    int length;
+    static boolean hasRecentCase = false;
+
+    /** the constructor */
+    UpdateRecentCases(){
+        length = RecentCases.LENGTH;
+    }
+
+    /**
+     * Creates main menu/popup menu items. Null values will be later replaced by
+     * JSeparators. This method is called for popups and for menus. It's called
+     * each time a popup menu is constructed and just once for the main menu.
+     * Main menu updates happen through the synchMenuPresenters() method.
+     *
+     * @return
+     */
+    @Override
+    public JComponent[] getMenuPresenters() {
+        String[] caseName = RecentCases.getInstance().getRecentCaseNames();
+        String[] casePath = RecentCases.getInstance().getRecentCasePaths();
+        JComponent[] comps = new JComponent[length + 2]; // + 2 for separator and clear menu
+
+        // if it has the recent menus, add them to the component list
+        for (int i = 0; i < length; i++) {
+            if((!caseName[i].equals(""))){
+                JMenuItem menuItem = new JMenuItem(caseName[i]);
+                menuItem.setActionCommand(caseName[i].toUpperCase());
+                menuItem.addActionListener(new RecentItems(caseName[i], casePath[i]));
+                comps[i] = menuItem;
+                hasRecentCase = hasRecentCase || true;
+            }
+        }
+
+        // if it has recent case, create clear menu
+        if(hasRecentCase){
+            comps[length] = new JSeparator();
+            JMenuItem clearMenu = new JMenuItem("Clear Recent Cases");
+            clearMenu.addActionListener(SystemAction.get(RecentCases.class));
+            comps[length+1] = clearMenu;
+        }
+        // otherwise, just create a disabled empty menu
+        else{
+            comps = new JComponent[1];
+            JMenuItem emptyMenu = new JMenuItem("-Empty-");
+            emptyMenu.addActionListener(new RecentItems("", ""));
+            comps[0] = emptyMenu;
+            comps[0].setEnabled(false);
+        }
+        return comps;
+    }
+
+    /**
+     * Updates main menu presenters. This method is called only by the main menu processing.
+     *
+     * @param jcs    the previously used menu items returned by previous call to getMenuPresenters() or synchMenuPresenters()
+     * @return menu  a new set of items to show in menu. Can be either an updated old set of instances or a completely new one.
+     */
+    @Override
+    public JComponent[] synchMenuPresenters(JComponent[] jcs) {
+        return getMenuPresenters();
+    }
+}
\ No newline at end of file
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java b/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b8e85a215275a71cb742c2302a8854b3ec63cac
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/XMLCaseManagement.java
@@ -0,0 +1,802 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.io.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.TimeZone;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+import org.w3c.dom.*;
+
+/**
+ *
+ * This class is used to create, access, and modify the XML configuration file,
+ * where we store the information about the case and image(s). This class uses
+ * the document handler to store the information about the case. The document
+ * handler will be created / opened when the case configuration file is created/
+ * opened.
+ *
+ * @author jantonius
+ */
+public class XMLCaseManagement implements CaseConfigFileInterface{
+    final static String TOP_ROOT_NAME = "AutopsyCase";
+    final static String CASE_ROOT_NAME = "Case";
+
+    // general metadata about the case file
+    final static String NAME = "Name";
+    final static String CREATED_DATE_NAME = "CreatedDate";
+    final static String MODIFIED_DATE_NAME = "ModifiedDate";
+    final static String SCHEMA_VERSION_NAME = "SchemaVersion";
+    final static String AUTOPSY_CRVERSION_NAME = "AutopsyCreatedVersion";
+    final static String AUTOPSY_MVERSION_NAME = "AutopsySavedVersion";
+
+    // disk image paths
+    final static String IMAGES_NAME = "Images";
+    final static String IMG_SET_NAME = "ImgSet";
+    final static String IMG_PATH_NAME = "ImgPath";
+    final static String IMG_DB_NAME = "ImgDb";
+    final static String NEXT_ID_NAME = "NextID";
+
+    // image attribute
+    final static String IMG_SET_COUNT = "count";
+    final static String IMG_SET_ID = "id";
+    final static String IMG_PATH_ID = "idx";
+    final static String TIMEZONE = "timezone";
+
+    // folders inside case directory
+    final static String LOG_FOLDER_NAME = "LogFolder";
+    final static String LOG_FOLDER_RELPATH = "Log";
+    final static String TEMP_FOLDER_NAME = "TempFolder";
+    final static String TEMP_FOLDER_RELPATH = "Temp";
+    final static String EXPORT_FOLDER_NAME = "ExportFolder";
+    final static String EXPORT_FOLDER_RELPATH = "Export";
+
+    // folders attribute
+    final static String RELATIVE_NAME = "Relative";	// relevant path info
+
+    // folder attr values
+    final static String RELATIVE_TRUE = "true";     // if it's a relative path
+    final static String RELATIVE_FALSE = "false";   // if it's not a relative path
+
+    // the document
+    private Document doc;
+
+    // general info
+    private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
+    private String caseDirPath;     // case directory path
+    private String caseName;        // case name
+    private String schemaVersion = "1.0";
+    private String autopsySavedVersion;
+    
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** The constructor */
+    XMLCaseManagement() throws Exception {
+        String autopsyVer = Case.getAutopsyVersion();
+//        System.setProperty("netbeans.buildnumber", autopsyVer); // set the current autopsy version // moved to CoreComponents installer
+        autopsySavedVersion = System.getProperty("netbeans.buildnumber");
+    }
+
+    /**
+     * Sets the case directory path of the case directory on the local variable
+     *
+     * @param givenPath  the new path to be stored as case directory path
+     */
+    private void setCaseDirPath(String givenPath){
+        caseDirPath = givenPath; // change this to change the xml file if needed
+    }
+
+    /**
+     * Sets the case Name on the XML configuration file
+     *
+     * @param givenCaseName  the new case name to be set
+     */
+    @Override
+    public void setCaseName(String givenCaseName) throws Exception {
+        // change this to change the xml file if needed
+        Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
+        nameElement.setTextContent(givenCaseName);
+        doc.normalize();
+
+        // edit the modified data
+        String newDate = dateFormat.format(new Date());
+        Element rootEl = getRootElement();
+        rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
+
+        try {
+            writeFile();
+        } catch (Exception ex) {
+            throw new Exception("Cannot update the case name in the XML config file.", ex);
+        }
+    }
+    
+    /**
+     * Sets the case name internally (on local variable in this class)
+     * 
+     * @param givenCaseName  the new case name
+     */
+    private void setName(String givenCaseName){
+        caseName = givenCaseName; // change this to change the xml file if needed
+    }
+    
+    /**
+     * Gets the case Name from the document handler
+     *
+     * @return caseName  the case name from the document handler
+     */
+    @Override
+    public String getCaseName(){
+        if(doc == null){
+            return "";
+        }
+        else{
+            Element nameElement = (Element) getCaseElement().getElementsByTagName(NAME).item(0);
+            String result = nameElement.getTextContent();
+            return result;
+        }
+    }
+
+    /**
+     * Gets the case directory path that's stored in this class
+     *
+     * @return caseDirPath  the case directory path
+     */
+    public String getCaseDirectory(){
+        if(doc == null){
+            return "";
+        }
+        else{
+            return caseDirPath;
+        }
+        // Note: change this to get the case name from the xml file if needed
+    }
+
+    /**
+     * Gets the Root Element from the document handler
+     *
+     * @return rootElement  the root element on the document handler
+     */
+    private Element getRootElement(){
+        if(doc != null){
+            return doc.getDocumentElement();
+        }
+        else{
+            return null; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the created Date from the document handler
+     *
+     * @return createdDate  the creation date of this case
+     */
+    protected String getCreatedDate(){
+        if(doc != null){
+            Element crDateElement = (Element) getRootElement().getElementsByTagName(CREATED_DATE_NAME).item(0);
+            return crDateElement.getTextContent();
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the Modified Date from the document handler
+     *
+     * @return modifiedDate  the modification date of this case
+     */
+    protected String getModifiedDate(){
+        if(doc != null){
+            Element mDateElement = (Element) getRootElement().getElementsByTagName(MODIFIED_DATE_NAME).item(0);
+            return mDateElement.getTextContent();
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the Autopsy Created Version from the document handler
+     *
+     * @return createdVersion  the version of autopsy when this case was created
+     */
+    protected String getCreatedVersion(){
+        if(doc != null){
+            Element crVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_CRVERSION_NAME).item(0);
+            return crVerElement.getTextContent();
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the Autopsy Saved Version from the document handler
+     *
+     * @return savedVersion  the latest version of autopsy when this case is saved
+     */
+    protected String getSavedVersion(){
+        if(doc != null){
+            Element mVerElement = (Element) getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0);
+            return mVerElement.getTextContent();
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the Schema Version from the document handler
+     *
+     * @return schemaVersion  the schema version of this XML configuration file
+     */
+    protected String getSchemaVersion(){
+        if(doc != null){
+            Element schemaVerElement = (Element) getRootElement().getElementsByTagName(SCHEMA_VERSION_NAME).item(0);
+            return schemaVerElement.getTextContent();
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the Case Element from the document handler
+     *
+     * @return caseElement  the "Case" element
+     */
+    private Element getCaseElement(){
+        if(doc != null){
+            return (Element) doc.getElementsByTagName(CASE_ROOT_NAME).item(0);
+        }
+        else{
+            return null; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the full path to the log directory
+     *
+     * @return logDir  the full path of the "Log" directory
+     */
+    protected String getLogDir(){
+        if(doc != null){
+            Element logElement = (Element)getCaseElement().getElementsByTagName(LOG_FOLDER_NAME).item(0);
+            if(logElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)){
+                return caseDirPath + File.separator + logElement.getTextContent();
+            }
+            else{
+                return logElement.getTextContent();
+            }
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the full path to the temp directory
+     *
+     * @return tempDir  the full path of the "Temp" directory
+     */
+    protected String getTempDir(){
+        if(doc != null){
+            Element tempElement = (Element)getCaseElement().getElementsByTagName(TEMP_FOLDER_NAME).item(0);
+            if(tempElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)){
+                return caseDirPath + File.separator + tempElement.getTextContent();
+            }
+            else{
+                return tempElement.getTextContent();
+            }
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets the full path to the Export directory
+     *
+     * @return exportDir  the full path of the "Export" directory
+     */
+    protected String getExportDir(){
+        if(doc != null){
+            Element exportElement = (Element)getCaseElement().getElementsByTagName(EXPORT_FOLDER_NAME).item(0);
+            if(exportElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)){
+                return caseDirPath + File.separator + exportElement.getTextContent();
+            }
+            else{
+                return exportElement.getTextContent();
+            }
+        }
+        else{
+            return ""; // should throw error or exception
+        }
+    }
+
+    /**
+     * Gets image Element from the document handler
+     *
+     * @return imageElement  the "Image" element
+     */
+    private Element getImagesElement(){
+        if(doc != null){
+            return (Element) doc.getElementsByTagName(IMAGES_NAME).item(0);
+        }
+        else{
+            return null; // should throw error or exception
+        }
+    }
+
+    /**
+     * Looks up for the Image Set Element in the document handler with the given
+     * image ID.
+     *
+     * @param id        the image ID
+     * @return element  the "ImageSet" element
+     */
+    protected Element getImageSetElement(int id){
+        if(doc != null){
+            Element result = null;
+            int totalImageSet = getImageSetCount();
+            
+            for(int i = 0; i < totalImageSet; i++){
+                Element imageSetElement = (Element)getImagesElement().getElementsByTagName(IMG_SET_NAME).item(i);
+                int imgSetID = Integer.parseInt(imageSetElement.getAttribute(IMG_SET_ID));
+                if(id == imgSetID){
+                    result = imageSetElement;
+                }
+            }
+            return result;
+        }
+        else{
+            return null; //TODO: should throw error or exception
+        }
+    }
+
+    /**
+     * Sets the ImgDb entry for corresponding image set in the document handler
+     *
+     * @param id    the image ID
+     * @param path  the image path
+     */
+    protected void setImageSetDbPath(int id, String path){
+        Element imgDbElement = (Element) getImageSetElement(id).getElementsByTagName(IMG_DB_NAME).item(0);
+        imgDbElement.setTextContent(path);
+        imgDbElement.setAttribute(RELATIVE_NAME, RELATIVE_TRUE); // depends on the path (relative or not)
+        
+        // if need to write the XML file immidiately, uncomment the code below
+        // writeFile();
+    }
+
+    /**
+     * Returns number of image sets in this case
+     *
+     * @return imageSetCount  total number of imageSet in this case
+     */
+    protected int getImageSetCount(){
+        return getImagesElement().getElementsByTagName(IMG_SET_NAME).getLength();
+    }
+
+    /**
+     * Returns a set of image paths of the given image ID in this case
+     *
+     * @param id           the image ID
+     * @return imagePaths  the image paths of the given imageID
+     */
+    protected String[] getImageSet(int id){
+        Element imgSetElement = getImageSetElement(id);
+        int totalImagePaths = imgSetElement.getElementsByTagName(IMG_PATH_NAME).getLength(); // or use the attribute count
+        String[] result = new String[totalImagePaths];
+
+        for(int i = 0; i < totalImagePaths; i++){
+            Element imgPathElement = (Element) imgSetElement.getElementsByTagName(IMG_PATH_NAME).item(i);
+            if(imgPathElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)){
+                result[i] = caseDirPath + File.separator + imgPathElement.getTextContent();
+            }
+            else{
+                result[i] = imgPathElement.getTextContent();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns absolute path of image database of the given image ID.
+     *
+     * @param id       the image ID
+     * @return dbPath  the database path of the given image
+     */
+    protected String getImageSetDbPath(int id){
+        Element imgDbElement = (Element) getImageSetElement(id).getElementsByTagName(IMG_DB_NAME).item(0);
+        if(imgDbElement.getAttribute(RELATIVE_NAME).equals(RELATIVE_TRUE)){
+            return caseDirPath + File.separator + imgDbElement.getTextContent();
+        }
+        else{
+            return imgDbElement.getTextContent();
+        }
+    }
+
+    /**
+     * Gets the next free image ID and and increments the internal counter
+     *
+     * @return imageID  the next free image ID
+     */
+    @Override
+    public int getNextImageID(){
+        Element imgElement = getImagesElement();
+        if(imgElement == null){
+            return -1; // which indicates the error
+        }
+        else{
+            String nextID = imgElement.getAttribute(NEXT_ID_NAME);
+            int result = Integer.parseInt(nextID);
+
+            // increment the nextID
+            int incNextID = result + 1;
+            getImagesElement().setAttribute(NEXT_ID_NAME, Integer.toString(incNextID));
+
+            // write the change to the config file immediately
+            try{ 
+                writeFile();
+            }
+            catch(Exception ex){
+                // TODO: throw exception further up
+                Logger logger = Logger.getLogger(this.className);
+                logger.log(Level.WARNING, "Error while trying to write the new NextID to the config file.", ex);
+            }
+            
+            return result;
+        }
+    }
+
+    /**
+     * Returns an array of all image ID values in this case.
+     *
+     * @return imageIDs  array of all image IDs in this case
+     */
+    @Override
+    public int[] getImageIDs() {
+        int totalImageSet = getImageSetCount();
+        int[] result = new int[totalImageSet];
+
+        Element imgElement = getImagesElement();
+        for(int i = 0; i < totalImageSet; i++){
+            Element imgSetElement = (Element)imgElement.getElementsByTagName(IMG_SET_NAME).item(i);
+            result[i] = Integer.parseInt(imgSetElement.getAttribute(IMG_SET_ID));
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the HashSet of all timezone values of all images in this case.
+     *
+     * @return imageIDs  the HashSet of all timezone values
+     */
+    public HashSet<TimeZone> getTimeZone() {
+        HashSet<TimeZone> result = new HashSet<TimeZone>();
+
+        int totalImageSet = getImageSetCount();
+        Element imgElement = getImagesElement();
+        for(int i = 0; i < totalImageSet; i++){
+            Element imgSetElement = (Element)imgElement.getElementsByTagName(IMG_SET_NAME).item(i);
+            result.add(TimeZone.getTimeZone(imgSetElement.getAttribute(TIMEZONE)));
+        }
+
+        return result;
+    }
+
+    /**
+     * Removes the imageSet of the given image ID.
+     *
+     * @param imgID  the image ID of the image that going to be removed
+     */
+    public void removeImageSet(int imgID) {
+            Element imgElement = getImagesElement();
+            Element selectedElement = getImageSetElement(imgID);
+            imgElement.removeChild(selectedElement); // remove the imagesetElement
+            doc.normalize();
+
+            // edit the modified data
+            String newDate = dateFormat.format(new Date());
+            Element rootEl = getRootElement();
+            rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
+    }
+
+    /**
+     * Initialize the basic values for a new case management file.
+     * Note: this is the schema version 1.0
+     *
+     * @param parentPath  the name of the parent of the case directory.
+     * @param caseName    the name of the config file to be located in the case directory
+     */
+    protected void create(String dirPath, String caseName) throws Exception {
+        clear(); // clear the previous data
+
+        // set the case Name and Directory and the parent directory
+        setCaseDirPath(dirPath);
+        setName(caseName);
+        DocumentBuilder docBuilder;
+        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+
+        // throw an error here
+        try {
+             docBuilder = docFactory.newDocumentBuilder();
+        } catch (Exception ex) {
+            clear();
+            throw ex;
+        }
+
+        doc = docBuilder.newDocument();
+        Element rootElement = doc.createElement(TOP_ROOT_NAME); // <AutopsyCase> ... </AutopsyCase>
+        doc.appendChild(rootElement);
+
+        Element crDateElement = doc.createElement(CREATED_DATE_NAME); // <CreatedDate> ... </CreatedDate>
+        crDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
+        rootElement.appendChild(crDateElement);
+
+        Element mDateElement = doc.createElement(MODIFIED_DATE_NAME); // <ModifedDate> ... </ModifedDate>
+        mDateElement.appendChild(doc.createTextNode(dateFormat.format(new Date())));
+        rootElement.appendChild(mDateElement);
+
+        Element autVerElement = doc.createElement(AUTOPSY_CRVERSION_NAME); // <AutopsyVersion> ... </AutopsyVersion>
+        autVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
+        rootElement.appendChild(autVerElement);
+
+        Element autSavedVerElement = doc.createElement(AUTOPSY_MVERSION_NAME); // <AutopsySavedVersion> ... </AutopsySavedVersion>
+        autSavedVerElement.appendChild(doc.createTextNode(autopsySavedVersion));
+        rootElement.appendChild(autSavedVerElement);
+
+        Element schVerElement = doc.createElement(SCHEMA_VERSION_NAME); // <SchemaVersion> ... </SchemaVersion>
+        schVerElement.appendChild(doc.createTextNode(schemaVersion));
+        rootElement.appendChild(schVerElement);
+
+        Element caseElement = doc.createElement(CASE_ROOT_NAME); // <Case> ... </Case>
+        rootElement.appendChild(caseElement);
+
+        Element nameElement = doc.createElement(NAME); // <Name> ... </Name>
+        nameElement.appendChild(doc.createTextNode(caseName));
+        caseElement.appendChild(nameElement);
+
+        Element exportElement = doc.createElement(EXPORT_FOLDER_NAME); // <ExportFolder> ... </ExportFolder>
+        exportElement.appendChild(doc.createTextNode(EXPORT_FOLDER_RELPATH));
+        exportElement.setAttribute(RELATIVE_NAME, "true");
+        caseElement.appendChild(exportElement);
+
+        Element logElement = doc.createElement(LOG_FOLDER_NAME); // <LogFolder> ... </LogFolder>
+        logElement.appendChild(doc.createTextNode(LOG_FOLDER_RELPATH));
+        logElement.setAttribute(RELATIVE_NAME, "true");
+        caseElement.appendChild(logElement);
+
+        Element tempElement = doc.createElement(TEMP_FOLDER_NAME); // <TempFolder> ... </TempFolder>
+        tempElement.appendChild(doc.createTextNode(TEMP_FOLDER_RELPATH));
+        tempElement.setAttribute(RELATIVE_NAME, "true");
+        caseElement.appendChild(tempElement);
+
+        // create the new images
+        Element imagesElement = doc.createElement(IMAGES_NAME); // <Images> ... </Images>
+        imagesElement.setAttribute(NEXT_ID_NAME, Integer.toString(0)); // add nextID to 0
+        rootElement.appendChild(imagesElement);
+
+        // write more code if needed ...
+    }
+
+    /**
+     * Writes the case management file to disk (from document handler to .aut file)
+     *
+     */
+    @Override
+    public void writeFile() throws Exception {
+        if (doc == null || caseName.equals("")) {
+            throw new Exception("No set case to write management file for.");
+        }
+
+        // Prepare the DOM document for writing
+        Source source = new DOMSource(doc);
+
+        // Prepare the data for the output file
+        StringWriter sw = new StringWriter();
+        Result result = new StreamResult(sw);
+
+        // Write the DOM document to the file
+        Transformer xformer;// = TransformerFactory.newInstance().newTransformer();
+        TransformerFactory tfactory = TransformerFactory.newInstance();
+
+        try {
+            xformer = tfactory.newTransformer();
+        } catch (Exception ex) {
+            throw ex;
+        }
+
+        //Setup indenting to "pretty print"
+        xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+
+        try {
+            xformer.transform(source, result);
+        } catch (TransformerException ex) {
+            throw ex;
+        }
+
+        // preparing the output file
+        String xmlString = sw.toString();
+        File file = new File(caseDirPath + File.separator + caseName + ".aut");
+
+        // write the file
+        try {
+            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
+            bw.write(xmlString);
+            bw.flush();
+            bw.close();
+        } catch (Exception ex) {
+            throw ex;
+        }
+    }
+
+    /**
+     * Opens the configuration file and load the document handler
+     * Note: this is for the schema version 1.0
+     *
+     * @param conFilePath  the path of the XML case configuration file path
+     */
+    @Override
+    public void open(String conFilePath) throws Exception{
+        clear();
+        File file = new File(conFilePath);
+        
+        try{
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            DocumentBuilder db = dbf.newDocumentBuilder();
+            doc = db.parse(file);
+            doc.getDocumentElement().normalize();
+
+            Element rootEl = doc.getDocumentElement();
+            String rootName = rootEl.getNodeName();
+
+            // check if it's the autopsy case, if not, throws an error
+            if(!rootName.equals(TOP_ROOT_NAME)){
+                // throw an error ...
+                clear();
+                JOptionPane.showMessageDialog(caller, "Error: This is not an Autopsy config file (\"" + file.getName() + "\").\n \nDetail: \nCannot open a non-Autopsy config file (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
+            }
+            else{
+                /* Autopsy Created Version */
+                String createdVersion = getCreatedVersion(); // get the created version
+
+                // check if it has the same autopsy version as the current one
+                if(!createdVersion.equals(autopsySavedVersion)){
+                    // if not the same version, update the saved version in the xml to the current version
+                    getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0).setTextContent(autopsySavedVersion);
+                }
+
+                /* Schema Version */
+                String schemaVer = getSchemaVersion();
+                // check if it has the same schema version as the current one
+                if(!schemaVer.equals(schemaVersion)){
+                    // do something here if not the same version
+                    // ... @Override
+                }
+
+                // set the case Directory and Name
+                setCaseDirPath(file.getParent());
+                String fullFileName = file.getName();
+                String fileName = fullFileName.substring(0, fullFileName.indexOf(".")); // remove the extension
+                setName(fileName);
+            }
+        }
+        catch(Exception e){
+            throw e;
+            // throw an error here
+            //JOptionPane.showMessageDialog(caller, "Error: This file is not supported (\"" + file.getName() + "\").\n \nDetail: \n" + e.getMessage() + " (at " + className + ")." , "Error", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * When user wants to close the case. This method writes any changes to the
+     * XML case configuration file, closes it and the document handler, and
+     * clears all the local variables / fields.
+     *
+     */
+    @Override
+    public void close() throws Exception {
+        try {
+            writeFile(); // write any changes to xml
+        } catch (Exception ex) {
+            throw new Exception("Error: error while trying to close XML config file.", ex);
+        }
+
+        clear();
+    }
+
+    /**
+     * Clear the internal structures / variables
+     */
+    private void clear() {
+        doc = null;
+        caseDirPath = "";
+        caseName = "";
+    }
+
+    /**
+     * Adds the image to the current document handler.
+     *
+     * @param images     the paths of the images that want to be added
+     * @param currentID  the ID of the image that want to be added
+     * @param timeZone   the timeZone where the image is added
+     */
+    protected void addImage(String[] images, long currentID, String timeZone) throws Exception {
+
+        String dbName = "image-" + currentID + ".db";
+
+        if (doc == null) {
+            throw new Exception("No case open.");
+        } else {
+            Element rootEl = getRootElement();
+
+            int imgCount = images.length; // how many given images to add to the config file
+            Element imagesElement = getImagesElement();
+
+            //int currentID = Integer.parseInt(imagesElement.getAttribute(NEXT_ID_NAME));
+
+            // add the latest image set
+            Element imgSetElement = doc.createElement(IMG_SET_NAME); // <ImgSet> ... </ImgSet>
+            imgSetElement.setAttribute(IMG_SET_COUNT, Integer.toString(imgCount));
+            imgSetElement.setAttribute(IMG_SET_ID, Long.toString(currentID));
+            imgSetElement.setAttribute(TIMEZONE, timeZone);
+            imagesElement.appendChild(imgSetElement);
+
+            // add all the image Path
+            for (int i = 0; i < imgCount; i++) {
+                Element imgPathElement = doc.createElement(IMG_PATH_NAME); // <ImgPath> ... </ImgPath>
+                imgPathElement.setAttribute(IMG_PATH_ID, Integer.toString(i));
+                imgPathElement.setAttribute(RELATIVE_NAME, "false");
+                imgPathElement.appendChild(doc.createTextNode(images[i]));
+                imgSetElement.appendChild(imgPathElement);
+            }
+
+            // add the database
+            Element imgDbElement = doc.createElement(IMG_DB_NAME); // <ImgDb> ... </ImgDb>
+            imgDbElement.setAttribute(RELATIVE_NAME, "true");
+            imgDbElement.appendChild(doc.createTextNode(dbName));
+            //imgDbElement.appendChild(doc.createTextNode("image-" + currentID + ".db"));
+            imgSetElement.appendChild(imgDbElement);
+
+            // edit the modified data
+            String newDate = dateFormat.format(new Date());
+            rootEl.getElementsByTagName(MODIFIED_DATE_NAME).item(0).setTextContent(newDate);
+        }
+
+//            JOptionPane.showMessageDialog(caller, "Error while trying to add the image to XML config file.\n \nDetail: \n" + e.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
+
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/addImage-icon.png b/Case/src/org/sleuthkit/autopsy/casemodule/addImage-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a36d4714ac9db8a3888ab2610bef2ab0cfbb6b7c
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/addImage-icon.png differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/casemodule-helpset.xml b/Case/src/org/sleuthkit/autopsy/casemodule/casemodule-helpset.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cf939eae2eb7762dafb203d17916c97770e015b6
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/casemodule-helpset.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpsetref PUBLIC "-//NetBeans//DTD JavaHelp Help Set Reference 1.0//EN" "http://www.netbeans.org/dtds/helpsetref-1_0.dtd">
+<helpsetref url="nbdocs:/org/sleuthkit/autopsy/casemodule/docs/casemodule-hs.xml"/>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/close-icon.png b/Case/src/org/sleuthkit/autopsy/casemodule/close-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5b46fafe588f4b3e296cdfc9b08ff596b9745df
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/close-icon.png differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/layer.xml b/Case/src/org/sleuthkit/autopsy/casemodule/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..13aca858758879a9a483c100c1a84a2e7fc450ca
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/layer.xml
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <attr name="Menu\File\Separator2.instance_hidden\position" intvalue="100"/>
+    <attr name="Menu\File\Separator3.instance_hidden\position" intvalue="200"/>
+    <attr name="Menu\File\Separator4.instance_hidden\position" intvalue="400"/>
+    <attr name="Menu\File\org-netbeans-modules-print-action-PageSetupAction.shadow_hidden\position" intvalue="300"/>
+    <attr name="Menu\File\org-netbeans-modules-print-action-PrintAction.shadow_hidden\position" intvalue="500"/>
+    <attr name="Toolbars\File\org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance\iconBase" stringvalue="org/sleuthkit/autopsy/images/close-icon.gif"/>
+    <folder name="Actions">
+        <folder name="File">
+            <file name="org-sleuthkit-autopsy-casemodule-AddImageAction.instance">
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance">
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseNewAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseNewAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseOpenActionOld.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseOpenActionOld"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseOpenActionOld"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance">
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-NewCaseAct.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.NewCaseAct"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_NewCaseAct"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-NewCaseAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.NewCaseAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_NewCaseAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseOpenAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_OpenAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseSaveAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_SaveCaseAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-RecentCases.instance">
+            </file>
+        </folder>
+        <folder name="Tools">
+            <file name="org-sleuthkit-autopsy-filebrowser-FileBrowserAction.instance"></file>
+            <file name="org-sleuthkit-autopsy-hashdatabase-HashDbMgmtAction.instance">
+            </file>
+        </folder>
+        <folder name="View">
+            <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance">
+            </file>
+        </folder>
+        <folder name="Window">
+            <file name="org-sleuthkit-autopsy-casemodule-testAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.casemodule.testTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_testAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-filebrowser-FileBrowserAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.filebrowser.FileBrowserTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.filebrowser.Bundle#CTL_FileBrowserAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>
+            <file name="org-netbeans-core-windows-actions-GlobalPropertiesAction.instance_hidden"/>
+            <file name="org-sleuthkit-autopsy-filebrowser-ChangeViewAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.filebrowser.ChangeViewAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.filebrowser.Bundle#CTL_ChangeViewAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-filebrowser-DetailWindowAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.filebrowser.DetailWindowTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.filebrowser.Bundle#CTL_DetailWindowAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="File">
+            <file name="org-sleuthkit-autopsy-casemodule-CaseNewAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
+                <attr name="position" intvalue="1212"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
+                <attr name="position" intvalue="1225"/>
+            </file>
+            <folder name="Open Recent Case">
+                <attr name="position" intvalue="1262"/>
+                <file name="org-sleuthkit-autopsy-casemodule-RecentCasesAction.shadow">
+                    <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-RecentCases.instance"/>
+                </file>
+            </folder>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseCloseAct.shadow">
+                <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance"/>
+                <attr name="position" intvalue="1300"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorBefore.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="1318"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-AddImage.shadow">
+                <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>
+                <attr name="position" intvalue="1336"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorAfter.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="1354"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction-separatorBefore.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="1340"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CasePropertiesAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CasePropertiesAction.instance"/>
+                <attr name="position" intvalue="1345"/>
+            </file>
+
+            <file name="Separator2.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="Separator4.instance_hidden"/>
+            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden">
+                <attr name="position" intvalue="200"/>
+            </file>
+            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden">
+                <attr name="position" intvalue="300"/>
+            </file>
+            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
+        </folder>
+        <file name="GoTo_hidden"/>
+        <folder name="Help">
+            <file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
+        </folder>
+        <folder name="Tools">
+            <file name="org-sleuthkit-autopsy-hashdatabase-HashDatabaseSettingsAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-hashdatabase-HashDbMgmtAction.instance"/>
+                <attr name="position" intvalue="1000"/>
+            </file>
+            <file name="SeparatorAfterHashDatabaseSettings.instance">
+	        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+	        <attr name="position" intvalue="1001"/>
+            </file>
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-templates-TemplatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-options-OptionsWindowAction.shadow_hidden"/>
+            <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
+        </folder>
+        <folder name="View">
+            <file name="org-netbeans-core-actions-HTMLViewAction.shadow_hidden"/>
+            <file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
+            <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+        </folder>
+        <folder name="Window">
+            <file name="CloneDocumentAction.shadow_hidden"/>
+            <file name="CloseAllButThisAction.shadow_hidden"/>
+            <file name="CloseAllDocumentsAction.shadow_hidden"/>
+            <file name="DocumentsAction.shadow_hidden"/>
+            <file name="FileBrowserAction.shadow"/>
+            <file name="FileBrowserAction.shadow_hidden"/>
+            <file name="Output_hidden"/>
+            <file name="ProgressListAction.shadow_hidden"/>
+            <file name="SwitchToRecentDocumentAction.shadow_hidden"/>
+            <file name="ViewFavoritesTabAction.shadow_hidden"/>
+            <file name="org-netbeans-core-windows-actions-ResetWindowsAction.shadow_hidden"/>
+            <file name="testAction.shadow_hidden"/>
+        </folder>
+    </folder>
+    <folder name="Services">
+        <folder name="JavaHelp">
+            <file name="casemodule-helpset.xml" url="casemodule-helpset.xml">
+                <attr name="position" intvalue="3075"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Shortcuts">
+        <file name="D-N.shadow">
+            <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseNewAction.instance"/>
+        </file>
+        <file name="D-O.shadow">
+            <attr name="originalFile" stringvalue="Actions/File/org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance"/>
+        </file>
+    </folder>
+    <folder name="Toolbars">
+        <folder name="File">
+            <file name="org-sleuthkit-autopsy-casemodule-NewCaseAct.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseNewAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseNewAction"/>
+                <attr name="iconBase" stringvalue="org/sleuthkit/autopsy/images/new-icon.png"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+                <attr name="position" intvalue="150"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseSaveAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_SaveCaseAction"/>
+                <attr name="iconBase" stringvalue="org/sleuthkit/autopsy/images/save-icon.png"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+                <attr name="position" intvalue="300"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseOpenAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseOpenAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_OpenAction"/>
+                <attr name="iconBase" stringvalue="org/sleuthkit/autopsy/images/open-icon.png"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+                <attr name="position" intvalue="200"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseCloseAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.CaseCloseAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_CaseCloseAct"/>
+                <attr name="iconBase" stringvalue="org/sleuthkit/autopsy/images/close-icon.png"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+                <attr name="position" intvalue="400"/>
+            </file>
+            <file name="sep1.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JToolBar$Separator"/>
+                <attr name="position" intvalue="500"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-AddImageAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.casemodule.AddImageAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.casemodule.Bundle#CTL_AddImage"/>
+                <attr name="iconBase" stringvalue="org/sleuthkit/autopsy/images/addImage-icon.png"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+                <attr name="position" intvalue="550"/>
+            </file>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden">
+                <attr name="position" intvalue="100"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance_hidden"/>
+        </folder>
+        <file name="UndoRedo_hidden"/>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components"/>
+        <folder name="Modes">
+            <folder name="editor"/>
+            <folder name="output"/>
+        </folder>
+    </folder>
+</filesystem>
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/new-icon.png b/Case/src/org/sleuthkit/autopsy/casemodule/new-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..02566d35affba3384958dc9d7e56bc3ef53dce31
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/new-icon.png differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/open-icon.png b/Case/src/org/sleuthkit/autopsy/casemodule/open-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..073b95b0869464686de1e0ad3296bafb026bc470
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/open-icon.png differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/open-recent-icon.png b/Case/src/org/sleuthkit/autopsy/casemodule/open-recent-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee3664a9357bf277f16938e6c6f003b557d34650
Binary files /dev/null and b/Case/src/org/sleuthkit/autopsy/casemodule/open-recent-icon.png differ
diff --git a/Case/src/org/sleuthkit/autopsy/casemodule/package.html b/Case/src/org/sleuthkit/autopsy/casemodule/package.html
new file mode 100644
index 0000000000000000000000000000000000000000..4d7d55f36f4c9949892e358c8dadb0f4d9e43f73
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/casemodule/package.html
@@ -0,0 +1,10 @@
+<body>
+    <p>A case contains one or more disk images and is the highest-level unit of an investigation.  All data in a case will be stored in a single database and configuration file. A case must be open before analysis can occur. You will use a {@link org.sleuthkit.autopsy.casemodule.Case#Case Case} object to get access to the data being analyzed.</p>
+
+    <p>Case settings are stored in an XML file.  See the {@link org.sleuthkit.autopsy.casemodule.XMLCaseManagement#XMLCaseManagement() XMLCaseManagement} class for more details.</p>
+    
+    <p>Currently, only one case can be opened at a time.  To determine the open case, use the static {@link org.sleuthkit.autopsy.casemodule.Case#getCurrentCase() Case.getCurrentCase()} method.  Once you have the object for the currently open case, {@link org.sleuthkit.autopsy.casemodule.Case#getRootObjects() Case.getRootObjects()} will return the top-level Sleuth Kit Content modules. You can then get their children to go down the tree of data types. </p>
+    
+    <p>To receive an event when cases are opened, closed, or changed, use the {@link org.sleuthkit.autopsy.casemodule.Case#addPropertyChangeListener(PropertyChangeListener) addPropertyChangeListener} method to register your class as a PropertyChangeListener.  THis is most commonly required when developing a new {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer#DataExplorer() DataExplorer} module that needs to get data about the currently opened case. </p>
+</body>
+
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties b/Case/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4e1a79475347a422abd7d87ec35a6379d09ee3e6
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/Bundle.properties
@@ -0,0 +1,2 @@
+HashDatabaseManagementPanel.okayButton.text=Okay
+HashDbPanel.fileSelectButton.text=Select...\n
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a70ad8180b26815fd8c83e3783d8b892b261269
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDb.java
@@ -0,0 +1,179 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+import java.io.File;
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.SleuthkitJNI;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * HashDb is based on the path to a database, and has methods to check the 
+ * status of database and index files, and create indexes.  One of these 
+ * is created for every open hash database. 
+ */
+class HashDb {
+
+    // Suffix added to the end of a database name to get its index file
+    private static final String INDEX_SUFFIX = "-md5.idx";
+    /**
+     * Path to database (database and/or index may not actually exist)
+     */
+    String databasePath;
+
+    /**
+     * New {@link HashDb} for database at given path
+     * @param databasePath Path of database this instance represents (database
+     * and/or index may not actually exist)
+     */
+    HashDb(String databasePath) {
+        this.databasePath = databasePath;
+    }
+
+    /**
+     * Checks if the database exists.
+     * @return true if a file exists at the database path, else false
+     */
+    boolean databaseExists() {
+        return databaseFile().exists();
+    }
+
+    /**
+     * Checks if Sleuth Kit can open the index for the database path.
+     * @return true if the index was found and opened successfully, else false
+     */
+    boolean indexExists() {
+        try {
+            return hasIndex(databasePath);
+        } catch (TskException ex) {
+            Log.get(this.getClass()).log(Level.WARNING, "Error checking if index exists.", ex);
+            return false;
+        }
+    }
+
+    /**
+     * Gets the database file.
+     * @return a File initialized with the database path
+     */
+    File databaseFile() {
+        return new File(databasePath);
+    }
+
+    /**
+     * Gets the index file
+     * @return a File initialized with an index path derived from the database
+     * path
+     */
+    File indexFile() {
+        return new File(toIndexPath(databasePath));
+    }
+
+    /**
+     * Checks if the index file is older than the database file
+     * @return true if there is are files at the index path and the database
+     * path, and the index file has an older modified-time than the database
+     * file, else false
+     */
+    boolean isOutdated() {
+        File i = indexFile();
+        File db = databaseFile();
+
+        return i.exists() && db.exists() && isOlderThan(i, db);
+    }
+
+    /**
+     * Returns the status of the HashDb as determined from indexExists(),
+     * databaseExists(), and isOutdated()
+     * @return IndexStatus enum according to their definitions
+     */
+    IndexStatus status() {
+        boolean i = this.indexExists();
+        boolean db = this.databaseExists();
+
+        if (i) {
+            if (db) {
+                return this.isOutdated() ? IndexStatus.INDEX_OUTDATED : IndexStatus.INDEX_CURRENT;
+            } else {
+                return IndexStatus.NO_DB;
+            }
+        } else {
+            return db ? IndexStatus.NO_INDEX : IndexStatus.NONE;
+        }
+    }
+
+    /**
+     * Tries to index the database (overwrites any existing index)
+     * @throws TskException if an error occurs in the SleuthKit bindings 
+     */
+    void createIndex() throws TskException {
+        SleuthkitJNI.createLookupIndex(databasePath);
+        //TODO: error checking
+    }
+
+    /**
+     * Checks if one file is older than an other
+     * @param a first file
+     * @param b second file
+     * @return true if the first file's last modified data is before the second
+     * file's last modified date
+     */
+    private static boolean isOlderThan(File a, File b) {
+        return a.lastModified() < b.lastModified();
+    }
+
+    /**
+     * Determines if a path points to an index by checking the suffix
+     * @param path
+     * @return true if index
+     */
+    static boolean isIndexPath(String path) {
+        return path.endsWith(INDEX_SUFFIX);
+    }
+
+    /**
+     * Derives database path from an image path by removing the suffix.
+     * @param indexPath
+     * @return 
+     */
+    static String toDatabasePath(String indexPath) {
+        return indexPath.substring(0, indexPath.lastIndexOf(INDEX_SUFFIX));
+    }
+
+    /**
+     * Derives image path from an database path by appending the suffix.
+     * @param databasePath
+     * @return 
+     */
+    static String toIndexPath(String databasePath) {
+        return databasePath.concat(INDEX_SUFFIX);
+    }
+
+    /**
+     * Calls Sleuth Kit method via JNI to determine whether there is an
+     * index for the given path
+     * @param databasePath path Path for the database the index is of
+     * (database doesn't have to actually exist)'
+     * @return true if index exists
+     * @throws TskException if  there is an error in the JNI call 
+     */
+    static boolean hasIndex(String databasePath) throws TskException {
+        return SleuthkitJNI.lookupIndexExists(databasePath);
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtAction.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..757dea2f5e9ea15850a841581b8d08a25eff6b8c
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtAction.java
@@ -0,0 +1,106 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.logging.Level;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.sleuthkit.autopsy.casemodule.Autopsy;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The HashDbMgmtAction opens the HashDbMgmtPanel in a dialog, and saves the
+ * settings of the panel if the Apply button is clicked.
+ * @author pmartel
+ */
+class HashDbMgmtAction extends CallableSystemAction {
+
+    private static final String ACTION_NAME = "Hash Database Management";
+
+    @Override
+    public void performAction() {
+        Log.noteAction(this.getClass());
+
+        try {
+            // Load settings from the property file
+            HashDbSettings hashDatabaseSettings = new HashDbSettings(Autopsy.getPropertyFile());
+
+            // create the popUp window for it
+            final JFrame frame = new JFrame(ACTION_NAME);
+            final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
+
+            // initialize panel with loaded settings
+            final HashDbMgmtPanel panel = new HashDbMgmtPanel(hashDatabaseSettings);
+
+            // set action for the "Apply" button
+            panel.setApplyButtonActionListener(new ActionListener() {
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    if (panel.indexesExist()) {
+                        try {
+                            panel.saveSettings();
+                        } catch (IOException ex) {
+                            Log.get(HashDbMgmtAction.class).log(Level.WARNING, "Couldn't save hash database settings.", ex);
+                        }
+                        popUpWindow.dispose();
+                    } else {
+                        NotifyDescriptor d = new NotifyDescriptor.Message("All selected databases must have indexes.", NotifyDescriptor.INFORMATION_MESSAGE);
+                        DialogDisplayer.getDefault().notify(d);
+                    }
+                }
+            });
+
+            // add the panel to the popup window
+            popUpWindow.add(panel);
+            popUpWindow.pack();
+            popUpWindow.setResizable(false);
+
+            // set the location of the popUp Window on the center of the screen
+            Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+            double w = popUpWindow.getSize().getWidth();
+            double h = popUpWindow.getSize().getHeight();
+            popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
+
+            // display the window
+            popUpWindow.setVisible(true);
+        } catch (Exception ex) {
+            Log.get(HashDbMgmtAction.class).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return ACTION_NAME;
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..09d619dbd64373231047aac89a7bba093258d46d
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbMgmtPanel.java
@@ -0,0 +1,131 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * Panel for displaying and editing the Hash Database settings.
+ * @author pmartel
+ */
+class HashDbMgmtPanel extends javax.swing.JPanel {
+
+    private HashDbSettings settings;
+    // text of panel for each database
+    private static final String INTRO_TEXT1 = "Hash lookups are conducted when an image is added to a case.";
+    private static final String INTRO_TEXT2 = "Lookup results can be found using the File Search feature.";
+    private static final String NSRL_NAME = "NIST NSRL Database";
+    private static final String NSRL_DESC = "Hashes that are known good and bad.";
+    private static final String KNOWN_BAD_NAME = "Known Bad Database";
+    private static final String KNOWN_BAD_DESC = "Hashes that are known bad.";
+    private JLabel introText1;
+    private JLabel introText2;
+    private HashDbPanel NSRLPanel;
+    private HashDbPanel knownBadPanel;
+    private JButton applyButton;
+
+    /**
+     * 
+     * @param settings Settings to initialize the panel state from.
+     */
+    HashDbMgmtPanel(HashDbSettings settings) {
+        this.settings = settings;
+
+        initComponents();
+    }
+
+    /**
+     * Sets a listener for the Apply button
+     * @param e  The action listener
+     */
+    void setApplyButtonActionListener(ActionListener e) {
+        this.applyButton.addActionListener(e);
+    }
+
+    /**
+     * Checks if indexes exist for all defined databases
+     * @return true if Sleuth Kit can open the indexes of all databases
+     * than have been selected
+     */
+    boolean indexesExist() {
+        HashDb nsrl = this.NSRLPanel.db;
+        HashDb knownBad = this.knownBadPanel.db;
+
+        if (nsrl != null && !nsrl.indexExists()) {
+            return false;
+        }
+        if (knownBad != null && !knownBad.indexExists()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Modifies the given settings object to match the current panel state, and
+     * then persists it to its backing file.
+     * @throws IOException if there is an error saving the settings to a file
+     */
+    void saveSettings() throws IOException {
+        this.settings.setNSRLDatabase(this.NSRLPanel.db);
+        this.settings.setKnownBadDatabase(this.knownBadPanel.db);
+        this.settings.save();
+    }
+
+    /**
+     * Initializes all the panel components
+     */
+    private void initComponents() {
+
+        NSRLPanel = new HashDbPanel(this.settings.getNSRLDatabase(), HashDbMgmtPanel.NSRL_NAME, HashDbMgmtPanel.NSRL_DESC);
+        knownBadPanel = new HashDbPanel(this.settings.getKnownBadDatabase(), HashDbMgmtPanel.KNOWN_BAD_NAME, HashDbMgmtPanel.KNOWN_BAD_DESC);
+
+        applyButton = new JButton();
+        applyButton.setText("OK");
+        applyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+        introText1 = new JLabel();
+        introText1.setText(INTRO_TEXT1);
+        introText1.setBorder(new EmptyBorder(10, 10, 5, 10));
+        introText1.setAlignmentX(Component.CENTER_ALIGNMENT);
+        introText1.setMaximumSize(NSRLPanel.getMaximumSize());
+
+        introText2 = new JLabel();
+        introText2.setText(INTRO_TEXT2);
+        introText2.setBorder(new EmptyBorder(0, 10, 0, 10));
+        introText2.setAlignmentX(Component.CENTER_ALIGNMENT);
+        introText2.setMaximumSize(NSRLPanel.getMaximumSize());
+
+        BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
+        this.setLayout(layout);
+        this.add(introText1);
+        this.add(introText2);
+        this.add(NSRLPanel);
+        this.add(knownBadPanel);
+        this.add(applyButton);
+        this.add(Box.createRigidArea(new Dimension(0, 10)));
+    }
+}
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.form b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..ea8d74107df53ac064fd944dae95b1d411bedc64
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.form
@@ -0,0 +1,129 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="databaseNameLabel" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" max="-2" attributes="0">
+                      <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Group type="102" alignment="0" attributes="0">
+                              <Component id="indexButton" min="-2" max="-2" attributes="0"/>
+                              <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
+                              <Component id="indexStatusLabel" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <Group type="102" alignment="0" attributes="0">
+                              <Component id="databasePathField" min="-2" pref="329" max="-2" attributes="0"/>
+                              <EmptySpace min="-2" max="-2" attributes="0"/>
+                              <Component id="fileSelectButton" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <Component id="databaseDetailsLabel" alignment="0" max="32767" attributes="1"/>
+                      </Group>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Component id="databaseNameLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="databaseDetailsLabel" min="-2" pref="14" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="databasePathField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="fileSelectButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="indexButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="indexStatusLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="32767" attributes="1"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="databaseNameLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
+          <FontInfo relative="true">
+            <Font bold="true" component="databaseNameLabel" property="font" relativeSize="true" size="2"/>
+          </FontInfo>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="databaseName()" type="code"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JFormattedTextField" name="databasePathField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="path()" type="code"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="databasePathFieldActionPerformed"/>
+        <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="databasePathFieldFocusLost"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="indexButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="indexOrReindex()" type="code"/>
+        </Property>
+        <Property name="enabled" type="boolean" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="indexable()" type="code"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="indexButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="indexStatusLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="indexStatus()" type="code"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="databaseDetailsLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="databaseDetails()" type="code"/>
+        </Property>
+        <Property name="verticalAlignment" type="int" value="1"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="fileSelectButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/hashdatabase/Bundle.properties" key="HashDbPanel.fileSelectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fileSelectButtonActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..49f934d9d4014d1d5acc1fbfe52f03939da2513c
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbPanel.java
@@ -0,0 +1,300 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * HashDbPanel.java
+ *
+ * Created on Oct 11, 2011, 2:44:56 PM
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+import java.awt.Cursor;
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JFileChooser;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * Panel for selecting a hash database.
+ * @author pmartel
+ */
+class HashDbPanel extends javax.swing.JPanel {
+
+    /**
+     * Current hash database backing the panel (can be null).
+     */
+    HashDb db;
+    /**
+     * Name to title this database panel.
+     */
+    String databaseName;
+    /**
+     * Details of this database slot.
+     */
+    String databaseDetails;
+    private JFileChooser fc = new JFileChooser();
+
+    /**
+     * Create a panel from a current setting and description strings.
+     * @param db current hash database (can be null)
+     * @param databaseName name to title this database panel
+     * @param databaseDetails details of this database
+     */
+    HashDbPanel(HashDb db, String databaseName, String databaseDetails) {
+        this.db = db; // nullable
+        this.databaseDetails = databaseDetails;
+        this.databaseName = databaseName;
+
+        fc.setDragEnabled(false);
+        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+        fc.setMultiSelectionEnabled(false);
+
+        this.initComponents();
+        this.refresh();
+    }
+
+    /**
+     * Gets the string for the (re)index button.
+     * @return "Reindex" if the database and index exist, otherwise "Index"
+     */
+    private String indexOrReindex() {
+        return (this.db != null) && this.db.databaseExists() && this.db.indexExists() ? "Reindex" : "Index";
+    }
+
+    private String databaseName() {
+        return this.databaseName;
+    }
+
+    private String databaseDetails() {
+        return this.databaseDetails;
+    }
+
+    /**
+     * @return Path to database to display in panel
+     */
+    private String path() {
+        return (this.db != null) ? this.db.databasePath : "";
+    }
+
+    /**
+     * Short description of the index/db state (if there is one)
+     * @return 
+     */
+    private String indexStatus() {
+        return (this.db != null) ? db.status().message() : "";
+    }
+
+    /**
+     * Check if an index can be created.
+     * @return true if the database exists
+     */
+    private boolean indexable() {
+        return (this.db != null) && db.databaseExists();
+    }
+
+    private boolean invalid() {
+        return (this.db != null) && this.db.status().equals(IndexStatus.NONE);
+    }
+
+    /**
+     * Updates the state of all panel elements.
+     */
+    private void refresh() {
+        this.databasePathField.setText(this.path());
+        this.indexButton.setEnabled(this.indexable());
+        this.indexButton.setText(this.indexOrReindex());
+        this.indexStatusLabel.setText(this.indexStatus());
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        databaseNameLabel = new javax.swing.JLabel();
+        databasePathField = new javax.swing.JFormattedTextField();
+        indexButton = new javax.swing.JButton();
+        indexStatusLabel = new javax.swing.JLabel();
+        databaseDetailsLabel = new javax.swing.JLabel();
+        fileSelectButton = new javax.swing.JButton();
+
+        databaseNameLabel.setFont(databaseNameLabel.getFont().deriveFont(databaseNameLabel.getFont().getStyle() | java.awt.Font.BOLD, databaseNameLabel.getFont().getSize()+2));
+        databaseNameLabel.setText(databaseName());
+
+        databasePathField.setText(path());
+        databasePathField.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                databasePathFieldActionPerformed(evt);
+            }
+        });
+        databasePathField.addFocusListener(new java.awt.event.FocusAdapter() {
+            public void focusLost(java.awt.event.FocusEvent evt) {
+                databasePathFieldFocusLost(evt);
+            }
+        });
+
+        indexButton.setText(indexOrReindex());
+        indexButton.setEnabled(indexable());
+        indexButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                indexButtonActionPerformed(evt);
+            }
+        });
+
+        indexStatusLabel.setText(indexStatus());
+
+        databaseDetailsLabel.setText(databaseDetails());
+        databaseDetailsLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
+
+        fileSelectButton.setText(org.openide.util.NbBundle.getMessage(HashDbPanel.class, "HashDbPanel.fileSelectButton.text")); // NOI18N
+        fileSelectButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                fileSelectButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(databaseNameLabel)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(10, 10, 10)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(layout.createSequentialGroup()
+                                .addComponent(indexButton)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(indexStatusLabel))
+                            .addGroup(layout.createSequentialGroup()
+                                .addComponent(databasePathField, javax.swing.GroupLayout.PREFERRED_SIZE, 329, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(fileSelectButton))
+                            .addComponent(databaseDetailsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(databaseNameLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(databaseDetailsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(databasePathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(fileSelectButton))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(indexButton)
+                    .addComponent(indexStatusLabel))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void indexButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_indexButtonActionPerformed
+        if (this.db != null) {
+            try {
+                // change the cursor to "waiting cursor"
+                this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                try {
+                    this.db.createIndex();
+                } finally {
+                    this.setCursor(null);
+                }
+            } catch (TskException ex) {
+                Log.get(this.getClass()).log(Level.WARNING, "Couldn't create index.", ex);
+            }
+        }
+
+        this.refresh();
+    }//GEN-LAST:event_indexButtonActionPerformed
+
+    private void databasePathFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_databasePathFieldActionPerformed
+        // if field becomes editable: add handler
+    }//GEN-LAST:event_databasePathFieldActionPerformed
+
+    private void fileSelectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSelectButtonActionPerformed
+
+        int retval = fc.showOpenDialog(this);
+
+        if (retval == JFileChooser.APPROVE_OPTION) {
+            File f = fc.getSelectedFile();
+            try {
+                String filePath = f.getCanonicalPath();
+
+                if (HashDb.isIndexPath(filePath)) {
+                    filePath = HashDb.toDatabasePath(filePath);
+                }
+
+                this.db = new HashDb(filePath);
+
+
+            } catch (IOException ex) {
+                Logger.getLogger(HashDbPanel.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex);
+                return;
+            }
+        }
+
+        this.refresh();
+    }//GEN-LAST:event_fileSelectButtonActionPerformed
+
+    private void databasePathFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_databasePathFieldFocusLost
+
+        String path = databasePathField.getText().trim();
+
+        if (path.isEmpty()) {
+            this.db = null;
+        } else {
+            File f = new File(path);
+            try {
+                String filePath = f.getCanonicalPath();
+
+                if (HashDb.isIndexPath(filePath)) {
+                    filePath = HashDb.toDatabasePath(filePath);
+                }
+
+                this.db = new HashDb(filePath);
+
+            } catch (IOException ex) {
+                Logger.getLogger(HashDbPanel.class.getName()).log(Level.WARNING, "Couldn't get selected file path.", ex);
+                return;
+            }
+        }
+
+        this.refresh();
+    }//GEN-LAST:event_databasePathFieldFocusLost
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel databaseDetailsLabel;
+    private javax.swing.JLabel databaseNameLabel;
+    private javax.swing.JFormattedTextField databasePathField;
+    private javax.swing.JButton fileSelectButton;
+    private javax.swing.JButton indexButton;
+    private javax.swing.JLabel indexStatusLabel;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbSettings.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..370e0394518ba4a6d9fbcfd21e5cde86f1407348
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/HashDbSettings.java
@@ -0,0 +1,166 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Loads and stores Hash Database settings from/to a property file
+ * @author pmartel
+ */
+public class HashDbSettings {
+
+    private static final String PROP_PREFIX = "HASHDB";
+    private static final String NSRL_PROP = "NSRL";
+    private static final String KNOWN_BAD_PROP = "KNOWN_BAD";
+    private File propertyFile;
+    private HashDb NSRLDatabase, knownBadDatabase;
+
+    /**
+     * @param propertyFile file to load settings from
+     * @throws IOException if there's an error loading the property file
+     * @throws FileNotFoundException if the property file can't be found
+     */
+    public HashDbSettings(File propertyFile) throws IOException, FileNotFoundException {
+        this.propertyFile = propertyFile;
+
+        Properties temp = new Properties();
+        InputStream loadStream = new FileInputStream(propertyFile);
+        temp.load(loadStream);
+        loadStream.close();
+
+        String NSRL = getNSRL(temp);
+        String knownBad = getKnownBad(temp);
+
+        if (!NSRL.equals("")) {
+            this.NSRLDatabase = new HashDb(NSRL);
+        }
+
+        if (!knownBad.equals("")) {
+            this.knownBadDatabase = new HashDb(knownBad);
+        }
+    }
+
+    /**
+     * Writes settings to the property file
+     * @throws IOException if there's an error loading or writing to the
+     * property file
+     * @throws FileNotFoundException if the property file can't be found
+     */
+    void save() throws IOException, FileNotFoundException {
+        Properties temp = new Properties();
+        InputStream loadStream = new FileInputStream(propertyFile);
+        temp.load(loadStream);
+        loadStream.close();
+
+        setNSRL(temp, this.NSRLDatabase != null ? this.NSRLDatabase.databasePath : "");
+        setKnownBad(temp, this.knownBadDatabase != null ? this.knownBadDatabase.databasePath : "");
+
+        String comments = "";
+        OutputStream storeStream = new FileOutputStream(propertyFile);
+        temp.store(storeStream, comments);
+        storeStream.close();
+    }
+
+    /**
+     * Returns the path the the selected NSRL hash database, or null if there is
+     * none selected.
+     * @return path or null
+     */
+    public String getNSRLDatabasePath() {
+        return this.NSRLDatabase != null ? this.NSRLDatabase.databasePath : null;
+    }
+
+    /**
+     * Returns the path the the selected Known Bad hash database, or null if
+     * there is none selected.
+     * @return path or null
+     */
+    public String getKnownBadDatabasePath() {
+        return this.knownBadDatabase != null ? this.knownBadDatabase.databasePath : null;
+    }
+
+    /**
+     * Gets NSRL database if there is one
+     * @return database (can be null)
+     */
+    HashDb getNSRLDatabase() {
+        return this.NSRLDatabase;
+    }
+
+    /**
+     * Gets known bad database if there is one
+     * @return database (can be null)
+     */
+    HashDb getKnownBadDatabase() {
+        return this.knownBadDatabase;
+    }
+
+    /**
+     * Set NSRL database 
+     * @param nsrl database, or null to clear
+     */
+    void setNSRLDatabase(HashDb nsrl) {
+        this.NSRLDatabase = nsrl;
+    }
+
+    /**
+     * Set known bad database 
+     * @param knownBad known bad database, or null to clear
+     */
+    void setKnownBadDatabase(HashDb knownBad) {
+        this.knownBadDatabase = knownBad;
+    }
+
+    // helper functions:
+    private static void setNSRL(Properties props, String databasePath) {
+        setProp(props, NSRL_PROP, databasePath);
+    }
+
+    private static void setKnownBad(Properties props, String databasePath) {
+        setProp(props, KNOWN_BAD_PROP, databasePath);
+    }
+
+    private static String getNSRL(Properties props) {
+        return getProp(props, NSRL_PROP);
+    }
+
+    private static String getKnownBad(Properties props) {
+        return getProp(props, KNOWN_BAD_PROP);
+    }
+
+    private static void setProp(Properties props, String propName, String propValue) {
+        props.setProperty(fullProp(propName), propValue);
+    }
+
+    private static String getProp(Properties props, String propName) {
+        return props.getProperty(fullProp(propName), "");
+    }
+
+    private static String fullProp(String propName) {
+        return PROP_PREFIX + "_" + propName;
+    }
+}
\ No newline at end of file
diff --git a/Case/src/org/sleuthkit/autopsy/hashdatabase/IndexStatus.java b/Case/src/org/sleuthkit/autopsy/hashdatabase/IndexStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..479f73834c42cdaa8c96ce8fef2058ef2fb0b74f
--- /dev/null
+++ b/Case/src/org/sleuthkit/autopsy/hashdatabase/IndexStatus.java
@@ -0,0 +1,65 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.hashdatabase;
+
+/**
+ * The status of a HashDb as determined from its indexExists(),
+ * databaseExists(), and isOutdated() methods
+ * @author pmartel
+ */
+enum IndexStatus {
+
+    /**
+     * The index and database both exist, and the index is older.
+     */
+    INDEX_OUTDATED("Index is older than database."),
+    /**
+     * The index and database both exist, and the index is not older.
+     */
+    INDEX_CURRENT("Database has index."),
+    /**
+     * The index exists but the database does not.
+     */
+    NO_DB("Index does not have database."),
+    /**
+     * The database exists but the index does not.
+     */
+    NO_INDEX("Database does not have index."),
+    /**
+     * Neither the index nor the database exists.
+     */
+    NONE("No index or database.");
+    
+    private String message;
+
+    /**
+     * @param message Short description of the state represented
+     */
+    private IndexStatus(String message) {
+        this.message = message;
+    }
+
+    /**
+     * Get status message
+     * @return a short description of the state represented
+     */
+    String message() {
+        return this.message;
+    }
+}
diff --git a/Case/test/unit/src/org/sleuthkit/autopsy/casemodule/RecentCasesTest.java b/Case/test/unit/src/org/sleuthkit/autopsy/casemodule/RecentCasesTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f56a7bec6b45daeef11b8dc1b655624ba1c67019
--- /dev/null
+++ b/Case/test/unit/src/org/sleuthkit/autopsy/casemodule/RecentCasesTest.java
@@ -0,0 +1,280 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.casemodule;
+
+import java.awt.event.ActionEvent;
+import javax.swing.JMenuItem;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class RecentCasesTest {
+    RecentCases instance;
+
+    public RecentCasesTest() {
+        instance = RecentCases.getInstance();
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+        instance.actionPerformed(null);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getInstance method, of class RecentCases.
+     */
+    @Test
+    public void testGetInstance() {
+        System.out.println("getInstance");
+        RecentCases expResult = RecentCases.getInstance();
+        RecentCases result = RecentCases.getInstance();
+        assertEquals(expResult, result);
+        assertNotNull(result);
+    }
+
+    /**
+     * Test of getMenuPresenter method, of class RecentCases.
+     */
+    @Test
+    public void testGetMenuPresenter() {
+        System.out.println("getMenuPresenter");
+        JMenuItem result = instance.getMenuPresenter();
+        assertNotNull(result);
+    }
+
+    /**
+     * Test of actionPerformed method, of class RecentCases.
+     */
+    @Test
+    public void testActionPerformed() {
+        System.out.println("actionPerformed");
+        ActionEvent e = null;
+        instance.addRecentCase("test", "test");
+        instance.actionPerformed(e);
+        assertEquals(instance.getTotalRecentCases(), 0);
+
+    }
+
+    /**
+     * Test of addRecentCase method, of class RecentCases.
+     */
+    @Test
+    public void testAddRecentCase() {
+        System.out.println("addRecentCase");
+        String name = "name";
+        String path = "C:\\path";
+        instance.addRecentCase(name, path);
+        instance.addRecentCase(name, path);
+        assertEquals(name, instance.getRecentCaseNames()[0]);
+        assertEquals(path, instance.getRecentCasePaths()[0]);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+
+    /**
+     * Test of updateRecentCase method, of class RecentCases.
+     */
+    @Test
+    public void testUpdateRecentCase() throws Exception {
+        System.out.println("updateRecentCase");
+        String oldName = "oldName";
+        String oldPath = "C:\\oldPath";
+        String newName = "newName";
+        String newPath = "C:\\newPath";
+        instance.addRecentCase(oldName, oldPath);
+        instance.updateRecentCase(oldName, oldPath, newName, newPath);
+        assertEquals(newName, instance.getRecentCaseNames()[0]);
+        assertEquals(newPath, instance.getRecentCasePaths()[0]);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+
+    /**
+     * Test of getTotalRecentCases method, of class RecentCases.
+     */
+    @Test
+    public void testGetTotalRecentCases() {
+        System.out.println("getTotalRecentCases");
+        int expResult = 0;
+        int result = instance.getTotalRecentCases();
+        assertEquals(expResult, result);
+        instance.addRecentCase("name", "path");
+        result = instance.getTotalRecentCases();
+        expResult = 1;
+        assertEquals(expResult, result);
+    }
+
+    /**
+     * Test of removeRecentCase method, of class RecentCases.
+     */
+    @Test
+    public void testRemoveRecentCase() {
+        System.out.println("removeRecentCase");
+        String name = "name";
+        String path = "path";
+        String name1 = "name1";
+        String path1 = "path1";
+        instance.addRecentCase(name, path);
+        instance.addRecentCase(name1, path1);
+        instance.removeRecentCase(name, path);
+        assertEquals(1, instance.getTotalRecentCases());
+        instance.removeRecentCase(name, path);
+        assertEquals(1, instance.getTotalRecentCases());
+        instance.removeRecentCase(name1, path1);
+        assertEquals(0, instance.getTotalRecentCases());
+    }
+
+    /**
+     * Test of getRecentCaseNames method, of class RecentCases.
+     */
+    @Test
+    public void testGetRecentCaseNames() {
+        System.out.println("getRecentCaseNames");
+        String[] expResult = {"","","","",""};
+        String[] result = instance.getRecentCaseNames();
+        assertArrayEquals(expResult, result);
+        String name = "name";
+        String path = "C:\\path";
+        String name1 = "name1";
+        String path1 = "C:\\path1";
+        instance.addRecentCase(name, path);
+        instance.addRecentCase(name1, path1);
+        String[] expResult1 = {name1,name,"","",""};
+        String[] result1 = instance.getRecentCaseNames();
+        assertArrayEquals(expResult1, result1);
+    }
+
+    /**
+     * Test of getRecentCasePaths method, of class RecentCases.
+     */
+    @Test
+    public void testGetRecentCasePaths() {
+        System.out.println("getRecentCasePaths");
+        String[] expResult = {"","","","",""};
+        String[] result = instance.getRecentCasePaths();
+        assertArrayEquals(expResult, result);
+        String name = "name";
+        String path = "C:\\path";
+        String name1 = "name1";
+        String path1 = "C:\\path1";
+        instance.addRecentCase(name, path);
+        instance.addRecentCase(name1, path1);
+        String[] expResult1 = {path1, path,"","",""};
+        String[] result1 = instance.getRecentCasePaths();
+        assertArrayEquals(expResult1, result1);
+    }
+
+    /**
+     * Test of getName method, of class RecentCases.
+     */
+    @Test
+    public void testGetName() {
+        System.out.println("getName");
+        String result = instance.getName();
+        assertNotNull(result);
+    }    
+    
+    
+    
+    /**
+     * Regression tests for TSK-227
+     * Make sure that paths are normalized, so that different representations of
+     * the same path don't result in duplicates.
+     */
+    @Test
+    public void testNormalizePathAddRecentCase1() {
+        System.out.println("normalizePathAddRecentCase1");
+        String name = "name";
+        String path = "C:\\biig-case\\biig-case.aut";
+        String oddPath = "c:\\\\biig-case\\biig-case.aut";
+        instance.addRecentCase(name, path);
+        instance.addRecentCase(name, oddPath);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+    @Test
+    public void testNormalizePathAddRecentCase2() {
+        System.out.println("normalizePathAddRecentCase2");
+        String name = "name";
+        String path = "C:\\biig-case\\biig-case.aut";
+        String oddPath = "c:\\\\biig-case\\biig-case.aut";
+        instance.addRecentCase(name, oddPath);
+        instance.addRecentCase(name, path);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+    @Test
+    public void testNormalizePathUpdateRecentCase1() throws Exception {
+        System.out.println("normalizePathUpdateRecentCase1");
+        String oldName = "oldName";
+        String oldPath = "C:\\biig-case\\biig-case.aut";
+        String oddOldPath = "c:\\\\biig-case\\biig-case.aut";
+        String newName = "newName";
+        String newPath = "newPath";
+        instance.addRecentCase(oldName, oldPath);
+        instance.updateRecentCase(oldName, oddOldPath, newName, newPath);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+    @Test
+    public void testNormalizePathUpdateRecentCase2() throws Exception {
+        System.out.println("normalizePathUpdateRecentCase2");
+        String oldName = "oldName";
+        String oldPath = "C:\\biig-case\\biig-case.aut";
+        String oddOldPath = "c:\\\\biig-case\\biig-case.aut";
+        String newName = "newName";
+        String newPath = "newPath";
+        instance.addRecentCase(oldName, oddOldPath);
+        instance.updateRecentCase(oldName, oldPath, newName, newPath);
+        assertEquals(1, instance.getTotalRecentCases());
+    }
+    @Test
+    public void testNormalizePathRemoveRecentCase1() {
+        System.out.println("normalizePathRemoveRecentCase1");
+        String name = "name";
+        String path = "C:\\biig-case\\biig-case.aut";
+        String oddPath = "c:\\\\biig-case\\biig-case.aut";
+        instance.addRecentCase(name, path);
+        instance.removeRecentCase(name, oddPath);
+        assertEquals(0, instance.getTotalRecentCases());
+    }
+    @Test
+    public void testNormalizePathRemoveRecentCase2() {
+        System.out.println("normalizePathRemoveRecentCase2");
+        String name = "name";
+        String path = "C:\\biig-case\\biig-case.aut";
+        String oddPath = "c:\\\\biig-case\\biig-case.aut";
+        instance.addRecentCase(name, oddPath);
+        instance.removeRecentCase(name, path);
+        assertEquals(0, instance.getTotalRecentCases());
+    }
+    
+
+}
\ No newline at end of file
diff --git a/CoreComponentInterfaces/build.xml b/CoreComponentInterfaces/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..34bf86be8d423bbbe0bc99202b128d4cfb511285
--- /dev/null
+++ b/CoreComponentInterfaces/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.corecomponentinterfaces" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.corecomponentinterfaces.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/CoreComponentInterfaces/manifest.mf b/CoreComponentInterfaces/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..514519f60e46d03f0814a057416ab413c8964398
--- /dev/null
+++ b/CoreComponentInterfaces/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.corecomponentinterfaces/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/corecomponentinterfaces/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corecomponentinterfaces/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager
+
diff --git a/CoreComponentInterfaces/nbproject/build-impl.xml b/CoreComponentInterfaces/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc08b8cc9c4ad151d5f1ddb80e7a68a42de2d6db
--- /dev/null
+++ b/CoreComponentInterfaces/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.corecomponentinterfaces-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/CoreComponentInterfaces/nbproject/genfiles.properties b/CoreComponentInterfaces/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..614b3b3cd2dfee552d921a5145af27c19beec70d
--- /dev/null
+++ b/CoreComponentInterfaces/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=70bb94aa
+build.xml.script.CRC32=c5094f8f
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=70bb94aa
+nbproject/build-impl.xml.script.CRC32=23300e1b
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/CoreComponentInterfaces/nbproject/project.properties b/CoreComponentInterfaces/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c51692cafc19134f77f8ba341594b3e9ff4df820
--- /dev/null
+++ b/CoreComponentInterfaces/nbproject/project.properties
@@ -0,0 +1,3 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=0.0
diff --git a/CoreComponentInterfaces/nbproject/project.xml b/CoreComponentInterfaces/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3276c14db812e1e9530b2cb25a3bb7edcb1968ed
--- /dev/null
+++ b/CoreComponentInterfaces/nbproject/project.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.28.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.corecomponentinterfaces</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/CoreComponentInterfaces/nbproject/suite.properties b/CoreComponentInterfaces/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/CoreComponentInterfaces/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/Bundle.properties b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..1468238a77e403c3bce95e4f125e5a0af84f2132
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=CoreComponentInterfaces
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/CoreComponentControl.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/CoreComponentControl.java
new file mode 100644
index 0000000000000000000000000000000000000000..79892763e003c5426040ff6a06a254c60bb48fea
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/CoreComponentControl.java
@@ -0,0 +1,75 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.openide.util.Lookup;
+import org.openide.windows.Mode;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * Responsible for opening and closing the core windows when a case is opened and closed.
+ *
+ * @author jantonius
+ */
+public class CoreComponentControl {
+
+    /**
+     * Opens all TopComponent windows that are needed ({@link DataExplorer}, {@link DataResult}, and
+     * {@link DataContent})
+     */
+    public static void openCoreWindows() {
+        // TODO: there has to be a better way to do this.
+
+        // find the data explorer top components
+        Collection<? extends DataExplorer> dataExplorers = Lookup.getDefault().lookupAll(DataExplorer.class);
+        for (DataExplorer de : dataExplorers) {
+            TopComponent explorerWin = de.getTopComponent();
+            Mode m = WindowManager.getDefault().findMode("explorer");
+            m.dockInto(explorerWin); // redock into the explorer mode
+            explorerWin.open(); // open that top component
+        }
+
+        // find the data content top component
+        DataContent dc = Lookup.getDefault().lookup(DataContent.class);
+        TopComponent contentWin = dc.getTopComponent();
+        Mode m = WindowManager.getDefault().findMode("output");
+        m.dockInto(contentWin); // redock into the output mode
+        contentWin.open(); // open that top component
+    }
+
+    /**
+     * Closes all TopComponent windows that needed ({@link DataExplorer}, {@link DataResult}, and
+     * {@link DataContent})
+     */
+    public static void closeCoreWindows() {
+        WindowManager wm = WindowManager.getDefault();
+        Iterator<Mode> iter = (Iterator<Mode>) wm.getModes().iterator();
+
+        while (iter.hasNext()) {
+            Mode mode = iter.next();
+            for (TopComponent tc : mode.getTopComponents()) {
+                tc.close();
+            }
+        }
+    }
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee8e1c78fbbcdc5b325a44b0762bfbb5c7ac23f4
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java
@@ -0,0 +1,44 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import java.beans.PropertyChangeListener;
+import org.openide.windows.TopComponent;
+
+/**
+ * The interface for the "bottom right component" window.
+ *
+ * @author jantonius
+ */
+public interface DataContent extends PropertyChangeListener {
+
+    /**
+     * Sets the "selected" node in this class
+     * @param selectedNode node to use
+     */
+    public void setNode(ContentNode selectedNode);
+
+    /**
+     * Get the TopComponent that is used when displaying this DataContent
+     * @return TopComponent for this DataContent
+     */
+    public TopComponent getTopComponent();
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContentViewer.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContentViewer.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb91673725139d5ca01c7cdfefd68dd706357e7d
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContentViewer.java
@@ -0,0 +1,63 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import java.awt.Component;
+
+/**
+ * Responsible for a tab in the {@link DataContent} component. Displays the
+ * contents of the node passed to {@link setNode(ContentNode)}.
+ */
+public interface DataContentViewer {
+    /**
+     * Sets the node to display in the viewer. When called with null, must
+     * clear all references to previous nodes.
+     */
+    public void setNode(ContentNode selectedNode);
+    
+    /**
+     * Returns the title of this viewer. 
+     */
+    public String getTitle();
+
+    /**
+     * Get new DataContentViewer instance.
+     */
+    public DataContentViewer getInstance();
+    
+    /**
+     * Get Component to display this DataContentViewer
+     */
+    public Component getComponent();
+
+    /**
+     * Resets the component in this viewer.
+     */
+    public void resetComponent();
+
+    /**
+     * Checks whether the given node is supported by the viewer
+     * @param node Node to check for support
+     * @return True if supported, else false
+     */
+    public boolean isSupported(ContentNode node);
+
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataExplorer.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataExplorer.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b0cdffcf1186da53d2d1700854fc45308c43a72
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataExplorer.java
@@ -0,0 +1,39 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import java.beans.PropertyChangeListener;
+import org.openide.windows.TopComponent;
+
+/**
+ * The interface for the "top left component" window.
+ *
+ * @author jantonius
+ */
+public interface DataExplorer extends PropertyChangeListener {
+
+    /**
+     * Gets the TopComponent for rendering this DateExplorer
+     * 
+     * @return the DataExplorer's TopComponent
+     */
+    public TopComponent getTopComponent();
+
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResult.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..743666df89677bffcf3f622e28320543e7b6a2b4
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResult.java
@@ -0,0 +1,55 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+
+/**
+ * The interface for the "top right component" window.
+ *
+ * @author jantonius
+ */
+public interface DataResult {
+
+    /**
+     * Sets the "selected" node in this class.
+     */
+    public void setNode(ContentNode selectedNode);
+
+    /**
+     * Gets the unique TopComponent ID of this class.
+     *
+     * @return preferredID  the unique ID
+     */
+    public String getPreferredID();
+
+    /**
+     * Sets the title of this TopComponent
+     * 
+     * @param title  the given title (String)
+     */
+    public void setTitle(String title);
+
+    /**
+     * Checks if this is the main (uncloseable) instance of DataResult
+     *
+     * @return true if it is the main instance, otherwise false
+     */
+    public boolean isMain();
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ef241e890906e470ef44d620a9e9997ac4fae35
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java
@@ -0,0 +1,64 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.corecomponentinterfaces;
+
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import java.awt.Component;
+
+/**
+ * Interface for the different viewers that show a set of nodes in the DataResult area. 
+ * AbstractDataResultViewer has default implementations for the action handlers. 
+ * 
+ * @author jantonius
+ */
+public interface DataResultViewer {
+    /**
+     * Set the root node to display in this viewer. When called with null, must
+     * clear all references to previous nodes.
+     */
+    public void setNode(ContentNode selectedNode);
+
+    /**
+     * Gets the title of this viewer
+     */
+    public String getTitle();
+
+    /**
+     * Get a new instance of DataResultViewer
+     */
+    public DataResultViewer getInstance();
+    
+    /**
+     * Get Component to display this DataResultViewer
+     */
+    public Component getComponent();
+
+    /**
+     * Resets the viewer.
+     */
+    public void resetComponent();
+
+    /**
+     * Frees the objects that have been allocated by this viewer, in
+     * preparation for permanently disposing of it.
+     */
+    public void clearComponent();
+}
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/layer.xml b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..83b7d8df3b5418f8130b6a36113303672be9fd8b
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/layer.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+</filesystem>
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.html b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.html
new file mode 100644
index 0000000000000000000000000000000000000000..a43d19c45f060c627b436206ea5aedfe3e82711d
--- /dev/null
+++ b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/corecomponentinterfaces/package.html
@@ -0,0 +1,106 @@
+<body>
+<p>This package contains the interface classes that define the core components in Autopsy.  These components are used in the difference zones of the GUI.</p>
+
+<h2>Autopsy Zones</h2>
+
+<p>There are three major zones in the Autopsy UI. The left hand side has the {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer DataExplorer} zone. This area is where you can search for and explore data. It has all of the analysis smarts. An example of a DataExplorer is the directory tree that shows the hierarchy of directories (and hides the files from view).</p>
+
+<p>The DataExplorer area identifies a subset of the data to show the user and passes the data to the {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataResult DataResult}s area in the upper right. In the previous example, the contents of a specific folder would be passed to this area and displayed in a table or thumbnail form.</p>
+
+<p>When a file or object is selected in the DataResult, it is passed to the {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataContent DataContent} zone in the lower right. This is where file content can be viewed in hex form, strings, etc. </p>
+
+
+<h2>Data Flow</h2>
+<h3>Creating Nodes in DataExplorer</h3>
+
+<p>Data flows between the areas inside of a NetBeans node. The DataExplorer modules create the NetBeans nodes. They query the SQLite database or do whatever they want to identify the set of files that are of interest. They create the NetBeans nodes based on Sleuthkit data model objects. See the org.sleuthkit.autopsy.datamodel package for more details on this. </p>
+
+<h3>Getting Nodes to DataResult</h3>
+
+<p>Each DataExplorer TopComponent is responsible for creating its own DataResult TopComponent to display its results. It can choose to re-use the same TopComponent for multiple searches (as DirectoryTree does) or it can choose to make a new one each time (as FileSearch does). The setNode() method on the DataResult object is used to set the root node to display. A dummy root node must be created as the parent if a parent does not already exist. </p>
+
+<p>The DataExplorer is responsible for setting the double-click and right-click actions associated with the node.  The default single click action is to pass data to DataContent.  To override this, you must create a new DataResultViewer instance that overrides the propertyChange() method. The DataExplorer adds actions to wrapping the node in a FilterNode variant. The FilterNode then defines the actions for the node by overriding the getPreferredAction() and getActions() methods.  As an example, org.sleuthkit.autopsy.directorytree.DataResultFilterNode and org.sleuthkit.autopsy.directorytree.DataResultFilterChildren wraps the nodes that are passed over by the DirectoryTree DataExplorer.</p>
+
+DataResult can send data back to its DataExplorer by making a custom action that looks up it's instance (DataExplorer.getInstance()).
+
+<h3>Getting Nodes to DataContent </h3>
+<p> A default DataContent viewer is created when a case is opened. To display the contents of a node, it must be passed to a DataContent instance.  The default single-click behavior of the DataResultViewers is to lookup the default DataContent TopComponent and pass the selected node to it.   See {@link org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer#propertyChange(PropertyChangeEvent) AbstractDataResultViewer.propertyChange()} for details. </p>
+
+<h2>Creating new Functionality</h2>
+
+<h3>Creating a DataExplorer</h3>
+<ol>
+    <li>Create a module from within NetBeans.  It must be dependent on these modules:
+    <ul>
+        <li>Case
+        <li>CoreComponentInterfaces
+        <li>CoreComponents
+        <li>DataModel
+        <li>DialogsAPI (if pop-ups and such are going to be used)
+        <li>Explorer & Property Sheet API
+        <li>Lookup
+        <li>Nodes API
+        <li>Setting API
+        <li>UI Utilities API
+        <li>Utilities API
+        <li>Window System API
+    </ul>
+
+    <li> Create a class that implements {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer DataExplorer}. We have been making the TopComponent class be the one that implements DataExplorer. Register this class as a DataExplorer service provider by specifying "@ServiceProvider(service=DataExplorer.class)" in the class or using layer.xml. 
+    <li>Implement the methods required by the DataExplorer interface. 
+    <li>Register the class to receive property change events from the org.sleuthkit.autopsy.Case module by using its addPropertyChangeListener() method. 
+    <li>Access case data using the org.sleuthkit.autopsy.Case module. 
+    <li>Create Nodes for the data objects using the techniques outlined in the previous section.
+    <li>Wrap the nodes in FilterNodes to define actions as outlined in the previous section. 
+    <li>Send results to DataResults using the techniques outlined in the previous section. 
+</ol>
+
+<h3>Creating a DataResultViewer</h3>
+<p>DataResultTopComponent is the high-level window in the DataResult area.  Each instance of this loads up all instances of DataResultViewers that have been registered with the system. Example viewers include the table and thumbnail views.  If you want to make your own type of viewer, follow the steps below.  Note that the table and thumbnail viewers come with Autopsy by default and can be used by all DataExplorers. </p>
+
+<ol>
+    <li>Create a module from within NetBeans.  It must be dependent on these modules:
+    <ul>
+        <li>Case
+        <li>CoreComponentInterfaces
+        <li>CoreComponents
+        <li>DataModel
+        <li>DialogsAPI (if pop-ups and such are going to be used)
+        <li>Explorer & Property Sheet API
+        <li>Lookup
+        <li>Nodes API
+        <li>Setting API
+        <li>UI Utilities API
+        <li>Utilities API
+        <li>Window System API
+    </ul>
+
+    <li>Make a class that extends {@link org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer#AbstractDataResultViewer() AbstractDataResultViewer} and is registered as a service provider for the {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer DataResultViewer} class by specifying "@ServiceProvider(service = DataResultViewer.class)" or by using layer.xml.  This class will extend JPanel. </li>
+
+    <li>See the previous sections on default actions.</li>
+</ol>
+
+<h3>Creating a DataContentViewer</h3>
+<p>DataContentTopComponent is the high-level window in the DataContent area.  Each instance of this loads up all instances of DataContentViewers that have been registered with the system. Example viewers include the strings and hexdump views.  If you want to make your own type of viewer, follow the steps below.  Note that the strings, hexdump, and image viewers come with Autopsy by default and can be used by all DataExplorers and DataResults. You only need to make a new DataContentViewer if these viewers do not satisfy your needs.</p>
+
+<ol>
+    <li>Create a module from within NetBeans.  It must be dependent on these modules:
+    <ul>
+        <li>Case
+        <li>CoreComponentInterfaces
+        <li>CoreComponents
+        <li>DataModel
+        <li>DialogsAPI (if pop-ups and such are going to be used)
+        <li>Explorer & Property Sheet API
+        <li>Lookup
+        <li>Nodes API
+        <li>Setting API
+        <li>UI Utilities API
+        <li>Utilities API
+        <li>Window System API
+    </ul>
+
+    <li>Make a class that implements {@link org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer DataContentViewer} and is registered as a service provider for DataContentViewer.class by specifying "@ServiceProvider(service = DataContentViewer.class)" or by using layer.xml.  This class must extend JPanel. </li>
+</ol>
+
+</body>
\ No newline at end of file
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/Folder-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/Folder-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..77fb7695deb151621129a32a9d1b377851a65359
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/Folder-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/addImage-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/addImage-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a36d4714ac9db8a3888ab2610bef2ab0cfbb6b7c
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/addImage-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/close-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/close-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5b46fafe588f4b3e296cdfc9b08ff596b9745df
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/close-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon-deleted.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon-deleted.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef172e501b5ff414e7c95d9a96f70e2be2063bfb
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon-deleted.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..add0e90646ddd16d3d53fb96f50523586ca2f74a
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/file-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/folder-icon-deleted.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/folder-icon-deleted.png
new file mode 100644
index 0000000000000000000000000000000000000000..3603190e327ac916f05127dd986307e240568d65
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/folder-icon-deleted.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/hard-drive-icon.jpg b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/hard-drive-icon.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f948ab2ac1492f62a0872e50d516b48c018e3fa4
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/hard-drive-icon.jpg differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/new-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/new-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..14206340e177dc0d06327438ca11fcff38ef706f
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/new-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/open-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/open-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d16e51b68287b10e230b6f6a25efe30e7b7b1dee
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/open-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/save-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/save-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6595171d4df29c3d0917a743e7a7fe116077b1a
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/save-icon.png differ
diff --git a/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/vol-icon.png b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/vol-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..5cd23b971a3687894f31ca04c2cbd9179fb2e57f
Binary files /dev/null and b/CoreComponentInterfaces/src/org/sleuthkit/autopsy/images/vol-icon.png differ
diff --git a/CoreComponents/build.xml b/CoreComponents/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..da573e27291ab1e598f045a8cd97d9b6e00423e0
--- /dev/null
+++ b/CoreComponents/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.corecomponents" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.corecomponents.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ContentViewer_example.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ContentViewer_example.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6d71c4a06c8d63ae581684547870c27ee934552
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ContentViewer_example.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Hex_Content_Viewer.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Hex_Content_Viewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..1766f03aec6f5386d89c497af4b18eb55648ce3e
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Hex_Content_Viewer.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Picture_Content_Viewer.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Picture_Content_Viewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..79914b834bc3870967f8ff166a2637c4621426ec
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Picture_Content_Viewer.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ResultViewer_example.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ResultViewer_example.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd813be8529c1127064b641ec9ab4e552561e7bd
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/ResultViewer_example.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/String_Content_Viewer.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/String_Content_Viewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb0b296174d20a21fd75bd48910711228ba05b0c
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/String_Content_Viewer.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Table_Results_Viewer.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Table_Results_Viewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..10af96f850fe9300ad439bcaa9346bdef325e8c2
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Table_Results_Viewer.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Thumbnail_Results_Viewer.png b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Thumbnail_Results_Viewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..5494c3cadf8212b71c433fb6a0abce5526c29a29
Binary files /dev/null and b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/Thumbnail_Results_Viewer.png differ
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-about.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..c212ee26dd41d1b350b86042945c32c4aaa054c1
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-about.html
@@ -0,0 +1,30 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>About CoreComponents</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About CoreComponents</h2>
+        <p>
+            <!-- TODO describe your module, add more pages... -->
+            Contains data result and data content.
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-hs.xml b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-hs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e69727b5698f9067f5e591bb5a8adb12134fa6f7
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-hs.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN" "http://java.sun.com/products/javahelp/helpset_2_0.dtd">
+<helpset version="2.0">
+    <title>CoreComponents Help</title>
+    <maps>
+        <homeID>org.sleuthkit.autopsy.corecomponents.about</homeID>
+        <mapref location="corecomponents-map.xml"/>
+    </maps>
+    <view mergetype="javax.help.AppendMerge">
+        <name>TOC</name>
+        <label>Table of Contents</label>
+        <type>javax.help.TOCView</type>
+        <data>corecomponents-toc.xml</data>
+    </view>
+    <view mergetype="javax.help.AppendMerge">
+        <name>Index</name>
+        <label>Index</label>
+        <type>javax.help.IndexView</type>
+        <data>corecomponents-idx.xml</data>
+    </view>
+    <view>
+        <name>Search</name>
+        <label>Search</label>
+        <type>javax.help.SearchView</type>
+        <data engine="com.sun.java.help.search.DefaultSearchEngine">JavaHelpSearch</data>
+    </view>
+</helpset>
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml
new file mode 100644
index 0000000000000000000000000000000000000000..651659b2b4e032021b7a0f914d9b42a71f2cd03b
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-idx.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd">
+<index version="2.0">
+    <indexitem text="About CoreComponents" target="org.sleuthkit.autopsy.corecomponents.about"/>
+    <indexitem text="About Result Viewers" target="org.sleuthkit.autopsy.corecomponents.dataresult-about"/>
+    <indexitem text="About Content Viewers" target="org.sleuthkit.autopsy.corecomponents.datacontent-about"/>
+    <indexitem text="About Data Explorers" target="org.sleuthkit.autopsy.corecomponents.dataexplorer-about"/>
+
+    <indexitem text="About Directory Tree" target="org.sleuthkit.autopsy.directorytree.about"/>
+    <indexitem text="How to Open Directory Tree" target="org.sleuthkit.autopsy.directorytree.open-directorytree"/>
+    <indexitem text="How to Use Directory Tree" target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree"/>
+    <indexitem text="Image Details Window" target="org.sleuthkit.autopsy.directorytree.image-details"/>
+    <indexitem text="Volume Details Window" target="org.sleuthkit.autopsy.directorytree.volume-details"/>
+    <indexitem text="File System Details Window" target="org.sleuthkit.autopsy.directorytree.filesystem-details"/>
+
+    <indexitem text="About File Search" target="org.sleuthkit.autopsy.filesearch.about"/>
+    <indexitem text="How to Open File Search" target="org.sleuthkit.autopsy.filesearch.open-filesearch"/>
+    <indexitem text="How to Use File Search" target="org.sleuthkit.autopsy.filesearch.how-to-use-filesearch"/>
+
+    <indexitem text="About Result Viewers" target="org.sleuthkit.autopsy.corecomponents.dataresult-about"/>
+    <indexitem text="Table Results Viewer" target="org.sleuthkit.autopsy.corecomponents.table-results-viewer"/>
+    <indexitem text="Thumbnail Result Viewer" target="org.sleuthkit.autopsy.corecomponents.thumbnail-results-viewer"/>
+
+    <indexitem text="Hex Content Viewer" target="org.sleuthkit.autopsy.corecomponents.hex-content-viewer"/>
+    <indexitem text="String Content Viewer" target="org.sleuthkit.autopsy.corecomponents.string-content-viewer"/>
+    <indexitem text="Picture Content Viewer" target="org.sleuthkit.autopsy.corecomponents.picture-content-viewer"/>
+</index>
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a8379fb4cf936042a2824c7f8da861e7a9f5fb5d
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-map.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE map PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN" "http://java.sun.com/products/javahelp/map_2_0.dtd">
+<map version="2.0">
+    <mapID target="org.sleuthkit.autopsy.directorytree.about" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/directorytree-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.open-directorytree" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/open-directorytree.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/how-to-use-directorytree.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.image-details" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/image-details.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.volume-details" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/volume-details.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.filesystem-details" url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/filesystem-details.html"/>
+
+    <mapID target="org.sleuthkit.autopsy.filesearch.about" url="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/filesearch-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.filesearch.open-filesearch" url="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html"/>
+    <mapID target="org.sleuthkit.autopsy.filesearch.how-to-use-filesearch" url="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/how-to-use-filesearch.html"/>
+
+    <mapID target="org.sleuthkit.autopsy.corecomponents.about" url="corecomponents-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.dataexplorer-about" url="dataexplorer-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.dataresult-about" url="dataresult-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.datacontent-about" url="datacontent-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.table-results-viewer" url="table-results-viewer.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.thumbnail-results-viewer" url="thumbnail-results-viewer.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.hex-content-viewer" url="hex-content-viewer.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.string-content-viewer" url="string-content-viewer.html"/>
+    <mapID target="org.sleuthkit.autopsy.corecomponents.picture-content-viewer" url="picture-content-viewer.html"/>
+</map>
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eb5d8fa3d0e58097a52b0a7b625cf31c971af3b7
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-toc.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE toc PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN" "http://java.sun.com/products/javahelp/toc_2_0.dtd">
+<toc version="2.0">
+    <tocitem text="Data Explorers">
+        <tocitem text="About Data Explorers" target="org.sleuthkit.autopsy.corecomponents.dataexplorer-about"/>
+        <tocitem text="Directory Tree">
+            <tocitem text="About Directory Tree" target="org.sleuthkit.autopsy.directorytree.about"/>
+            <tocitem text="How to Open Directory Tree" target="org.sleuthkit.autopsy.directorytree.open-directorytree"/>
+            <tocitem text="How to Use Directory Tree" target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree"/>
+            <tocitem text="Image Details Window" target="org.sleuthkit.autopsy.directorytree.image-details"/>
+            <tocitem text="Volume Details Window" target="org.sleuthkit.autopsy.directorytree.volume-details"/>
+            <tocitem text="File System Details Window" target="org.sleuthkit.autopsy.directorytree.filesystem-details"/>
+        </tocitem>
+        <tocitem text="File Search">
+            <tocitem text="About File Search" target="org.sleuthkit.autopsy.filesearch.about"/>
+            <tocitem text="How to Open File Search" target="org.sleuthkit.autopsy.filesearch.open-filesearch"/>
+            <tocitem text="How to Use File Search" target="org.sleuthkit.autopsy.filesearch.how-to-use-filesearch"/>
+        </tocitem>
+    </tocitem>
+    <tocitem text="Result Viewers">
+        <tocitem text="About Result Viewers" target="org.sleuthkit.autopsy.corecomponents.dataresult-about"/>
+        <tocitem text="Table Results Viewer">
+            <tocitem text="Table Results Viewer" target="org.sleuthkit.autopsy.corecomponents.table-results-viewer"/>
+        </tocitem>
+        <tocitem text="Thumbnail Results Viewer">
+            <tocitem text="Thumbnail Result Viewer" target="org.sleuthkit.autopsy.corecomponents.thumbnail-results-viewer"/>
+        </tocitem>
+    </tocitem>
+    <tocitem text="Content Viewers">
+        <tocitem text="About Content Viewers" target="org.sleuthkit.autopsy.corecomponents.datacontent-about"/>
+        <tocitem text="Hex Content Viewer">
+            <tocitem text="Hex Content Viewer" target="org.sleuthkit.autopsy.corecomponents.hex-content-viewer"/>
+        </tocitem>
+        <tocitem text="String Content Viewer">
+            <tocitem text="String Content Viewer" target="org.sleuthkit.autopsy.corecomponents.string-content-viewer"/>
+        </tocitem>
+        <tocitem text="Picture Content Viewer">
+            <tocitem text="Picture Content Viewer" target="org.sleuthkit.autopsy.corecomponents.picture-content-viewer"/>
+        </tocitem>
+    </tocitem>
+</toc>
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/datacontent-about.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/datacontent-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..6d648e57ecc4656c58bdf12dedf43cafd5de467b
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/datacontent-about.html
@@ -0,0 +1,45 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>About Content Viewers</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Content Viewers</h2>
+        <p>
+            The "Content Viewers" are in the lower right area of the interface.  They allow you to view raw data.  The data being shown should be have been selected from a <a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html">Result Viewer</a> window (upper right).
+        </p>
+        <p>
+            Currently, there are 3 main tabs on "Content Viewer" window:
+        <ul>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/hex-content-viewer.html">Hex Content Viewer</a></li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/string-content-viewer.html">String Content Viewer</a></li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/picture-content-viewer.html">Picture Content Viewer</a></li>
+            </ul>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of a "Content Viewer" window:
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="ContentViewer_example.png" alt="Example of Content Viewer Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataexplorer-about.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataexplorer-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..39cd795ab6f38eace38789e2fa8ae3cbdd2da023
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataexplorer-about.html
@@ -0,0 +1,35 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Data Explorers</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Data Explorers</h2>
+        <p>
+            The Data Explorer area of the Autopsy interface is the area in the left-hand side.  It provides different methods for finding relevant data. It will publish its results to the upper-right <a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html">Result Viewer</a> area.
+            In general, if you are looking for an 'analysis technique', then this is where you should look.
+        </p>
+        <p>Some example Data Explorers include:</p>
+        <ul>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/directorytree-about.html">Directory Tree</a></li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/filesearch-about.html">File Search</a></li>
+        </ul>
+     </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..b0ff962a20a0de3eff66b529d39fb4ea64e03671
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html
@@ -0,0 +1,64 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>About Result Viewers</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Result Viewers</h2>
+        <p>
+            The Result Viewer windows are in the upper right area of the interface and display the results from a <a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataexplorer-about.html">Data Explorer</a> window.
+            You will have the option in this are to display the results in a variety of formats.
+            Currently, there are 2 main tabs on "Result Viewer" window:
+        <ul>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/table-results-viewer.html">Table Results Viewer</a></li>
+            <li><a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/thumbnail-results-viewer.html">Thumbnail Results Viewer</a></li>
+        </ul>
+        </p>
+
+        <h2>Right Click Functions</h2>
+        <p>
+            Viewers in Result Viewers have some right click function that built in into them:
+            <br><br>
+            &nbsp;&nbsp; 1. Open File in External Viewer<br>
+            &nbsp;&nbsp;&nbsp;&nbsp; This right click function will open the selected node/data in an "external" application. Note: This does not support all file types.
+            <br><br>
+
+            &nbsp;&nbsp; 2. View in New Window<br>
+            &nbsp;&nbsp;&nbsp;&nbsp; This right click function will pop up a new "Content Viewers" window for the selected node/data. You can dock this new window or close it.
+            <br><br>
+
+            &nbsp;&nbsp; 3. Extract<br>
+            &nbsp;&nbsp;&nbsp;&nbsp; This right click function will extract the selected file or directory to any location on the local hard drive (you can specify the location).
+            <br><br>
+
+            &nbsp;&nbsp; 4. View (Hex and String)<br>
+            &nbsp;&nbsp;&nbsp;&nbsp; This right click function will change the active tab on the main "Content Viewers" window to be the selected tab.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of a "Result Viewer" window:
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="ResultViewer_example.png" alt="Example of Result Viewer Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/hex-content-viewer.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/hex-content-viewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..409c33f398303b4bfd9a8102f2201ba8fe27b50e
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/hex-content-viewer.html
@@ -0,0 +1,40 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Hex Content Viewer</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Hex Content Viewer</h2>
+        <p>
+            Hex Content Viewer show you the raw and exact contents of a file. 
+            In this Hex Content Viewer, the data of the file is represented as hexadecimal values grouped in 2 groups of 8 bytes, followed by one group of 16 ASCII characters which are derived from each pair of hex values (each byte).
+            Non-printable ASCII characters and characters that would take more than one character space are typically represented by a dot (".") in the following ASCII field.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of "Hex Content Viewer":
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="Hex_Content_Viewer.png" alt="Example of Hex Content Viewer Tab" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/picture-content-viewer.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/picture-content-viewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..03390f1c6196e692d426fd3e9b1accd97afabf98
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/picture-content-viewer.html
@@ -0,0 +1,40 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Picture Content Viewer</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Picture Content Viewer</h2>
+        <p>
+            Picture Content Viewer will show the actual picture from the picture file. 
+            Currently, Picture Content Viewer only support JPG, GIF, and PNG formats.
+            If you select an non-picture file or an unsupported picture format on the "Result Viewers", this tab will be disabled.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of "Picture Content Viewer":
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="Picture_Content_Viewer.png" alt="Example of Picture Content Viewer Tab" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/string-content-viewer.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/string-content-viewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..7c1286dc30050b5a52bf0bbd1ca88f5d0ff72bb7
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/string-content-viewer.html
@@ -0,0 +1,38 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>String Content Viewer</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>String Content Viewer</h2>
+        <p>
+            Strings Content Viewer just scans the data of the file / folder and show you it for printable ASCII strings of a default length of 4 or more ASCII characters. If the length of printable ASCII is less than 4, it won't show the string.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of "String Content Viewer":
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="String_Content_Viewer.png" alt="Example of String Content Viewer Tab" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/table-results-viewer.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/table-results-viewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..33ec0ce7c22427fc9689ec1ccfe6506b1e145f47
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/table-results-viewer.html
@@ -0,0 +1,39 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Table Results Viewer</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Table Results Viewer</h2>
+        <p>
+            Table Results Viewer displays the catalog as a table with some details (properties) of each file. The properties that it shows are: name, time (modified, changed, accessed, and created), size, flags (directory and meta), mode, user ID, group ID, metadata address, attribute address, and type (directory and meta).
+            Click the Table Viewer tab to select this view.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of a "Table Results Viewer":
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="Table_Results_Viewer.png" alt="Example of Table Result Viewers Tab" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/thumbnail-results-viewer.html b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/thumbnail-results-viewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..2b960b04823ffbe01d0875e5106b87aebc2747ae
--- /dev/null
+++ b/CoreComponents/javahelp/org/sleuthkit/autopsy/corecomponents/docs/thumbnail-results-viewer.html
@@ -0,0 +1,40 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Thumbnail Results Viewer</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Thumbnail Results Viewer</h2>
+        <p>
+            Thumbnail Results Viewer displays the catalog as a table of thumbnail images in adjustable sizes.
+            This viewer only supports picture file(s) (Currently, only supports JPG, GIF, and PNG formats).
+            Click the Thumbnail tab to select this view. 
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's one of the example of "Thumbnail Results Viewer":
+            <br>
+            &nbsp;&nbsp;&nbsp;&nbsp; <img src="Thumbnail_Results_Viewer.png" alt="Example of Thumbnail Results Viewer Tab" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/CoreComponents/manifest.mf b/CoreComponents/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..4bdafdae11fc5973f9f7ef20c2fb9a8c1130e99e
--- /dev/null
+++ b/CoreComponents/manifest.mf
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.corecomponents/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Install: org/sleuthkit/autopsy/corecomponents/Installer.class
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/corecomponents/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corecomponents/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager, org.netbeans.api.javahelp.Help
+
diff --git a/CoreComponents/nbproject/build-impl.xml b/CoreComponents/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6824a818f52a8e940af7f37ff0d4c757db8bcde3
--- /dev/null
+++ b/CoreComponents/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.corecomponents-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/CoreComponents/nbproject/genfiles.properties b/CoreComponents/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..18dcc0bc4d56e97964c558ab5aa2a41858d1e286
--- /dev/null
+++ b/CoreComponents/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=c2ffee94
+build.xml.script.CRC32=d7506201
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=c2ffee94
+nbproject/build-impl.xml.script.CRC32=c3845be2
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/CoreComponents/nbproject/project.properties b/CoreComponents/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..72f5d107d66b75a8492b29e14f879a21ac757b01
--- /dev/null
+++ b/CoreComponents/nbproject/project.properties
@@ -0,0 +1,4 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+javahelp.hs=corecomponents-hs.xml
+spec.version.base=0.0
diff --git a/CoreComponents/nbproject/project.xml b/CoreComponents/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..919dada1fda25c76e3d2ccd95438120ee95ad8f0
--- /dev/null
+++ b/CoreComponents/nbproject/project.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.corecomponents</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.13.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.core</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>2</release-version>
+                        <implementation-version/>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.core.startup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <implementation-version/>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.swing.outline</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.9.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.15.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.28.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.corecomponents</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/CoreComponents/nbproject/suite.properties b/CoreComponents/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/CoreComponents/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b85a8fb9e79ada13a23945f3c6197f8651e5f3e
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java
@@ -0,0 +1,82 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Cursor;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JPanel;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerManager.Provider;
+import org.openide.nodes.Node;
+import org.openide.util.Lookup;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+
+/**
+ * Holds commonalities between all DataResultViewers
+ */
+public abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider, PropertyChangeListener {
+
+    /**
+     * Propagates changes in the current select node from the DataResultViewer to the DataContentTopComponent
+     *
+     * @param evt
+     */
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        String changed = evt.getPropertyName();
+
+        // change that should affect view
+        if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)
+                || changed.equals(ExplorerManager.PROP_NODE_CHANGE)
+                || changed.equals(ExplorerManager.PROP_EXPLORED_CONTEXT)
+                || changed.equals(ExplorerManager.PROP_ROOT_CONTEXT)) {
+
+            // change the cursor to "waiting cursor" for this operation
+            this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+            try {
+                Node originalSelectedNode = this.getOriginalSelectedNode();
+
+                // DataContent is designed to return only the default viewer
+                DataContent dataContent = Lookup.getDefault().lookup(DataContent.class);
+
+                if (originalSelectedNode != null && originalSelectedNode instanceof ContentNode) {
+                    // there's a new/changed node to display
+                    ContentNode newSelectedNode = (ContentNode) originalSelectedNode; // get the selected Node on the table
+                    // push the node to default "DataContent"
+                    dataContent.setNode(newSelectedNode);
+                } else {
+                    // clear the node viewer
+                    dataContent.setNode(null);
+                }
+            } finally {
+                this.setCursor(null);
+            }
+        }
+    }
+
+    /**
+     * Gets the current node, stripping off any FilterNode that this class might
+     * have wrapped it in.
+     * @return
+     */
+    public abstract Node getOriginalSelectedNode();
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..bd2723bcfea0fc795f86922e9fa57233134da18e
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -0,0 +1,66 @@
+CTL_DataContentAction=DataContent
+CTL_DataContentTopComponent=Data Content
+CTL_NodeTableAction=NodeTable
+CTL_NodeTableTopComponent=NodeTable Window
+CTL_HexViewAction=HexView
+CTL_HexViewTopComponent=Hex View
+CTL_StringViewAction=StringView
+CTL_StringViewTopComponent=String View
+CTL_CustomAboutAction=About
+HINT_DataContentTopComponent=This is a DataContent window
+HINT_NodeTableTopComponent=This is a NodeTable window
+HINT_HexViewTopComponent=This is a HexView window
+HINT_StringViewTopComponent=This is a StringView window
+OpenIDE-Module-Name=CoreComponents
+OutputViewPanel.prevPageButton.text=Previous Page
+OutputViewPanel.totalPageLabel.text=100
+OutputViewPanel.ofLabel.text=of
+OutputViewPanel.currentPageLabel.text=1
+OutputViewPanel.pageLabel.text=Page:
+OutputViewPanel.filePathLabel.text=FilePath
+OutputViewPanel.nextPageButton.text=Next Page
+DataResultTopComponent.directoryTablePath.text=directoryPath
+DataContentViewerHex.filePathLabel.text=FilePath
+DataContentViewerHex.pageLabel.text=Page:
+DataContentViewerHex.currentPageLabel.text=1
+DataContentViewerHex.ofLabel.text=of
+DataContentViewerHex.totalPageLabel.text=100
+DataContentViewerHex.prevPageButton.text=
+DataContentViewerHex.nextPageButton.text=
+DataContentViewerString.totalPageLabel.text=100
+DataContentViewerString.prevPageButton.text=
+DataContentViewerString.nextPageButton.text=
+DataContentViewerString.filePathLabel.text=FilePath
+DataContentViewerString.pageLabel.text=Page:
+DataContentViewerString.currentPageLabel.text=1
+DataContentViewerString.ofLabel.text=of
+DataContentViewerHex.pageLabel.text_1=Page:
+DataContentViewerHex.currentPageLabel.text_1=1
+DataContentViewerHex.ofLabel.text_1=of
+DataContentViewerHex.totalPageLabel.text_1=100
+DataContentViewerString.pageLabel.text_1=Page:
+DataContentViewerString.currentPageLabel.text_1=1
+DataContentViewerString.ofLabel.text_1=of
+DataContentViewerString.totalPageLabel.text_1=100
+DataContentViewerPicture.picLabel.text=[Picture goes Here]
+DataContentViewerHex.pageLabel2.text=Page
+DataContentViewerString.pageLabel2.text=Page
+DataResultTopComponent.matchLabel.text=Results
+DataResultTopComponent.numberMatchLabel.text=0
+
+
+# Product Information panel
+LBL_Description=<div style=\"font-size: 12pt; font-family: Verdana, 'Verdana CE',  Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif;\">\n    <b>Product Version:</b> {0} <br><b>Sleuth Kit Version:</b> {7} <br> <b>Java:</b> {1}; {2}<br> <b>System:</b> {3}; {4}; {5}<br><b>Userdir:</b> {6}</div>
+Format_OperatingSystem_Value={0} version {1} running on {2}
+LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE',  Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; "> The Autopsy Forensic Browser is a graphical interface to the command line digital investigation analysis tools in The Sleuth Kit. <br> <br>Copyright &copy; 2003-2011. For more information, please visit: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>. </div>
+URL_ON_IMG=http://www.sleuthkit.org/
+
+
+#SwingBrowser
+LBL_SwingBrowserDescription=Simple HTML Browser based on a Swing component
+MSG_cannot_create_browser=Cannot create Swing HTML Browser.
+Services/Browsers/SwingBrowser.settings=Swing HTML Browser
+LBL_Close=Close
+MNE_Close=C
+ACSN_Close=Close
+ACSD_Close=Close
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/CustomAboutAction.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/CustomAboutAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd691327ca02eedc9b4daa021789110baa825118
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/CustomAboutAction.java
@@ -0,0 +1,57 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Dialog;
+import org.openide.util.NbBundle;
+import org.netbeans.core.actions.AboutAction;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * Action to open custom implementation of the "About" window from the Help menu.
+ */
+public class CustomAboutAction extends AboutAction {
+
+    @Override
+    public void performAction() {
+        Log.noteAction(this.getClass());
+
+        DialogDescriptor descriptor = new DialogDescriptor(
+                new ProductInformationPanel(),
+                NbBundle.getMessage(AboutAction.class, "About_title"),
+                true,
+                new Object[0],
+                null,
+                DialogDescriptor.DEFAULT_ALIGN,
+                null,
+                null);
+        Dialog dlg = null;
+        try {
+            dlg = DialogDisplayer.getDefault().createDialog(descriptor);
+            dlg.setResizable(false);
+            dlg.setVisible(true);
+        } finally {
+            if (dlg != null) {
+                dlg.dispose();
+            }
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.form
new file mode 100644
index 0000000000000000000000000000000000000000..a99a3b3a2b93657cddb646f1787bfc3402408a16
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.form
@@ -0,0 +1,42 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="dataContentTabbedPane" alignment="0" pref="800" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="dataContentTabbedPane" alignment="0" pref="360" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JTabbedPane" name="dataContentTabbedPane">
+      <Properties>
+        <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+          <Color blue="ff" green="ff" red="ff" type="rgb"/>
+        </Property>
+        <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[700, 5]"/>
+        </Property>
+      </Properties>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..080a354f736bbe183398136149ec937f5c81723e
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponent.java
@@ -0,0 +1,336 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Cursor;
+import java.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+import org.openide.util.Lookup;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+
+/**
+ * Top component that organizes all of the data content viewers.  Doing a lookup on this class will
+ * always return the default instance (which is created at startup). 
+ */
+// Registered as a service provider in layer.xml
+public final class DataContentTopComponent extends TopComponent implements DataContent, ChangeListener {
+
+    // reference to the "default" TC that always stays open
+    private static DataContentTopComponent defaultInstance;
+    private ContentNode currentNode;
+    // set to true if this is the TC that always stays open and is the default place to display content
+    private boolean isDefault;
+    // Different DataContentViewers
+    private List<UpdateWrapper> viewers = new ArrayList<UpdateWrapper>();
+    // contains a list of the undocked TCs
+    private static ArrayList<DataContentTopComponent> newWindowList = new ArrayList<DataContentTopComponent>();
+    private static final String PREFERRED_ID = "DataContentTopComponent";
+    private static final String DEFAULT_NAME = NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent");
+    private static final String TOOLTIP_TEXT = NbBundle.getMessage(DataContentTopComponent.class, "HINT_DataContentTopComponent");
+    
+    private DataContentTopComponent(boolean isDefault, String name) {
+        initComponents();
+        setName(name);
+        setToolTipText(TOOLTIP_TEXT);
+
+        this.isDefault = isDefault;
+        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isDefault)); // prevent option to close compoment in GUI
+
+        // set the tab to listen to any tab change (see the "stateChange" method)
+        this.dataContentTabbedPane.addChangeListener(this);
+    }
+
+    private static class UpdateWrapper {
+
+        private DataContentViewer wrapped;
+        private boolean outdated;
+
+        UpdateWrapper(DataContentViewer wrapped) {
+            this.wrapped = wrapped;
+            this.outdated = true;
+        }
+
+        void setNode(ContentNode selectedNode) {
+            this.wrapped.setNode(selectedNode);
+            this.outdated = false;
+        }
+
+        void resetComponent() {
+            this.wrapped.resetComponent();
+            this.outdated = true;
+        }
+
+        boolean isOutdated() {
+            return this.outdated;
+        }
+
+        boolean isSupported(ContentNode node) {
+            return this.wrapped.isSupported(node);
+        }
+    }
+
+    /**
+     * This createInstance method is used to create an undocked instance
+     * for the "View in New Window" feature.
+     * @param filePath path of given file node
+     * @param givenNode node to view content of
+     * @return newly undocked instance
+     */
+    public static DataContentTopComponent createUndocked(String filePath, ContentNode givenNode) {
+
+        DataContentTopComponent dctc = new DataContentTopComponent(false, filePath);
+        dctc.componentOpened();
+        dctc.setNode(givenNode);
+
+        newWindowList.add(dctc);
+
+        return dctc;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        dataContentTabbedPane = new javax.swing.JTabbedPane();
+
+        dataContentTabbedPane.setBackground(new java.awt.Color(255, 255, 255));
+        dataContentTabbedPane.setPreferredSize(new java.awt.Dimension(700, 5));
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(dataContentTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 800, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(dataContentTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JTabbedPane dataContentTabbedPane;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized defaultInstance.
+     * To obtain the singleton instance, use {@link #findInstance}.
+     */
+    public static synchronized DataContentTopComponent getDefault() {
+        if (defaultInstance == null) {
+            defaultInstance = new DataContentTopComponent(true, DEFAULT_NAME);
+        }
+        return defaultInstance;
+    }
+
+    /**
+     * Obtain the default DataContentTopComponent defaultInstance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized DataContentTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            Logger.getLogger(DataContentTopComponent.class.getName()).warning(
+                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof DataContentTopComponent) {
+            return (DataContentTopComponent) win;
+        }
+        Logger.getLogger(DataContentTopComponent.class.getName()).warning(
+                "There seem to be multiple components with the '" + PREFERRED_ID
+                + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    public void componentOpened() {
+        // Add all the DataContentViewer to the tabbed pannel.
+        // (Only when the it's opened at the first time: tabCount = 0)
+        int totalTabs = dataContentTabbedPane.getTabCount();
+        if (totalTabs == 0) {
+            // find all dataContentViewer and add them to the tabbed pane
+            for (DataContentViewer factory : Lookup.getDefault().lookupAll(DataContentViewer.class)) {
+                DataContentViewer dcv = factory.getInstance();
+                this.viewers.add(new UpdateWrapper(dcv));
+                dataContentTabbedPane.addTab(dcv.getTitle(), dcv.getComponent());
+            }
+        }
+
+        resetTabs(currentNode);
+    }
+
+    @Override
+    public void componentClosed() {
+        
+        // clear all set nodes
+        for(UpdateWrapper dcv : viewers) {
+            dcv.setNode(null);
+        }
+        
+        if (!this.isDefault) {
+            newWindowList.remove(this);
+        }
+    }
+
+    @Override
+    protected String preferredID() {
+        if (this.isDefault) {
+            return PREFERRED_ID;
+        } else {
+            return this.getName();
+        }
+    }
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            // set the file path
+            if (selectedNode == null) {
+                setName(NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent"));
+            } else {
+                String path = DataConversion.getformattedPath(selectedNode.getDisplayPath(), 0);
+                setName(path);
+            }
+
+            currentNode = selectedNode;
+
+            resetTabs(selectedNode);
+
+            // set the display on the current active tab
+            int currentActiveTab = dataContentTabbedPane.getSelectedIndex();
+            if (currentActiveTab != -1) {
+                UpdateWrapper dcv = viewers.get(currentActiveTab);
+                dcv.setNode(selectedNode);
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    @Override
+    public boolean canClose() {
+        return (!this.isDefault) || !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+    }
+
+    @Override
+    public void stateChanged(ChangeEvent evt) {
+        JTabbedPane pane = (JTabbedPane) evt.getSource();
+
+        // Get and set current selected tab
+        int currentTab = pane.getSelectedIndex();
+        if (currentTab != -1) {
+            UpdateWrapper dcv = viewers.get(currentTab);
+            if (dcv.isOutdated()) {
+                // change the cursor to "waiting cursor" for this operation
+                this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                try {
+                    dcv.setNode(currentNode);
+                } finally {
+                    this.setCursor(null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Resets the tabs based on the selected Node. If the selected node is null
+     * or not supported, disable that tab as well.
+     *
+     * @param selectedNode  the selected content Node
+     */
+    public void resetTabs(ContentNode selectedNode) {
+
+        int totalTabs = dataContentTabbedPane.getTabCount();
+
+        if (totalTabs > 0) { // make sure there are tabs to reset
+            int tempIndex = dataContentTabbedPane.getSelectedIndex();
+            for (int i = 0; i < totalTabs; i++) {
+                UpdateWrapper dcv = viewers.get(i);
+                dcv.resetComponent();
+
+                // disable an unsupported tab (ex: picture viewer)
+                if (!dcv.isSupported(selectedNode)) {
+                    dataContentTabbedPane.setEnabledAt(i, false);
+
+                    // change the tab selection if it's the current selection
+                    if (tempIndex == i) {
+                        if (i > 0) {
+                            dataContentTabbedPane.setSelectedIndex(0);
+                        } else {
+                            dataContentTabbedPane.setSelectedIndex(1);
+                        }
+                    }
+                } else {
+                    dataContentTabbedPane.setEnabledAt(i, true);
+                }
+            }
+            int newIndex = dataContentTabbedPane.getSelectedIndex();
+            // set the display of the tab
+            viewers.get(newIndex).setNode(selectedNode);
+        }
+    }
+
+    /**
+     * Get the tab pane
+     * @return tab pane with individual {@link DataContentViewer}s
+     */
+    public JTabbedPane getTabPanels() {
+        return this.dataContentTabbedPane;
+    }
+
+    @Override
+    public TopComponent getTopComponent() {
+        return this;
+    }
+
+    /**
+     * Returns a list of the non-default (main) TopComponents
+     * @return
+     */
+    public static List<DataContentTopComponent> getNewWindowList() {
+        return newWindowList;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentSettings.xml b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentSettings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c48ecdaf2861cb1c7936db0ff8746cd285d9eaee
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentSettings.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="org.sleuthkit.autopsy.corecomponents" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="org.sleuthkit.autopsy.corecomponents.DataContentTopComponent"/>
+    <instance class="org.sleuthkit.autopsy.corecomponents.DataContentTopComponent" method="getDefault"/>
+</settings>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentWstcref.xml b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentWstcref.xml
new file mode 100644
index 0000000000000000000000000000000000000000..abd7e0f000dc0f3e5cb072ca2fbdc407629dd39b
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentTopComponentWstcref.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="org.sleuthkit.autopsy.corecomponents" spec="1.0"/>
+    <tc-id id="DataContentTopComponent"/>
+    <state opened="false"/>
+</tc-ref>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form
new file mode 100644
index 0000000000000000000000000000000000000000..d454394bd56896b5b6cf453625cc4983474e7496
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.form
@@ -0,0 +1,182 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="622" max="32767" attributes="0"/>
+          <Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+                  <Component id="hexViewerPanel" max="32767" attributes="0"/>
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="411" max="32767" attributes="0"/>
+          <Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+                  <Component id="hexViewerPanel" max="32767" attributes="0"/>
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="hexViewerPanel">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="pageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Component id="currentPageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="ofLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="totalPageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="51" max="-2" attributes="0"/>
+                  <Component id="pageLabel2" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="prevPageButton" min="-2" pref="27" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="nextPageButton" min="-2" pref="26" max="-2" attributes="0"/>
+                  <EmptySpace pref="374" max="32767" attributes="0"/>
+              </Group>
+              <Component id="jScrollPane1" alignment="0" pref="622" max="32767" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="pageLabel" min="-2" max="-2" attributes="0"/>
+                      <Group type="103" alignment="0" groupAlignment="3" attributes="0">
+                          <Component id="currentPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="ofLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="totalPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <Component id="pageLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="nextPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
+                      <Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+                  <Component id="jScrollPane1" pref="388" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+          <Properties>
+            <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+              <Color blue="ff" green="ff" red="ff" type="rgb"/>
+            </Property>
+          </Properties>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTextPane" name="outputViewPane">
+              <Properties>
+                <Property name="editable" type="boolean" value="false"/>
+                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+                  <Font name="Courier New" size="11" style="0"/>
+                </Property>
+                <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[700, 20]"/>
+                </Property>
+                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[700, 400]"/>
+                </Property>
+              </Properties>
+              <AuxValues>
+                <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JTextPane(){&#xd;&#xa;    public boolean getScrollableTracksViewportWidth() {&#xd;&#xa;    return (getSize().width &lt; 700);&#xd;&#xa;}};"/>
+                <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="this.outputViewPane.setBackground(new java.awt.Color(255, 255, 255)); // to make sure the background color is white"/>
+              </AuxValues>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JLabel" name="totalPageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.totalPageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="ofLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.ofLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="currentPageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.currentPageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="pageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.pageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JButton" name="prevPageButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/arrow_left.gif"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="prevPageButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="nextPageButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/arrow_right.gif"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nextPageButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JLabel" name="pageLabel2">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerHex.pageLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8995a7cfbf475325c1ae046ec10d0ee76b2d9bd
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
@@ -0,0 +1,328 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JTextPane;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * Hex view of file contents.
+ */
+@ServiceProvider(service = DataContentViewer.class)
+public class DataContentViewerHex extends javax.swing.JPanel implements DataContentViewer {
+
+    private static long currentOffset = 0;
+    private static long pageLength = 10240;
+    private static int currentPage = 1;
+    private Content dataSource;
+    // for error handling
+    private String className = this.getClass().toString();
+
+    /** Creates new form DataContentViewerHex */
+    public DataContentViewerHex() {
+        initComponents();
+        this.resetComponent();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        hexViewerPanel = new javax.swing.JPanel();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        outputViewPane = new JTextPane(){
+            public boolean getScrollableTracksViewportWidth() {
+                return (getSize().width < 700);
+            }};
+            this.outputViewPane.setBackground(new java.awt.Color(255, 255, 255)); // to make sure the background color is white
+            totalPageLabel = new javax.swing.JLabel();
+            ofLabel = new javax.swing.JLabel();
+            currentPageLabel = new javax.swing.JLabel();
+            pageLabel = new javax.swing.JLabel();
+            prevPageButton = new javax.swing.JButton();
+            nextPageButton = new javax.swing.JButton();
+            pageLabel2 = new javax.swing.JLabel();
+
+            jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
+
+            outputViewPane.setEditable(false);
+            outputViewPane.setFont(new java.awt.Font("Courier New", 0, 11)); // NOI18N
+            outputViewPane.setMinimumSize(new java.awt.Dimension(700, 20));
+            outputViewPane.setPreferredSize(new java.awt.Dimension(700, 400));
+            jScrollPane1.setViewportView(outputViewPane);
+
+            totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.totalPageLabel.text_1")); // NOI18N
+
+            ofLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.ofLabel.text_1")); // NOI18N
+
+            currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.currentPageLabel.text_1")); // NOI18N
+
+            pageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.pageLabel.text_1")); // NOI18N
+
+            prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/arrow_left.gif"))); // NOI18N
+            prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.prevPageButton.text")); // NOI18N
+            prevPageButton.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent evt) {
+                    prevPageButtonActionPerformed(evt);
+                }
+            });
+
+            nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/arrow_right.gif"))); // NOI18N
+            nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.nextPageButton.text")); // NOI18N
+            nextPageButton.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent evt) {
+                    nextPageButtonActionPerformed(evt);
+                }
+            });
+
+            pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.pageLabel2.text")); // NOI18N
+
+            javax.swing.GroupLayout hexViewerPanelLayout = new javax.swing.GroupLayout(hexViewerPanel);
+            hexViewerPanel.setLayout(hexViewerPanelLayout);
+            hexViewerPanelLayout.setHorizontalGroup(
+                hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                .addGroup(hexViewerPanelLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(pageLabel)
+                    .addGap(18, 18, 18)
+                    .addComponent(currentPageLabel)
+                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                    .addComponent(ofLabel)
+                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                    .addComponent(totalPageLabel)
+                    .addGap(51, 51, 51)
+                    .addComponent(pageLabel2)
+                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                    .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                    .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addContainerGap(374, Short.MAX_VALUE))
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
+            );
+            hexViewerPanelLayout.setVerticalGroup(
+                hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                .addGroup(hexViewerPanelLayout.createSequentialGroup()
+                    .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                        .addComponent(pageLabel)
+                        .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                            .addComponent(currentPageLabel)
+                            .addComponent(ofLabel)
+                            .addComponent(totalPageLabel))
+                        .addComponent(pageLabel2)
+                        .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGap(0, 0, 0)
+                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE))
+            );
+
+            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+            this.setLayout(layout);
+            layout.setHorizontalGroup(
+                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                .addGap(0, 622, Short.MAX_VALUE)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(0, 0, 0)
+                        .addComponent(hexViewerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addGap(0, 0, 0)))
+            );
+            layout.setVerticalGroup(
+                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                .addGap(0, 411, Short.MAX_VALUE)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(0, 0, 0)
+                        .addComponent(hexViewerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addGap(0, 0, 0)))
+            );
+        }// </editor-fold>//GEN-END:initComponents
+
+    private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset -= pageLength;
+        currentPage = currentPage - 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false);
+    }//GEN-LAST:event_prevPageButtonActionPerformed
+
+    private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset += pageLength;
+        currentPage = currentPage + 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false);
+    }//GEN-LAST:event_nextPageButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel currentPageLabel;
+    private javax.swing.JPanel hexViewerPanel;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JButton nextPageButton;
+    private javax.swing.JLabel ofLabel;
+    private javax.swing.JTextPane outputViewPane;
+    private javax.swing.JLabel pageLabel;
+    private javax.swing.JLabel pageLabel2;
+    private javax.swing.JButton prevPageButton;
+    private javax.swing.JLabel totalPageLabel;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Sets the DataView (The tabbed panel)
+     *
+     * @param dataSource  the content that want to be shown
+     * @param offset      the starting offset
+     * @param reset       whether to reset the dataView or not
+     */
+    public void setDataView(Content dataSource, long offset, boolean reset) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            try {
+                this.dataSource = dataSource;
+                byte[] data;
+
+                if (!reset && dataSource.getSize() > 0) {
+                    data = dataSource.read(offset, pageLength); // read the data
+                } else {
+                    // empty file
+                    data = null;
+                }
+
+                // I set the -1 to for empty node or directory
+                if (reset) {
+                    data = null;
+                }
+
+                // set the data on the bottom and show it
+                String text = "";
+                Boolean setVisible = false;
+
+                if (data != null) {
+                    text = DataConversion.getString(data, 4);
+                    setVisible = true;
+                }
+
+                // disable or enable the next button
+                if (!reset && offset + pageLength < dataSource.getSize()) {
+                    nextPageButton.setEnabled(true);
+                } else {
+                    nextPageButton.setEnabled(false);
+                }
+
+                if (offset == 0) {
+                    prevPageButton.setEnabled(false);
+                    currentPage = 1; // reset the page number
+                } else {
+                    prevPageButton.setEnabled(true);
+                }
+
+                if (setVisible) {
+                    int totalPage = (int) (dataSource.getSize() / pageLength) + 1;
+                    totalPageLabel.setText(Integer.toString(totalPage));
+                    currentPageLabel.setText(Integer.toString(currentPage));
+                    setComponentsVisibility(true); // shows the components that not needed
+
+                    // set the output view
+                    outputViewPane.setText(DataConversion.byteArrayToHex(data, pageLength, offset, outputViewPane.getFont()));
+                } else {
+                    // reset or hide the labels
+                    totalPageLabel.setText("");
+                    currentPageLabel.setText("");
+                    outputViewPane.setText(""); // reset the output view
+                    setComponentsVisibility(false); // hides the components that not needed
+                }
+
+                outputViewPane.moveCaretPosition(0);
+            } catch (TskException ex) {
+                // TODO: maybe make this error bubble up further
+                Logger.getLogger(this.className).log(Level.WARNING, "Error while trying to show the hex content.", ex);
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        if (selectedNode != null) {
+            this.setDataView(selectedNode.getContent(), 0, false);
+        } else {
+            this.setDataView(null, 0, true);
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        return "Hex View";
+    }
+
+    @Override
+    public DataContentViewer getInstance() {
+        return new DataContentViewerHex();
+    }
+
+    @Override
+    public void resetComponent() {
+        // clear / reset the fields
+        this.dataSource = null;
+        currentPageLabel.setText("");
+        totalPageLabel.setText("");
+        prevPageButton.setEnabled(false);
+        nextPageButton.setEnabled(false);
+        setComponentsVisibility(false); // hides the components that not needed
+    }
+
+    /**
+     * To set the visibility of specific components in this class.
+     *
+     * @param isVisible  whether to show or hide the specific components
+     */
+    private void setComponentsVisibility(boolean isVisible) {
+        currentPageLabel.setVisible(isVisible);
+        totalPageLabel.setVisible(isVisible);
+        ofLabel.setVisible(isVisible);
+        prevPageButton.setVisible(isVisible);
+        nextPageButton.setVisible(isVisible);
+        pageLabel.setVisible(isVisible);
+        pageLabel2.setVisible(isVisible);
+    }
+
+    @Override
+    public boolean isSupported(ContentNode node) {
+        return true;
+    }
+
+    @Override
+    public Component getComponent() {
+        return this;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.form
new file mode 100644
index 0000000000000000000000000000000000000000..43f9a88aea35ef10586709aa4199921469dc357f
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.form
@@ -0,0 +1,45 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="picViewerScrollPanel" alignment="0" pref="589" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="picViewerScrollPanel" alignment="0" pref="382" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="picViewerScrollPanel">
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="picLabel">
+          <Properties>
+            <Property name="horizontalAlignment" type="int" value="0"/>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerPicture.picLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="horizontalTextPosition" type="int" value="0"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java
new file mode 100644
index 0000000000000000000000000000000000000000..5defaf15ef7a9e15c60ba1314fa73b41b4383de3
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java
@@ -0,0 +1,156 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Image;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.imageio.ImageIO;
+import javax.swing.JPanel;
+import org.openide.nodes.Node;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * File content viewer capable of displaying some image formats.
+ */
+@ServiceProvider(service = DataContentViewer.class)
+public class DataContentViewerPicture extends javax.swing.JPanel implements DataContentViewer {
+
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** Creates new form DataContentViewerPicture */
+    public DataContentViewerPicture() {
+        initComponents();
+        this.resetComponent();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        picViewerScrollPanel = new javax.swing.JScrollPane();
+        picLabel = new javax.swing.JLabel();
+
+        picLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+        picLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerPicture.class, "DataContentViewerPicture.picLabel.text")); // NOI18N
+        picLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        picViewerScrollPanel.setViewportView(picLabel);
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(picViewerScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(picViewerScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel picLabel;
+    private javax.swing.JScrollPane picViewerScrollPanel;
+    // End of variables declaration//GEN-END:variables
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            if (selectedNode != null) {
+                try {
+                    // read the byte of the image file
+                    byte[] dataSource = selectedNode.getContent().read(0, selectedNode.getContent().getSize());
+
+                    // create the input stream for the content
+                    InputStream is = new ByteArrayInputStream(dataSource);
+
+                    Image test = ImageIO.read(is); // create the image
+
+                    this.picLabel.setIcon(new javax.swing.ImageIcon(test)); // show the file
+
+
+                } catch (TskException ex) {
+                    // TODO: maybe make errors bubble
+                    Logger.getLogger(this.className).log(Level.WARNING, "Error while trying to display the picture content.", ex);
+                } catch (Exception ex) {
+                    Logger.getLogger(this.className).log(Level.WARNING, "Error while trying to display the picture content.", ex);
+                }
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        return "Picture View";
+    }
+
+    @Override
+    public DataContentViewer getInstance() {
+        return new DataContentViewerPicture();
+    }
+
+    @Override
+    public void resetComponent() {
+        this.picLabel.setText("");
+        //this.picLabel.setIcon(null);
+    }
+
+    @Override
+    public boolean isSupported(ContentNode cNode) {
+        Node node = (Node) cNode;
+
+        if (node != null) {
+            // Note: only supports JPG, GIF, and PNG for now
+            return node.getDisplayName().toLowerCase().endsWith(".jpg")
+                    || node.getDisplayName().toLowerCase().endsWith(".jpeg")
+                    || node.getDisplayName().toLowerCase().endsWith(".jpe")
+                    || node.getDisplayName().toLowerCase().endsWith(".jfif")
+                    || node.getDisplayName().toLowerCase().endsWith(".gif")
+                    || node.getDisplayName().toLowerCase().endsWith(".bmp")
+                    || //node.getDisplayName().toLowerCase().endsWith(".tif") ||
+                    //node.getDisplayName().toLowerCase().endsWith(".tiff") ||
+                    //node.getDisplayName().toLowerCase().endsWith(".tga") ||
+                    node.getDisplayName().toLowerCase().endsWith(".png");
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public Component getComponent() {
+        return this;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.form
new file mode 100644
index 0000000000000000000000000000000000000000..8ca239c65db4d1112c8cf2feca32217e041e821c
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.form
@@ -0,0 +1,156 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="1" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="1" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="pageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Component id="currentPageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="ofLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="totalPageLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="50" max="-2" attributes="0"/>
+                  <Component id="pageLabel2" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="prevPageButton" min="-2" pref="27" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="nextPageButton" min="-2" pref="26" max="-2" attributes="0"/>
+                  <EmptySpace pref="375" max="32767" attributes="0"/>
+              </Group>
+              <Component id="jScrollPane1" alignment="1" pref="622" max="32767" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="103" alignment="0" groupAlignment="3" attributes="0">
+                          <Component id="pageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="currentPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="ofLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="totalPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <Component id="pageLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="nextPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
+                      <Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+                  <Component id="jScrollPane1" pref="401" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTextPane" name="outputViewPane">
+              <Properties>
+                <Property name="editable" type="boolean" value="false"/>
+                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+                  <Font name="Courier New" size="11" style="0"/>
+                </Property>
+                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[700, 400]"/>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JLabel" name="totalPageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.totalPageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="ofLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.ofLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="currentPageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.currentPageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="pageLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.pageLabel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JButton" name="nextPageButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/arrow_right.gif"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nextPageButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JLabel" name="pageLabel2">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.pageLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JButton" name="prevPageButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/arrow_left.gif"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerString.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="prevPageButtonActionPerformed"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java
new file mode 100644
index 0000000000000000000000000000000000000000..990ac9ac36384213640389806d2246aff7181ae4
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java
@@ -0,0 +1,307 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * Viewer displays strings extracted from contents.
+ */
+@ServiceProvider(service = DataContentViewer.class)
+public class DataContentViewerString extends javax.swing.JPanel implements DataContentViewer {
+
+    private static long currentOffset = 0;
+    private static long pageLength = 10240;
+    private static int currentPage = 1;
+    private Content dataSource;
+    // for error handling
+    private String className = this.getClass().toString();
+
+    /** Creates new form DataContentViewerString */
+    public DataContentViewerString() {
+        initComponents();
+        this.resetComponent();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        outputViewPane = new javax.swing.JTextPane();
+        totalPageLabel = new javax.swing.JLabel();
+        ofLabel = new javax.swing.JLabel();
+        currentPageLabel = new javax.swing.JLabel();
+        pageLabel = new javax.swing.JLabel();
+        nextPageButton = new javax.swing.JButton();
+        pageLabel2 = new javax.swing.JLabel();
+        prevPageButton = new javax.swing.JButton();
+
+        outputViewPane.setEditable(false);
+        outputViewPane.setFont(new java.awt.Font("Courier New", 0, 11)); // NOI18N
+        outputViewPane.setPreferredSize(new java.awt.Dimension(700, 400));
+        jScrollPane1.setViewportView(outputViewPane);
+
+        totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.totalPageLabel.text_1")); // NOI18N
+
+        ofLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.ofLabel.text_1")); // NOI18N
+
+        currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.currentPageLabel.text_1")); // NOI18N
+
+        pageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.pageLabel.text_1")); // NOI18N
+
+        nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/arrow_right.gif"))); // NOI18N
+        nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.nextPageButton.text")); // NOI18N
+        nextPageButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                nextPageButtonActionPerformed(evt);
+            }
+        });
+
+        pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.pageLabel2.text")); // NOI18N
+
+        prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/arrow_left.gif"))); // NOI18N
+        prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerString.class, "DataContentViewerString.prevPageButton.text")); // NOI18N
+        prevPageButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                prevPageButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(pageLabel)
+                .addGap(18, 18, 18)
+                .addComponent(currentPageLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(ofLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(totalPageLabel)
+                .addGap(50, 50, 50)
+                .addComponent(pageLabel2)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(375, Short.MAX_VALUE))
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                        .addComponent(pageLabel)
+                        .addComponent(currentPageLabel)
+                        .addComponent(ofLabel)
+                        .addComponent(totalPageLabel))
+                    .addComponent(pageLabel2)
+                    .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addGap(0, 0, 0)
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset -= pageLength;
+        currentPage = currentPage - 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false);
+    }//GEN-LAST:event_prevPageButtonActionPerformed
+
+    private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset += pageLength;
+        currentPage = currentPage + 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false);
+    }//GEN-LAST:event_nextPageButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel currentPageLabel;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JButton nextPageButton;
+    private javax.swing.JLabel ofLabel;
+    private javax.swing.JTextPane outputViewPane;
+    private javax.swing.JLabel pageLabel;
+    private javax.swing.JLabel pageLabel2;
+    private javax.swing.JButton prevPageButton;
+    private javax.swing.JLabel totalPageLabel;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Sets the DataView (The tabbed panel)
+     *
+     * @param dataSource  the content that want to be shown
+     * @param offset      the starting offset
+     * @param reset       whether to reset the dataView or not
+     */
+    public void setDataView(Content dataSource, long offset, boolean reset) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            try {
+                this.dataSource = dataSource;
+                byte[] data;
+
+                if (!reset && dataSource.getSize() > 0) {
+                    data = dataSource.read(offset, pageLength); // read the data
+                } else {
+                    // empty file
+                    data = null;
+                }
+
+                // I set the -1 to for empty node or directory
+                if (reset) {
+                    data = null;
+                }
+
+                // set the data on the bottom and show it
+                String text = "";
+                Boolean setVisible = false;
+
+                if (data != null) {
+                    text = DataConversion.getString(data, 4);
+                    setVisible = true;
+                }
+
+                // disable or enable the next button
+                if (!reset && offset + pageLength < dataSource.getSize()) {
+                    nextPageButton.setEnabled(true);
+                } else {
+                    nextPageButton.setEnabled(false);
+                }
+
+                if (offset == 0) {
+                    prevPageButton.setEnabled(false);
+                    currentPage = 1; // reset the page number
+                } else {
+                    prevPageButton.setEnabled(true);
+                }
+
+                if (setVisible) {
+                    int totalPage = (int) (dataSource.getSize() / pageLength) + 1;
+                    totalPageLabel.setText(Integer.toString(totalPage));
+                    currentPageLabel.setText(Integer.toString(currentPage));
+                    outputViewPane.setText(text); // set the output view
+                    setComponentsVisibility(true); // shows the components that not needed
+                } else {
+                    // reset or hide the labels
+                    totalPageLabel.setText("");
+                    currentPageLabel.setText("");
+                    outputViewPane.setText(""); // reset the output view
+                    setComponentsVisibility(false); // hides the components that not needed
+                }
+                outputViewPane.moveCaretPosition(0);
+            } catch (TskException ex) {
+                Logger logger = Logger.getLogger(this.className);
+                logger.log(Level.WARNING, "Error while trying to show the String content.", ex);
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    /**
+     * To set the visibility of specific components in this class.
+     *
+     * @param isVisible  whether to show or hide the specific components
+     */
+    private void setComponentsVisibility(boolean isVisible) {
+        currentPageLabel.setVisible(isVisible);
+        totalPageLabel.setVisible(isVisible);
+        ofLabel.setVisible(isVisible);
+        prevPageButton.setVisible(isVisible);
+        nextPageButton.setVisible(isVisible);
+        pageLabel.setVisible(isVisible);
+        pageLabel2.setVisible(isVisible);
+    }
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        if (selectedNode != null) {
+            this.setDataView(selectedNode.getContent(), 0, false);
+        } else {
+            this.setDataView(null, 0, true);
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        return "String View";
+    }
+
+    @Override
+    public DataContentViewer getInstance() {
+        return new DataContentViewerString();
+    }
+
+    @Override
+    public void resetComponent() {
+        // clear / reset the fields
+        this.dataSource = null;
+        currentPageLabel.setText("");
+        totalPageLabel.setText("");
+        prevPageButton.setEnabled(false);
+        nextPageButton.setEnabled(false);
+        setComponentsVisibility(false); // hides the components that not needed
+    }
+
+    @Override
+    public boolean isSupported(ContentNode node) {
+        return true;
+    }
+
+    @Override
+    public Component getComponent() {
+        return this;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.form
new file mode 100644
index 0000000000000000000000000000000000000000..13b479834a3a7ebad4f9dad886e3850f9511a24f
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.form
@@ -0,0 +1,72 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="1" attributes="0">
+              <Component id="directoryTablePath" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="855" max="32767" attributes="0"/>
+              <Component id="numberMatchLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="matchLabel" min="-2" max="-2" attributes="0"/>
+          </Group>
+          <Component id="dataResultTabbedPanel" alignment="0" pref="967" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="matchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="numberMatchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Component id="directoryTablePath" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+              <Component id="dataResultTabbedPanel" pref="565" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="directoryTablePath">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.directoryTablePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="matchLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.matchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="numberMatchLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.numberMatchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Container class="javax.swing.JTabbedPane" name="dataResultTabbedPanel">
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f893aa22c60950261039dfd11cdbf77d0c43c1df
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultTopComponent.java
@@ -0,0 +1,358 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Cursor;
+import java.beans.PropertyChangeListener;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.nodes.Node;
+import org.openide.util.Lookup;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+
+/**
+ * Top component which displays something.
+ */
+public final class DataResultTopComponent extends TopComponent implements DataResult, ChangeListener {
+
+    private ContentNode rootNode;
+    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+    private boolean isMain;
+    /** path to the icon used by the component and its open action */
+//    static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
+    private static String PREFERRED_ID = "NodeTableTopComponent";
+    /**
+     * Name of property change fired when a file search result is closed
+     */
+    public static String REMOVE_FILESEARCH = "RemoveFileSearchTopComponent";
+    // Different DataResultsViewers
+    private List<UpdateWrapper> viewers = new ArrayList<UpdateWrapper>();
+
+    public DataResultTopComponent(boolean isMain, String title) {
+        initComponents();
+        setToolTipText(NbBundle.getMessage(DataResultTopComponent.class, "HINT_NodeTableTopComponent"));
+
+        setTitle(title); // set the title
+        this.isMain = isMain;
+        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isMain)); // set option to close compoment in GUI
+
+        this.dataResultTabbedPanel.addChangeListener(this);
+    }
+
+    private static class UpdateWrapper {
+
+        private DataResultViewer wrapped;
+        private boolean outdated;
+
+        UpdateWrapper(DataResultViewer wrapped) {
+            this.wrapped = wrapped;
+            this.outdated = true;
+        }
+
+        void setNode(ContentNode selectedNode) {
+            this.wrapped.setNode(selectedNode);
+            this.outdated = false;
+        }
+
+        void resetComponent() {
+            this.wrapped.resetComponent();
+            this.outdated = true;
+        }
+
+        void clearComponent() {
+            this.wrapped.clearComponent();
+            this.outdated = true;
+        }
+
+        boolean isOutdated() {
+            return this.outdated;
+        }
+    }
+
+    /**
+     * Creates a new non-default DataResult component
+     *
+     * @param title Title of the component window
+     * @param pathText Descriptive text about the source of the nodes displayed
+     * @param givenNode The new root node
+     * @param totalMatches Cardinality of root node's children
+     * @return
+     */
+    public static DataResultTopComponent createInstance(String title, String pathText, Node givenNode, int totalMatches) {
+        DataResultTopComponent newDataResult = new DataResultTopComponent(false, title);
+
+        newDataResult.numberMatchLabel.setText(Integer.toString(totalMatches));
+
+        newDataResult.open(); // open it first so the component can be initialized
+
+        // set the tree table view
+        newDataResult.setNode((ContentNode) givenNode);
+        newDataResult.directoryTablePath.setText(pathText);
+
+        return newDataResult;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        directoryTablePath = new javax.swing.JLabel();
+        matchLabel = new javax.swing.JLabel();
+        numberMatchLabel = new javax.swing.JLabel();
+        dataResultTabbedPanel = new javax.swing.JTabbedPane();
+
+        org.openide.awt.Mnemonics.setLocalizedText(directoryTablePath, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.directoryTablePath.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(matchLabel, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.matchLabel.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(numberMatchLabel, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.numberMatchLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                .addComponent(directoryTablePath)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 855, Short.MAX_VALUE)
+                .addComponent(numberMatchLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(matchLabel))
+            .addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 967, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                        .addComponent(matchLabel)
+                        .addComponent(numberMatchLabel))
+                    .addComponent(directoryTablePath))
+                .addGap(0, 0, 0)
+                .addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 565, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JTabbedPane dataResultTabbedPanel;
+    private javax.swing.JLabel directoryTablePath;
+    private javax.swing.JLabel matchLabel;
+    private javax.swing.JLabel numberMatchLabel;
+    // End of variables declaration//GEN-END:variables
+//    /**
+//     * Gets default instance. Do not use directly: reserved for *.settings files only,
+//     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+//     * To obtain the singleton instance, use {@link #findInstance}.
+//     */
+//    public static synchronized DataResultTopComponent getDefault() {
+//        if (instance == null) {
+//            instance = new DataResultTopComponent();
+//        }
+//        return instance;
+//    }
+//
+//    /**
+//     * Obtain the DataResultTopComponent instance. Never call {@link #getDefault} directly!
+//     */
+//    public static synchronized DataResultTopComponent findInstance() {
+//        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+//        if (win == null) {
+//            Logger.getLogger(DataResultTopComponent.class.getName()).warning(
+//                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+//            return getDefault();
+//        }
+//        if (win instanceof DataResultTopComponent) {
+//            return (DataResultTopComponent) win;
+//        }
+//        Logger.getLogger(DataResultTopComponent.class.getName()).warning(
+//                "There seem to be multiple components with the '" + PREFERRED_ID
+//                + "' ID. That is a potential source of errors and unexpected behavior.");
+//        return getDefault();
+//    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    public void componentOpened() {
+        // Add all the DataContentViewer to the tabbed pannel.
+        // (Only when the it's opened at the first time: tabCount = 0)
+        int totalTabs = this.dataResultTabbedPanel.getTabCount();
+        if (totalTabs == 0) {
+            // find all dataContentViewer and add them to the tabbed pane
+            for (DataResultViewer factory : Lookup.getDefault().lookupAll(DataResultViewer.class)) {
+                DataResultViewer drv = factory.getInstance();
+                this.viewers.add(new UpdateWrapper(drv));
+                this.dataResultTabbedPanel.addTab(drv.getTitle(), drv.getComponent());
+            }
+        }
+
+        if (this.preferredID().equals(DataResultTopComponent.PREFERRED_ID)) {
+            // if no node selected on DataExplorer, clear the field
+            if (rootNode == null) {
+                setNode(rootNode);
+            }
+        }
+    }
+
+    @Override
+    public void componentClosed() {
+        pcs.firePropertyChange(REMOVE_FILESEARCH, "", this); // notify to remove this from the menu
+
+        // try to remove any references to this class
+        PropertyChangeListener[] pcl = pcs.getPropertyChangeListeners();
+        for (int i = 0; i < pcl.length; i++) {
+            pcs.removePropertyChangeListener(pcl[i]);
+        }
+        
+        // clear all set nodes
+        for (UpdateWrapper drv : this.viewers) {
+            drv.setNode(null);
+        }
+
+        if (!this.isMain) {
+            for (UpdateWrapper drv : this.viewers) {
+                drv.clearComponent();
+            }
+            this.directoryTablePath.removeAll();
+            this.directoryTablePath = null;
+            this.matchLabel.removeAll();
+            this.matchLabel = null;
+            this.numberMatchLabel.removeAll();
+            this.numberMatchLabel = null;
+            this.setLayout(null);
+            this.pcs = null;
+            this.removeAll();
+            System.gc();
+        }
+
+    }
+
+    @Override
+    protected String preferredID() {
+        if (this.isMain) {
+            return PREFERRED_ID;
+        } else {
+            return this.getName();
+        }
+    }
+
+    @Override
+    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+        this.pcs.addPropertyChangeListener(listener);
+    }
+
+    @Override
+    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+        this.pcs.removePropertyChangeListener(listener);
+    }
+
+    @Override
+    public String getPreferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        this.rootNode = selectedNode;
+        String path = "";
+        if (selectedNode != null) {
+            path = DataConversion.getformattedPath(selectedNode.getDisplayPath(), 0);
+
+            int childrenCount = ((Node) selectedNode).getChildren().getNodesCount(true);
+            this.numberMatchLabel.setText(Integer.toString(childrenCount));
+        }
+
+        this.numberMatchLabel.setVisible(true);
+        this.matchLabel.setVisible(true);
+
+        this.directoryTablePath.setText(path); // set the node path
+
+        resetTabs(selectedNode);
+
+        // set the display on the current active tab
+        int currentActiveTab = this.dataResultTabbedPanel.getSelectedIndex();
+        if (currentActiveTab != -1) {
+            UpdateWrapper drv = viewers.get(currentActiveTab);
+            drv.setNode(selectedNode);
+        }
+    }
+
+    @Override
+    public void setTitle(String title) {
+        setName(title);
+    }
+
+    @Override
+    public boolean isMain() {
+        return this.isMain;
+    }
+
+    @Override
+    public boolean canClose() {
+        return (!this.isMain) || !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
+    }
+
+    @Override
+    public void stateChanged(ChangeEvent e) {
+        JTabbedPane pane = (JTabbedPane) e.getSource();
+
+        // Get and set current selected tab
+        int currentTab = pane.getSelectedIndex();
+        if (currentTab != -1) {
+            UpdateWrapper drv = this.viewers.get(currentTab);
+            if (drv.isOutdated()) {
+                // change the cursor to "waiting cursor" for this operation
+                this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                try {
+                    drv.setNode(rootNode);
+                } finally {
+                    this.setCursor(null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Resets the tabs based on the selected Node. If the selected node is null
+     * or not supported, disable that tab as well.
+     *
+     * @param selectedNode  the selected content Node
+     */
+    public void resetTabs(ContentNode selectedNode) {
+
+        for (UpdateWrapper drv : this.viewers) {
+            drv.resetComponent();
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.form
new file mode 100644
index 0000000000000000000000000000000000000000..66868f5057aca72f698223b0890f387000683c39
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.form
@@ -0,0 +1,41 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="tableScrollPanel" alignment="0" pref="691" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="tableScrollPanel" alignment="0" pref="366" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="tableScrollPanel">
+      <Events>
+        <EventHandler event="componentResized" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="tableScrollPanelComponentResized"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new OutlineView(this.firstColumnLabel);"/>
+        <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="//new TreeTableView()"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..834e2fea30b784dab71edd311b0701027e70ec02
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java
@@ -0,0 +1,355 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.FontMetrics;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.view.OutlineView;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.nodes.Node.PropertySet;
+import org.openide.nodes.Sheet;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
+// TODO We should not have anything specific to Image in here...
+import org.sleuthkit.datamodel.Image;
+
+/**
+ * DataResult sortable table viewer
+ */
+@ServiceProvider(service = DataResultViewer.class)
+public class DataResultViewerTable extends AbstractDataResultViewer {
+
+    private transient ExplorerManager em = new ExplorerManager();
+    private String firstColumnLabel = "Name";
+    private boolean isImageNode;
+
+    /** Creates new form DataResultViewerTable */
+    public DataResultViewerTable() {
+        initComponents();
+
+        OutlineView ov = ((OutlineView) this.tableScrollPanel);
+
+        // only allow one item to be selected at a time
+        ov.getOutline().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        
+        // don't show the root node
+        ov.getOutline().setRootVisible(false);
+
+        this.isImageNode = false;
+        this.em.addPropertyChangeListener(this);
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        tableScrollPanel = new OutlineView(this.firstColumnLabel);
+
+        //new TreeTableView()
+        tableScrollPanel.addComponentListener(new java.awt.event.ComponentAdapter() {
+            public void componentResized(java.awt.event.ComponentEvent evt) {
+                tableScrollPanelComponentResized(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 691, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(tableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void tableScrollPanelComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_tableScrollPanelComponentResized
+        if (this.tableScrollPanel.getWidth() < 700 && isImageNode) {
+            ((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+        } else {
+            if (isImageNode) {
+                ((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+            }
+        }
+    }//GEN-LAST:event_tableScrollPanelComponentResized
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JScrollPane tableScrollPanel;
+    // End of variables declaration//GEN-END:variables
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return this.em;
+    }
+
+    @Override
+    public Node getOriginalSelectedNode() {
+        Node result = null;
+        Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
+        if (selectedNodes.length > 0) {
+            result = selectedNodes[0];
+            if (result != null && result instanceof TableFilterNode) {
+                result = ((TableFilterNode) result).getOriginal();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Gets regular Bean property set properties from first child of Node.
+     * @param parent Node with at least one child to get properties from
+     * @return Properties,
+     */
+    private Node.Property[] getChildPropertyHeaders(Node parent) {
+        Node firstChild = parent.getChildren().getNodeAt(0);
+
+        if (firstChild == null) {
+            throw new IllegalArgumentException("Couldn't get a child Node from the given parent.");
+        } else {
+            for (PropertySet ps : firstChild.getPropertySets()) {
+                if (ps.getName().equals(Sheet.PROPERTIES)) {
+                    return ps.getProperties();
+                }
+            }
+
+            throw new IllegalArgumentException("Child Node doesn't have the regular PropertySet.");
+        }
+    }
+
+    @Override
+    public void setNode(ContentNode selectedNode) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            boolean hasChildren = false;
+
+
+            if (selectedNode != null) {
+                hasChildren = ((Node) selectedNode).getChildren().getNodesCount() > 0;
+            }
+
+
+            // if there's no selection node, do nothing
+            if (hasChildren) {
+                Node root = (Node) selectedNode;
+
+                if (root instanceof TableFilterNode) {
+                    root = ((TableFilterNode) root).getOriginal();
+                } else {
+                    root = new TableFilterNode(root, true);
+                }
+
+                em.setRootContext(root);
+
+                OutlineView ov = ((OutlineView) this.tableScrollPanel);
+
+                List<Node.Property> tempProps = new ArrayList<Node.Property>(Arrays.asList(getChildPropertyHeaders((Node) selectedNode)));
+
+                tempProps.remove(0);
+
+                Node.Property[] props = tempProps.toArray(new Node.Property[tempProps.size()]);
+
+
+                // *********** Make the TreeTableView to be sortable ***************
+
+                //First property column is sortable, but also sorted initially, so
+                //initially this one will have the arrow icon:
+                props[0].setValue("TreeColumnTTV", Boolean.TRUE); // Identifies special property representing first (tree) column.
+                props[0].setValue("ComparableColumnTTV", Boolean.TRUE); // This property column should be used for sorting.
+                props[0].setValue("SortingColumnTTV", Boolean.TRUE); // TreeTableView should be initially sorted by this property column.
+
+                // The rest of the columns are sortable, but not initially sorted,
+                // so initially will have no arrow icon:
+                for (int i = 1; i < props.length; i++) {
+                    props[i].setValue("ComparableColumnTTV", Boolean.TRUE);
+                }
+
+                // *****************************************************************
+
+                //ttv.setProperties(props); // set the properties
+                ov.setProperties(props); // set the properties
+
+                //            // set the first entry
+                //            Children test = root.getChildren();
+                //            Node firstEntryNode = test.getNodeAt(0);
+                //            try {
+                //                this.getExplorerManager().setSelectedNodes(new Node[]{firstEntryNode});
+                //            } catch (PropertyVetoException ex) {}
+
+
+                // show the horizontal scroll panel and show all the content & header
+                if (!(selectedNode.getContent() instanceof Image)) {
+                    this.isImageNode = false;
+                    int totalColumns = props.length;
+
+                    //int scrollWidth = ttv.getWidth();
+                    int scrollWidth = ov.getWidth();
+                    int minWidth = scrollWidth / totalColumns;
+                    int margin = 4;
+                    int startColumn = 1;
+                    ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+
+                    // get the fontmetrics
+                    //FontMetrics metrics = ttv.getGraphics().getFontMetrics();
+                    FontMetrics metrics = ov.getGraphics().getFontMetrics();
+
+                    // get first 100 rows values for the table
+                    Object[][] content = null;
+                    try {
+                        content = selectedNode.getRowValues(100);
+                    } catch (SQLException ex) {
+                        // TODO: potential exception is being ignored (see below), should be handled 
+                    }
+
+
+                    if (content != null) {
+                        // for the "Name" column
+                        int nodeColWidth = getMaxColumnWidth(0, metrics, margin, 40, firstColumnLabel, content); // Note: 40 is the width of the icon + node lines. Change this value if those values change!
+                        ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(nodeColWidth);
+
+                        // get the max for each other column
+                        for (int colIndex = startColumn; colIndex < totalColumns; colIndex++) {
+                            int colWidth = getMaxColumnWidth(colIndex, metrics, margin, 8, props, content);
+                            ov.getOutline().getColumnModel().getColumn(colIndex).setPreferredWidth(colWidth);
+                        }
+                    }
+
+                    // if there's no content just auto resize all columns
+                    if (!(content.length > 0)) {
+                        // turn on the auto resize
+                        ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+                    }
+                } else {
+                    this.isImageNode = true;
+                    // turn on the auto resize for image result
+                    ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(175);
+                    ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+                }
+            } else {
+                Node emptyNode = new AbstractNode(Children.LEAF);
+                em.setRootContext(emptyNode); // make empty node
+                ((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+                ((OutlineView) this.tableScrollPanel).setProperties(new Node.Property[]{}); // set the empty property header
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        return "Table View";
+    }
+
+    @Override
+    public DataResultViewer getInstance() {
+        return new DataResultViewerTable();
+    }
+
+    @Override
+    public void resetComponent() {
+    }
+
+    /**
+     * Gets the max width of the column from the given index, header, and table.
+     *
+     * @param index    the index of the column on the table / header
+     * @param metrics  the font metrics that this component use
+     * @param margin   the left/right margin of the column
+     * @param padding  the left/right padding of the column
+     * @param header   the property headers of the table
+     * @param table    the object table
+     * @return max  the maximum width of the column
+     */
+    private int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, Node.Property[] header, Object[][] table) {
+        // set the tree (the node / names column) width
+        String headerName = header[index - 1].getDisplayName();
+
+        return getMaxColumnWidth(index, metrics, margin, padding, headerName, table);
+    }
+
+    /**
+     * Gets the max width of the column from the given index, header, and table.
+     *
+     * @param index    the index of the column on the table / header
+     * @param metrics  the font metrics that this component use
+     * @param margin   the left/right margin of the column
+     * @param padding  the left/right padding of the column
+     * @param header   the column header for the comparison
+     * @param table    the object table
+     * @return max  the maximum width of the column
+     */
+    private int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, String header, Object[][] table) {
+        // set the tree (the node / names column) width
+        String headerName = header;
+        int headerWidth = metrics.stringWidth(headerName); // length of the header
+        int colWidth = 0;
+
+        // Get maximum width of column data
+        for (int i = 0; i < table.length; i++) {
+            String test = table[i][index].toString();
+            colWidth = Math.max(colWidth, metrics.stringWidth(test));
+        }
+
+        colWidth += padding; // add the padding on the most left gap
+        headerWidth += 8; // add the padding to the header (change this value if the header padding value is changed)
+
+        // Set the width
+        int width = Math.max(headerWidth, colWidth);
+        width += 2 * margin; // Add margin
+
+        return width;
+    }
+
+    @Override
+    public void clearComponent() {
+        em.removePropertyChangeListener(this);
+        this.tableScrollPanel.removeAll();
+        this.tableScrollPanel = null;
+        try {
+            this.em.getRootContext().destroy();
+            em = null;
+        } catch (IOException ex) {
+            // TODO: Proper thing to do? Log? Don't throw RuntimeException?
+            throw new RuntimeException("Error: can't clear the component of the Table Result Viewer.", ex);
+        }
+    }
+
+    @Override
+    public Component getComponent() {
+        return this;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form
new file mode 100644
index 0000000000000000000000000000000000000000..4c5b1ed717d45f0a79609cda622bb79cf74cef16
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.form
@@ -0,0 +1,37 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="thumbnailScrollPanel" alignment="1" pref="675" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="thumbnailScrollPanel" alignment="1" pref="336" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="thumbnailScrollPanel">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new IconView();"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0fdc0ea6b6375885340f7711295d5ac7070f276
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java
@@ -0,0 +1,158 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.io.IOException;
+import javax.swing.ListSelectionModel;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.view.IconView;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.lookup.ServiceProvider;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
+
+/**
+ * Thumbnail view of images in data result
+ */
+@ServiceProvider(service = DataResultViewer.class)
+public class DataResultViewerThumbnail extends AbstractDataResultViewer {
+
+    private transient ExplorerManager em = new ExplorerManager();
+
+    /** Creates new form DataResultViewerThumbnail */
+    public DataResultViewerThumbnail() {
+        initComponents();
+
+        // only allow one item to be selected at a time
+        ((IconView) thumbnailScrollPanel).setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+        this.em.addPropertyChangeListener(this);
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        thumbnailScrollPanel = new IconView();
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(thumbnailScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 675, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(thumbnailScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JScrollPane thumbnailScrollPanel;
+    // End of variables declaration//GEN-END:variables
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return this.em;
+    }
+
+    @Override
+    public Node getOriginalSelectedNode() {
+        Node result = null;
+
+        Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
+        if (selectedNodes.length > 0) {
+            result = selectedNodes[0];
+            if (result != null && result instanceof ThumbnailViewNode) {
+                result = ((ThumbnailViewNode) result).getOriginal();
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void setNode(ContentNode givenNode) {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            if (givenNode != null) {
+                Node root = (Node) givenNode;
+
+                if (root instanceof ThumbnailViewNode) {
+                    root = ((ThumbnailViewNode) root).getOriginal();
+                } else {
+                    Node temp = new AbstractNode(new ThumbnailViewChildren((ContentNode) root));
+                    root = temp;
+                }
+
+                em.setRootContext(root);
+            } else {
+                Node emptyNode = new AbstractNode(Children.LEAF);
+                em.setRootContext(emptyNode); // make empty node
+                
+                IconView iv = ((IconView) this.thumbnailScrollPanel);
+                iv.setBackground(Color.BLACK);
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        return "Thumbnail View";
+    }
+
+    @Override
+    public DataResultViewer getInstance() {
+        return new DataResultViewerThumbnail();
+    }
+
+    @Override
+    public void resetComponent() {
+    }
+
+    @Override
+    public void clearComponent() {
+        em.removePropertyChangeListener(this);
+        this.thumbnailScrollPanel.removeAll();
+        this.thumbnailScrollPanel = null;
+        try {
+            this.em.getRootContext().destroy();
+            em = null;
+        } catch (IOException ex) {
+            // TODO: What's the proper thing to do here? Should it log? Not throw runtime exception?
+            throw new RuntimeException("Error: can't clear the component of the Thumbnail Result Viewer.", ex);
+        }
+    }
+
+    @Override
+    public Component getComponent() {
+        return this;
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Installer.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Installer.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a3cacffdb61de3e624af0634e6e436106e9e76e
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/Installer.java
@@ -0,0 +1,43 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import org.openide.modules.ModuleInstall;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.casemodule.Case;
+
+/**
+ * Manages this module's lifecycle. Opens the startup dialog during startup.
+ */
+public class Installer extends ModuleInstall {
+
+    @Override
+    public void restored() {
+        //TODO: the version number shouldn't really be stored in the Case class
+        System.setProperty("netbeans.buildnumber", Case.getAutopsyVersion());
+
+        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
+
+            @Override
+            public void run() {
+                Case.invokeStartupDialog(); // bring up the startup dialog
+            }
+        });
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..3ac931b2dc84f9559548d04f10a3b0fe297a5a9a
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.form
@@ -0,0 +1,139 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="jScrollPane1" pref="602" max="32767" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="pageLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                      <Component id="currentPageLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="ofLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="totalPageLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                      <Component id="prevPageButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                      <Component id="nextPageButton" min="-2" pref="99" max="-2" attributes="0"/>
+                      <EmptySpace pref="276" max="32767" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="filePathLabel" max="32767" attributes="0"/>
+                      <EmptySpace min="-2" pref="574" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="filePathLabel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="pageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="currentPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="ofLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="totalPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="prevPageButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="nextPageButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jScrollPane1" pref="337" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JButton" name="nextPageButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nextPageButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextPane" name="outputViewPane">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Courier New" size="11" style="0"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="prevPageButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="prevPageButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="totalPageLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.totalPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="ofLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.ofLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="currentPageLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.currentPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="pageLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.pageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="filePathLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="OutputViewPanel.filePathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7be0036dac25e917df926e98afe483b73529fc7
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/OutputViewPanel.java
@@ -0,0 +1,251 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * Paging view for DataContentViewer.
+ */
+public class OutputViewPanel extends javax.swing.JPanel {
+
+    private static long currentOffset = 0;
+    private static long pageLength = 10240;
+    private static int currentPage = 1;
+    private int outputType;
+    private Content dataSource;
+
+    /**
+     * Creates new form OutputViewPanel
+     * @param outputType type of panel to display: 1 = hex view, 2 = string view
+     */
+    public OutputViewPanel(int outputType) {
+        initComponents();
+        this.outputType = outputType;
+        this.dataSource = null;
+
+        // clear / reset the fields
+        filePathLabel.setText("");
+        currentPageLabel.setText("");
+        totalPageLabel.setText("");
+        ofLabel.setVisible(false);
+        prevPageButton.setEnabled(false);
+        nextPageButton.setEnabled(false);
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        nextPageButton = new javax.swing.JButton();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        outputViewPane = new javax.swing.JTextPane();
+        prevPageButton = new javax.swing.JButton();
+        totalPageLabel = new javax.swing.JLabel();
+        ofLabel = new javax.swing.JLabel();
+        currentPageLabel = new javax.swing.JLabel();
+        pageLabel = new javax.swing.JLabel();
+        filePathLabel = new javax.swing.JLabel();
+
+        nextPageButton.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.nextPageButton.text")); // NOI18N
+        nextPageButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                nextPageButtonActionPerformed(evt);
+            }
+        });
+
+        outputViewPane.setFont(new java.awt.Font("Courier New", 0, 11));
+        jScrollPane1.setViewportView(outputViewPane);
+
+        prevPageButton.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.prevPageButton.text")); // NOI18N
+        prevPageButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                prevPageButtonActionPerformed(evt);
+            }
+        });
+
+        totalPageLabel.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.totalPageLabel.text")); // NOI18N
+
+        ofLabel.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.ofLabel.text")); // NOI18N
+
+        currentPageLabel.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.currentPageLabel.text")); // NOI18N
+
+        pageLabel.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.pageLabel.text")); // NOI18N
+
+        filePathLabel.setText(org.openide.util.NbBundle.getMessage(OutputViewPanel.class, "OutputViewPanel.filePathLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 602, Short.MAX_VALUE)
+                        .addContainerGap())
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(pageLabel)
+                        .addGap(18, 18, 18)
+                        .addComponent(currentPageLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(ofLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(totalPageLabel)
+                        .addGap(18, 18, 18)
+                        .addComponent(prevPageButton)
+                        .addGap(18, 18, 18)
+                        .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addContainerGap(276, Short.MAX_VALUE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(filePathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addGap(574, 574, 574))))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(filePathLabel)
+                .addGap(4, 4, 4)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(pageLabel)
+                    .addComponent(currentPageLabel)
+                    .addComponent(ofLabel)
+                    .addComponent(totalPageLabel)
+                    .addComponent(prevPageButton)
+                    .addComponent(nextPageButton))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 337, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset -= pageLength;
+        currentPage = currentPage - 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false, outputType);
+    }//GEN-LAST:event_prevPageButtonActionPerformed
+
+    private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
+        //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
+        currentOffset += pageLength;
+        currentPage = currentPage + 1;
+        currentPageLabel.setText(Integer.toString(currentPage));
+        setDataView(dataSource, currentOffset, false, outputType);
+    }//GEN-LAST:event_nextPageButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel currentPageLabel;
+    private javax.swing.JLabel filePathLabel;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JButton nextPageButton;
+    private javax.swing.JLabel ofLabel;
+    private javax.swing.JTextPane outputViewPane;
+    private javax.swing.JLabel pageLabel;
+    private javax.swing.JButton prevPageButton;
+    private javax.swing.JLabel totalPageLabel;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Sets the DataView (The tabbed panel)
+     *
+     * @param dataSource  the content that want to be shown
+     * @param offset      the starting offset
+     * @param reset       whether to reset the dataView or not
+     * @param outputType  the type of the output. 1 = hex view, 2 = string view
+     */
+    public void setDataView(Content dataSource, long offset, boolean reset, int outputType) {
+        try {
+            this.dataSource = dataSource;
+            byte[] data;
+
+            if (dataSource.getSize() > 0) {
+                data = dataSource.read(offset, pageLength); // read the data
+            } else {
+                // empty file
+                data = null;
+            }
+
+            // I set the -1 to for empty node or directory
+            if (reset) {
+                data = null;
+                filePathLabel.setText("");
+            }
+
+            // set the data on the bottom and show it
+            String text = "";
+            Boolean setVisible = false;
+
+            if (data != null) {
+                text = DataConversion.getString(data, 4);
+                setVisible = true;
+            }
+
+            // disable or enable the next button
+            if (offset + pageLength < dataSource.getSize()) {
+                nextPageButton.setEnabled(true);
+            } else {
+                nextPageButton.setEnabled(false);
+            }
+
+            if (offset == 0) {
+                prevPageButton.setEnabled(false);
+                currentPage = 1; // reset the page number
+            } else {
+                prevPageButton.setEnabled(true);
+            }
+
+            // type 1 = hex view
+            if (outputType == 1) {
+                outputViewPane.setText(DataConversion.byteArrayToHex(data, pageLength, offset, outputViewPane.getFont()));
+                outputViewPane.moveCaretPosition(0);
+            }
+            // type 2 = string view
+            if (outputType == 2) {
+                outputViewPane.setText(text);
+                outputViewPane.moveCaretPosition(0);
+            }
+
+            if (setVisible) {
+                int totalPage = (int) (dataSource.getSize() / pageLength) + 1;
+                ofLabel.setVisible(true);
+                totalPageLabel.setText(Integer.toString(totalPage));
+                currentPageLabel.setText(Integer.toString(currentPage));
+            } else {
+                // reset or hide the labels
+                ofLabel.setVisible(false);
+                totalPageLabel.setText("");
+                currentPageLabel.setText("");
+            }
+        } catch (TskException ex) {
+            // TODO: maybe make bubble instead
+            Logger.getLogger(OutputViewPanel.class.getName()).log(Level.WARNING, "Error while trying to set the display on the ouput view panel.", ex);
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.form b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..1479125a3e5a79c9034200309b0c8720c18adfd1
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.form
@@ -0,0 +1,150 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jScrollPane2" alignment="0" pref="394" max="32767" attributes="0"/>
+                  <Component id="jScrollPane3" alignment="1" pref="394" max="32767" attributes="0"/>
+                  <Component id="jLabel1" alignment="0" pref="394" max="32767" attributes="0"/>
+                  <Group type="102" attributes="0">
+                      <Component id="jPanel1" pref="237" max="32767" attributes="1"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="verboseLoggingButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
+              <Component id="jScrollPane3" pref="101" max="32767" attributes="2"/>
+              <EmptySpace min="-2" pref="32" max="-2" attributes="0"/>
+              <Component id="jScrollPane2" pref="103" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace min="-2" pref="27" max="-2" attributes="0"/>
+                      <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Component id="verboseLoggingButton" alignment="0" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="horizontalAlignment" type="int" value="0"/>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="about" type="code"/>
+        </Property>
+        <Property name="horizontalTextPosition" type="int" value="0"/>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jLabel1MouseClicked"/>
+      </Events>
+    </Component>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JButton" name="jButton2">
+          <Properties>
+            <Property name="mnemonic" type="int" editor="org.netbeans.modules.i18n.form.FormI18nMnemonicEditor">
+              <ResourceString bundle="" key="MNE_Close" replaceFormat="NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/netbeans/core/ui/Bundle.properties" key="LBL_Close" replaceFormat="NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton2ActionPerformed"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane3">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="null"/>
+        </Property>
+      </Properties>
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextPane" name="copyright">
+          <Properties>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+              <Border info="null"/>
+            </Property>
+            <Property name="contentType" type="java.lang.String" value="text/html"/>
+            <Property name="editable" type="boolean" value="false"/>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/netbeans/core/ui/Bundle.properties" key="LBL_Copyright" replaceFormat="org.openide.util.NbBundle.getBundle({sourceFileName}.class).getString(&quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="copyrightMouseClicked"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane2">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextPane" name="description">
+          <Properties>
+            <Property name="contentType" type="java.lang.String" value="text/html"/>
+            <Property name="editable" type="boolean" value="false"/>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="ProductInformationPanel_description"/>
+          </AuxValues>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="verboseLoggingButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Activate verbose logging"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="activateVerboseLogging"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..d29e1ea8f33a60aef80e4a64d15ad02a9f0e4052
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ProductInformationPanel.java
@@ -0,0 +1,256 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Cursor;
+import java.awt.Window;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Locale;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import org.netbeans.core.actions.HTMLViewAction;
+import org.openide.awt.HtmlBrowser;
+import org.openide.util.NbBundle;
+import org.sleuthkit.autopsy.casemodule.Autopsy;
+import org.sleuthkit.datamodel.SleuthkitJNI;
+
+/**
+ * Custom "About" window panel.
+ */
+class ProductInformationPanel extends JPanel implements HyperlinkListener {
+
+    private URL url = null;
+    private Icon about;
+
+    ProductInformationPanel() {
+        about = new ImageIcon(org.netbeans.core.startup.Splash.loadContent(true));
+        initComponents();
+        jLabel1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        description.setText(org.openide.util.NbBundle.getMessage(ProductInformationPanel.class,
+                "LBL_Description", new Object[]{getProductVersionValue(), getJavaValue(), getVMValue(),
+                    getOperatingSystemValue(), getEncodingValue(), getSystemLocaleValue(), getUserDirValue(), getSleuthKitVersionValue()}));
+        description.addHyperlinkListener(this);
+        copyright.addHyperlinkListener(this);
+        copyright.setBackground(getBackground());
+        if (Autopsy.verboseLoggingIsSet()) {
+            disableVerboseLoggingButton();
+        }
+
+    }
+
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+        java.awt.GridBagConstraints gridBagConstraints;
+
+        jLabel1 = new javax.swing.JLabel();
+        jPanel1 = new javax.swing.JPanel();
+        jButton2 = new javax.swing.JButton();
+        jScrollPane3 = new javax.swing.JScrollPane();
+        copyright = new javax.swing.JTextPane();
+        jScrollPane2 = new javax.swing.JScrollPane();
+        description = new javax.swing.JTextPane();
+        verboseLoggingButton = new javax.swing.JButton();
+
+        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+        jLabel1.setIcon(about);
+        jLabel1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        jLabel1.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                jLabel1MouseClicked(evt);
+            }
+        });
+
+        jPanel1.setLayout(new java.awt.GridBagLayout());
+
+        jButton2.setMnemonic(NbBundle.getMessage(ProductInformationPanel.class, "MNE_Close").charAt(0));
+        jButton2.setText(NbBundle.getMessage(ProductInformationPanel.class, "LBL_Close")); // NOI18N
+        jButton2.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                jButton2ActionPerformed(evt);
+            }
+        });
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.weightx = 1.0;
+        gridBagConstraints.weighty = 1.0;
+        jPanel1.add(jButton2, gridBagConstraints);
+
+        jScrollPane3.setBorder(null);
+
+        copyright.setBorder(null);
+        copyright.setContentType("text/html");
+        copyright.setEditable(false);
+        copyright.setText(org.openide.util.NbBundle.getBundle(ProductInformationPanel.class).getString("LBL_Copyright")); // NOI18N
+        copyright.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                copyrightMouseClicked(evt);
+            }
+        });
+        jScrollPane3.setViewportView(copyright);
+
+        description.setContentType("text/html");
+        description.setEditable(false);
+        jScrollPane2.setViewportView(description);
+
+        verboseLoggingButton.setText("Activate verbose logging");
+        verboseLoggingButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                activateVerboseLogging(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
+                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
+                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 237, Short.MAX_VALUE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(verboseLoggingButton)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jLabel1)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
+                .addGap(32, 32, 32)
+                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 103, Short.MAX_VALUE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(27, 27, 27)
+                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addComponent(verboseLoggingButton))
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+private void copyrightMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_copyrightMouseClicked
+    showUrl();
+}//GEN-LAST:event_copyrightMouseClicked
+
+private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
+    closeDialog();
+}//GEN-LAST:event_jButton2ActionPerformed
+
+private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel1MouseClicked
+    try {
+        url = new URL(NbBundle.getMessage(ProductInformationPanel.class, "URL_ON_IMG")); // NOI18N
+        showUrl();
+    } catch (MalformedURLException ex) {
+        //ignore
+    }
+    url = null;    // TODO add your handling code here:
+}//GEN-LAST:event_jLabel1MouseClicked
+
+    private void activateVerboseLogging(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_activateVerboseLogging
+        Autopsy.startVerboseLogging();
+        disableVerboseLoggingButton();
+    }//GEN-LAST:event_activateVerboseLogging
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JTextPane copyright;
+    private javax.swing.JTextPane description;
+    private javax.swing.JButton jButton2;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane2;
+    private javax.swing.JScrollPane jScrollPane3;
+    private javax.swing.JButton verboseLoggingButton;
+    // End of variables declaration//GEN-END:variables
+
+    private void disableVerboseLoggingButton() {
+        this.verboseLoggingButton.setEnabled(false);
+        this.verboseLoggingButton.setText("Verbose logging enabled");
+    }
+
+    private void closeDialog() {
+        Window w = SwingUtilities.getWindowAncestor(this);
+        w.setVisible(false);
+        w.dispose();
+    }
+
+    private void showUrl() {
+        if (url != null) {
+            org.openide.awt.StatusDisplayer.getDefault().setStatusText(
+                    NbBundle.getBundle(HTMLViewAction.class).getString("CTL_OpeningBrowser"));
+            HtmlBrowser.URLDisplayer.getDefault().showURL(url);
+        }
+    }
+
+    private static String getSleuthKitVersionValue() {
+        return SleuthkitJNI.getVersion();
+    }
+
+    private static String getProductVersionValue() {
+        return MessageFormat.format(
+                NbBundle.getBundle("org.netbeans.core.startup.Bundle").getString("currentVersion"),
+                new Object[]{System.getProperty("netbeans.buildnumber")});
+    }
+
+    private static String getOperatingSystemValue() {
+        return NbBundle.getMessage(ProductInformationPanel.class, "Format_OperatingSystem_Value",
+                System.getProperty("os.name", "unknown"),
+                System.getProperty("os.version", "unknown"),
+                System.getProperty("os.arch", "unknown"));
+    }
+
+    private static String getJavaValue() {
+        return System.getProperty("java.version", "unknown");
+    }
+
+    private static String getVMValue() {
+        return System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "");
+    }
+
+    private static String getSystemLocaleValue() {
+        String branding;
+        return Locale.getDefault().toString() + ((branding = NbBundle.getBranding()) == null ? "" : (" (" + branding + ")")); // NOI18N
+    }
+
+    private String getUserDirValue() {
+        return System.getProperty("netbeans.user");
+    }
+
+    private static String getEncodingValue() {
+        return System.getProperty("file.encoding", "unknown");
+    }
+
+    @Override
+    public void hyperlinkUpdate(HyperlinkEvent event) {
+        if (HyperlinkEvent.EventType.ENTERED == event.getEventType()) {
+            url = event.getURL();
+        } else if (HyperlinkEvent.EventType.EXITED == event.getEventType()) {
+            url = null;
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterChildren.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..dcc3a788464489af623a3824522a7fc613a76e84
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterChildren.java
@@ -0,0 +1,59 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import org.openide.nodes.Children;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+
+/**
+ * Complementary class to TableFilterNode.
+ */
+class TableFilterChildren extends FilterNode.Children {
+
+    /** the constructor */
+    TableFilterChildren(Node arg) {
+        super(arg);
+    }
+
+    @Override
+    protected Node copyNode(Node arg0) {
+        return new TableFilterNode(arg0, false);
+    }
+
+    @Override
+    protected Node[] createNodes(Node arg0) {
+        // filter out the children
+        return new Node[]{this.copyNode(arg0)};
+    }
+
+    /**
+     * Converts the given FsContent into "Children".
+     *
+     * @param fs
+     * @return children
+     */
+    public static Children createInstance(Node arg, boolean createChild) {
+        if (createChild) {
+            return new TableFilterChildren(arg);
+        } else {
+            return Children.LEAF;
+        }
+    }
+}
\ No newline at end of file
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterNode.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..33236fc791c2b363a0a048d92a52bb8880fc799f
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/TableFilterNode.java
@@ -0,0 +1,59 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+
+/**
+ * This class is used to filter the nodes that we want to show on the "TreeTableView".
+ * So basically we just want to show one layer of nodes from it's parent.
+ *
+ * @author jantonius
+ */
+class TableFilterNode extends FilterNode {
+
+    private boolean createChild;
+
+    /** the constructor */
+    public TableFilterNode(Node arg, boolean crChild) {
+        super(arg, TableFilterChildren.createInstance(arg, crChild));
+        this.createChild = crChild;
+    }
+
+    @Override
+    public Node getOriginal() {
+        return super.getOriginal();
+    }
+
+    /**
+     * Override the display name / header for the first (tree) column on the
+     * "TreeTableView".
+     *
+     * @return disName  the display name for the first column
+     */
+    @Override
+    public String getDisplayName() {
+        if (createChild) {
+            return "Name";
+        } else {
+            return super.getDisplayName();
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewChildren.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..42916ee1031a1b043b49172b64e83521115bc78c
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewChildren.java
@@ -0,0 +1,78 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+
+/**
+ * Complementary class to ThumbnailViewNode
+ */
+class ThumbnailViewChildren extends FilterNode.Children {
+
+    private int totalChildren;
+
+    /** the constructor */
+    ThumbnailViewChildren(ContentNode arg) {
+        super((Node) arg);
+        this.totalChildren = 1;
+    }
+
+    @Override
+    protected Node copyNode(Node arg0) {
+        return new ThumbnailViewNode((ContentNode) arg0);
+    }
+
+    @Override
+    protected Node[] createNodes(Node arg0) {
+        // filter out the FileNode and the "." and ".." directories
+        if (arg0 != null && //(arg0 instanceof FileNode &&
+                isSupported(arg0)) {
+            totalChildren++;
+            return new Node[]{this.copyNode(arg0)};
+        } else {
+            return new Node[]{};
+        }
+    }
+
+    public int childrenCount() {
+        return this.totalChildren;
+    }
+
+    public static boolean isSupported(Node node) {
+        if (node != null) {
+            String lowerName = node.getDisplayName().toLowerCase();
+            // Note: only supports JPG, GIF, and PNG for now
+            // TODO: replace giant OR with check if in list
+            return lowerName.endsWith(".jpg")
+                    || lowerName.endsWith(".jpeg")
+                    || //node.getName().toLowerCase().endsWith(".jpe") ||
+                    //node.getName().toLowerCase().endsWith(".jfif") ||
+                    lowerName.endsWith(".gif")
+                    || //node.getName().toLowerCase().endsWith(".bmp") ||
+                    //node.getName().toLowerCase().endsWith(".tif") ||
+                    //node.getName().toLowerCase().endsWith(".tiff") ||
+                    //node.getName().toLowerCase().endsWith(".tga") ||
+                    lowerName.endsWith(".png");
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewNode.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..304cdeea6c33fa5657afd6380cfc70ad487472cb
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/ThumbnailViewNode.java
@@ -0,0 +1,125 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.corecomponents;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+import java.lang.ref.SoftReference;
+import java.util.logging.Level;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ *
+ * @author jantonius
+ */
+class ThumbnailViewNode extends FilterNode {
+
+    private ContentNode currentNode;
+    // for error handling
+    private SoftReference<Image> iconCache;
+    private static Image defaultIcon = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage();
+
+    /** the constructor */
+    ThumbnailViewNode(ContentNode arg) {
+        super((Node) arg, Children.LEAF);
+        this.currentNode = arg;
+    }
+
+    @Override
+    public Node getOriginal() {
+        return super.getOriginal();
+    }
+
+    @Override
+    public Image getIcon(int type) {
+        Image icon = null;
+
+        if (iconCache != null) {
+            icon = iconCache.get();
+        }
+
+        if (icon == null) {
+            try {
+                System.out.println("generate");
+                icon = generateIcon();
+                iconCache = new SoftReference<Image>(icon);
+            } catch (TskException ex) {
+                icon = ThumbnailViewNode.defaultIcon;
+            }
+        }
+
+        return icon;
+    }
+
+    private Image generateIcon() throws TskException {
+        ContentNode temp = currentNode;
+        byte[] content = temp.read(0, temp.getContent().getSize());
+        Image result = Toolkit.getDefaultToolkit().createImage(content);
+
+        // scale the image
+        MediaTracker mTracker = new MediaTracker(new JFrame());
+        mTracker.addImage(result, 1);
+        try {
+            mTracker.waitForID(1);
+        } catch (InterruptedException ex) {
+            // TODO: maybe make bubble instead
+            Log.get(ThumbnailViewNode.class).log(Level.WARNING, "Error while trying to scale the icon.", ex);
+        }
+        int width = result.getWidth(null);
+        int height = result.getHeight(null);
+
+        int max = Math.max(width, height);
+        double scale = (75 * 100) / max;
+
+        // getScaledInstance can't take have width or height be 0, so round
+        // up by adding 1 after truncating to int.
+        width = (int) ((width * scale) / 100) + 1;
+        height = (int) ((height * scale) / 100) + 1;
+
+        result = result.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+
+        // load the image completely
+        mTracker.addImage(result, 1);
+        try {
+            mTracker.waitForID(1);
+        } catch (InterruptedException ex) {
+            // TODO: maybe make bubble instead
+            Log.get(ThumbnailViewNode.class).log(Level.WARNING, "Error while trying to load the icon.", ex);
+        }
+
+        // create 75x75 image for the icon with the icon on the center
+        BufferedImage combined = new BufferedImage(75, 75, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = (Graphics2D) combined.getGraphics();
+        g.setColor(Color.WHITE);
+        g.setBackground(Color.WHITE);
+        g.drawImage(result, (75 - width) / 2, (75 - height) / 2, null);
+
+        return Toolkit.getDefaultToolkit().createImage(combined.getSource());
+    }
+}
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_left.gif b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_left.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d0d85dba4b9abc810f454a014fafc142f97f5f16
Binary files /dev/null and b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_left.gif differ
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_right.gif b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_right.gif
new file mode 100644
index 0000000000000000000000000000000000000000..85272ad99cc0df252748b08468d0649a9c90fcda
Binary files /dev/null and b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/arrow_right.gif differ
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/corecomponents-helpset.xml b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/corecomponents-helpset.xml
new file mode 100644
index 0000000000000000000000000000000000000000..367403b5933769496ea3337c8807d96115aab375
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/corecomponents-helpset.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpsetref PUBLIC "-//NetBeans//DTD JavaHelp Help Set Reference 1.0//EN" "http://www.netbeans.org/dtds/helpsetref-1_0.dtd">
+<helpsetref url="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/corecomponents-hs.xml"/>
diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/layer.xml b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e9a8fa7c8f6d8e8c3d3b6decbcd446181b0447fd
--- /dev/null
+++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/layer.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Help">
+            <file name="org-netbeans-core-actions-AboutAction.instance_hidden"/>
+            <file name="org-sleuthkit-autopsy-corecomponents-CustomAboutAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.corecomponents.CustomAboutAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.corecomponents.Bundle#CTL_CustomAboutAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+        </folder>
+        <folder name="Window">
+            <file name="org-sleuthkit-autopsy-corecomponents-DataContentAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.corecomponents.DataContentTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.corecomponents.Bundle#CTL_DataContentAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Help">
+            <attr name="master-help.xml/org-sleuthkit-autopsy-corecomponents-CustomAboutAction.shadow" boolvalue="true"/>
+            <file name="org-netbeans-core-actions-AboutAction.shadow_hidden"/>
+            <file name="org-sleuthkit-autopsy-corecomponents-CustomAboutAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Help/org-sleuthkit-autopsy-corecomponents-CustomAboutAction.instance"/>
+            </file>
+        </folder>
+        <folder name="Window"/>
+    </folder>
+    <folder name="Services">
+        <folder name="JavaHelp">
+            <file name="corecomponents-helpset.xml" url="corecomponents-helpset.xml">
+                <attr name="position" intvalue="3801"/>
+            </file>
+        </folder>
+        <file name="org-sleuthkit-autopsy-corecomponents-DataContentTopComponent.instance">
+            <attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.corecomponentinterfaces.DataContent"/>
+            <attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.corecomponents.DataContentTopComponent.getDefault"/>
+        </file>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+
+        </folder>
+        <folder name="Modes">
+            <folder name="editor">
+                </folder>
+            <folder name="output">
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
diff --git a/DataModel/build.xml b/DataModel/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1c5480c65a95218e010913239a2ea2fefb906954
--- /dev/null
+++ b/DataModel/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.datamodel" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.datamodel.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/DataModel/manifest.mf b/DataModel/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..e6e7aaf8c3dc7a9aef310630ef34f552f8584405
--- /dev/null
+++ b/DataModel/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.datamodel/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Install: org/sleuthkit/autopsy/datamodel/Installer.class
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/datamodel/Bundle.properties
+
diff --git a/DataModel/nbproject/build-impl.xml b/DataModel/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93e8e0c4d47d1dd2f93229f84ab05980a16e5970
--- /dev/null
+++ b/DataModel/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.datamodel-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/DataModel/nbproject/genfiles.properties b/DataModel/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..1b1b7ff913f6bb74bb04c76a7dce619757e02a6a
--- /dev/null
+++ b/DataModel/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=3fc9375e
+build.xml.script.CRC32=3bd58878
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=c861ba34
+nbproject/build-impl.xml.script.CRC32=b0a13adb
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.2
diff --git a/DataModel/nbproject/project.properties b/DataModel/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6687cb692072c4f4929631a99cce365a408ba514
--- /dev/null
+++ b/DataModel/nbproject/project.properties
@@ -0,0 +1,5 @@
+file.reference.sqlite-jdbc-3.6.20.jar=release/modules/ext/sqlite-jdbc-3.6.20.jar
+file.reference.Tsk_DataModel.jar=release/modules/ext/Tsk_DataModel.jar
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=0.0
diff --git a/DataModel/nbproject/project.xml b/DataModel/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4e76ac79743c3a7949ec78032ff7c8d96fa8d527
--- /dev/null
+++ b/DataModel/nbproject/project.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.datamodel</package>
+                <package>org.sleuthkit.datamodel</package>
+                <package>org.sqlite</package>
+            </public-packages>
+            <class-path-extension>
+                <runtime-relative-path>ext/sqlite-jdbc-3.6.20.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/sqlite-jdbc-3.6.20.jar</binary-origin>
+            </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/Tsk_DataModel.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/Tsk_DataModel.jar</binary-origin>
+            </class-path-extension>
+        </data>
+    </configuration>
+</project>
diff --git a/DataModel/nbproject/suite.properties b/DataModel/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/DataModel/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d50383d1575ec0ab00051bdaf45bd4c97b62fc0
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentChildren.java
@@ -0,0 +1,95 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.datamodel;
+
+import org.openide.nodes.Children.Keys;
+import org.openide.nodes.Node;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.ContentVisitor;
+import org.sleuthkit.datamodel.Directory;
+import org.sleuthkit.datamodel.File;
+import org.sleuthkit.datamodel.FileSystem;
+import org.sleuthkit.datamodel.Image;
+import org.sleuthkit.datamodel.Volume;
+import org.sleuthkit.datamodel.VolumeSystem;
+
+/**
+ * Abstract subclass for ContentChildren and RootContentChildren implementations
+ * that handles creating Nodes from Content objects.
+*/
+abstract class AbstractContentChildren extends Keys<Content> {
+    private static CreateNodeVisitor createNode = new CreateNodeVisitor();
+
+    /**
+     * Uses lazy Content.Keys 
+     */
+    AbstractContentChildren() {
+        super(true); // use lazy behavior
+    }
+
+    @Override
+    protected Node[] createNodes(Content key) {
+        return new Node[]{key.accept(createNode)};
+    }
+    
+    @Override
+    abstract protected void addNotify();
+    
+    @Override
+    abstract protected void removeNotify();
+   
+    
+    /**
+     * Creates appropriate Node for each sub-class of Content
+     */
+    static class CreateNodeVisitor implements ContentVisitor<AbstractContentNode> {
+        
+        @Override
+        public AbstractContentNode visit(Directory drctr) {
+            return new DirectoryNode(drctr);
+        }
+
+        @Override
+        public AbstractContentNode visit(File file) {
+            return new FileNode(file);
+        }
+
+        @Override
+        public AbstractContentNode visit(FileSystem fs) {
+            throw new UnsupportedOperationException("No Node defined for FileSystems.");
+        }
+
+        @Override
+        public AbstractContentNode visit(Image image) {
+            return new ImageNode(image);
+        }
+
+        @Override
+        public AbstractContentNode visit(Volume volume) {
+            return new VolumeNode(volume);
+        }
+
+        @Override
+        public AbstractContentNode visit(VolumeSystem vs) {
+            throw new UnsupportedOperationException("No Node defined for VolumeSystems.");
+        }
+    }
+    
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac8deb19ea9d2fce6848bac3acc9fa46b0639b34
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java
@@ -0,0 +1,243 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.datamodel;
+
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
+import org.openide.nodes.AbstractNode;
+import org.openide.util.lookup.Lookups;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.ContentVisitor;
+import org.sleuthkit.datamodel.Directory;
+import org.sleuthkit.datamodel.File;
+import org.sleuthkit.datamodel.FileSystem;
+import org.sleuthkit.datamodel.Image;
+import org.sleuthkit.datamodel.TskException;
+import org.sleuthkit.datamodel.Volume;
+import org.sleuthkit.datamodel.VolumeSystem;
+
+/**
+ * Interface class that all Data nodes inherit from.
+ * Provides basic information such as ID, parent ID, etc.
+ * @param <T> type of wrapped Content
+ */
+abstract class AbstractContentNode<T extends Content> extends AbstractNode implements ContentNode {
+    /**
+     * Underlying Sleuth Kit Content object
+     */
+    T content;
+    
+    /**
+     * Handles aspects that depend on the Content object
+     * @param content Underlying Content instances
+     */
+    AbstractContentNode(T content) {
+        super(new ContentChildren(content), Lookups.singleton(content));
+        this.content = content;
+        super.setName(content.accept(systemName));
+    }
+    
+    @Override
+    public void setName(String name) {
+        throw new UnsupportedOperationException("Can't change the system name.");
+    }
+    
+    @Override
+    public String getName() {
+        return super.getName();
+    }
+
+    /**
+     * Gets the ID of this node.
+     *
+     * @return ID  the ID of this node
+     */
+    public long getID() {
+        return content.getId();
+    }
+
+    /**
+     * Gets the row values for this node. The main purpose of this method is to
+     * get the 'x' number of the row values for this node to set the width of each
+     * column of the DataResult Table. Row values is the children and it's properties.
+     *
+     * @param rows              the number of rows we want to show
+     * @return rowValues        the row values for this node.
+     * @throws SQLException
+     */
+    abstract public Object[][] getRowValues(int rows) throws SQLException;
+
+    /**
+     * Reads the content of this node.
+     *
+     * @param offset  the starting offset
+     * @param len     the length
+     * @return        the bytes
+     * @throws TskException
+     */
+    public byte[] read(long offset, long len) throws TskException {
+        return content.read(offset, len);
+    }
+
+    /**
+     * Returns the location of the file ID / Metadata address on the columns on
+     * the directory table.
+     *
+     * @return
+     */
+    abstract public int getFileIDColumn();
+    
+    /**
+     * Returns the content of this node.
+     *
+     * @return content  the content of this node (can be image, volume, directory, or file)
+     */
+    public Content getContent() {
+        return content;
+    }
+    
+    private static final ShortNameVisitor shortName = new ShortNameVisitor();
+    
+    private static final GetPathVisitor getDisplayPath = new GetPathVisitor(shortName);
+    
+    /**
+     * Returns full path to this node.
+     *
+     * @return the path of this node
+     */
+    public String[] getDisplayPath() {
+        return content.accept(getDisplayPath).toArray(new String[]{});
+    }
+    
+    private static final SystemNameVisitor systemName = new SystemNameVisitor();
+    
+    private static final GetPathVisitor getSystemPath = new GetPathVisitor(systemName);
+    
+    /**
+     * Returns full path to this node.
+     * 
+     * @return the path of this node
+     */
+    public String[] getSystemPath() {
+        return content.accept(getSystemPath).toArray(new String[]{});
+    }
+    
+    private static class SystemNameVisitor extends ContentVisitor.Default<String> {
+        SystemNameVisitor() {}
+
+        @Override
+        protected String defaultVisit(Content cntnt) {
+            return cntnt.accept(shortName) + ":" + Long.toString(cntnt.getId());
+        }
+    }
+   
+    private static class ShortNameVisitor extends ContentVisitor.Default<String> {
+        ShortNameVisitor() {}
+
+        @Override
+        protected String defaultVisit(Content cntnt) {
+            throw new UnsupportedOperationException("Can't get short name for given content type:" + cntnt.getClass());
+        }
+
+        @Override
+        public String visit(Directory dir) {
+            return DirectoryNode.nameForDirectory(dir);
+        }
+
+        @Override
+        public String visit(File f) {
+            return FileNode.nameForFile(f);
+        }
+
+        @Override
+        public String visit(Volume v) {
+            return VolumeNode.nameForVolume(v);
+        }
+
+        @Override
+        public String visit(Image i) {
+            return ImageNode.nameForImage(i);
+        }
+    }
+    
+    private static class GetPathVisitor implements ContentVisitor<List<String>> { 
+        ContentVisitor<String> toString;
+
+        GetPathVisitor(ContentVisitor<String> toString) {
+            this.toString = toString;
+        }
+
+        @Override
+        public List<String> visit(Directory dir) {
+            List<String> path;
+
+            if (dir.isRoot()) {
+                path = dir.getFileSystem().accept(this);
+            } else {
+                try {
+                    path = dir.getParentDirectory().accept(this);
+                    path.add(toString.visit(dir));
+                } catch (TskException ex) {
+                    throw new RuntimeException("Couldn't get directory path.", ex);
+                }
+            }
+            
+            return path;
+        }
+
+        @Override
+        public List<String> visit(File file) {
+            try {
+                List<String> path = file.getParentDirectory().accept(this);
+                path.add(toString.visit(file));
+                return path;
+            } catch (TskException ex) {
+                throw new RuntimeException("Couldn't get file path.", ex);
+            }
+        }
+
+        @Override
+        public List<String> visit(FileSystem fs) {
+            return fs.getParent().accept(this);
+        }
+
+        @Override
+        public List<String> visit(Image image) {
+           List<String> path = new LinkedList<String>();
+           path.add(toString.visit(image));
+           return path;
+        }
+
+        @Override
+        public List<String> visit(Volume volume) {
+            List<String> path = volume.getParent().accept(this);
+            path.add(toString.visit(volume));
+            return path;
+        }
+
+        @Override
+        public List<String> visit(VolumeSystem vs) {
+            return vs.getParent().accept(this);
+        }
+
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ab314bb2b11b28eef421adf2e37908086143a6f
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
@@ -0,0 +1,73 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import org.openide.nodes.Sheet;
+import org.sleuthkit.datamodel.FsContent;
+
+/**
+ * Abstract class that implements the commonality between File and Directory
+ * Nodes (same properties).
+ */
+abstract class AbstractFsContentNode<T extends FsContent> extends AbstractContentNode<T> {
+
+    /**
+     * Name of the property that holds the name.
+     */
+    public static final String PROPERTY_NAME = "Name";
+    /**
+     * Name of the property that holds the path.
+     */
+    public static final String PROPERTY_LOCATION = "Location";
+
+    AbstractFsContentNode(T fsContent) {
+        super(fsContent);
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        Sheet.Set ss = s.get(Sheet.PROPERTIES);
+        if (ss == null) {
+            ss = Sheet.createPropertiesSet();
+            s.put(ss);
+        }
+
+        // Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed
+        ss.put(new NodeProperty(PROPERTY_NAME, "Name", "no description", content.getName()));
+        ss.put(new NodeProperty(PROPERTY_LOCATION, "Location", "no description", DataConversion.getformattedPath(this.getDisplayPath(), 0)));
+        ss.put(new NodeProperty("Modified Time", "Modified Time", "no description", content.getMtimeAsDate()));
+        ss.put(new NodeProperty("Changed Time", "Changed Time", "no description", content.getCtimeAsDate()));
+        ss.put(new NodeProperty("Access Time", "Access Time", "no description", content.getAtimeAsDate()));
+        ss.put(new NodeProperty("Created Time", "Created Time", "no description", content.getCrtimeAsDate()));
+        ss.put(new NodeProperty("Size", "Size", "no description", content.getSize()));
+        ss.put(new NodeProperty("Flags (Directory)", "Flags (Directory)", "no description", content.getDirFlagsAsString()));
+        ss.put(new NodeProperty("Flags (Meta)", "Flags (Meta)", "no description", content.getMetaFlagsAsString()));
+        ss.put(new NodeProperty("Mode ", "Mode", "no description", content.getModeAsString()));
+        ss.put(new NodeProperty("User ID", "User ID", "no description", content.getUid()));
+        ss.put(new NodeProperty("Group ID", "Group ID", "no description", content.getGid()));
+        ss.put(new NodeProperty("Metadata Address", "Metadata Addr", "no description", content.getMeta_addr()));
+        ss.put(new NodeProperty("Attribute Address", "Attribute Addr", "no description", Long.toString(content.getAttr_type()) + "-" + Long.toString(content.getAttr_id())));
+        ss.put(new NodeProperty("Type (Directory)", "Type (Directory)", "no description", content.getDirTypeAsString()));
+        ss.put(new NodeProperty("Type (Meta)", "Type (Meta)", "no description", content.getMetaTypeAsString()));
+        ss.put(new NodeProperty("Known", "Known", "no description", content.getKnown().getName()));
+
+        return s;
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/DataModel/src/org/sleuthkit/autopsy/datamodel/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..cd313e7b75774b342edce032fd039ab9f84b1c76
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/Bundle.properties
@@ -0,0 +1 @@
+OpenIDE-Module-Name=DataModel
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..710a02efdf6ba1c589284ca76d95108f95e1b38f
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentChildren.java
@@ -0,0 +1,100 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.ContentVisitor;
+import org.sleuthkit.datamodel.Directory;
+import org.sleuthkit.datamodel.FileSystem;
+import org.sleuthkit.datamodel.TskException;
+import org.sleuthkit.datamodel.VolumeSystem;
+
+/**
+ * Class for Children of all ContentNodes. Handles creating child ContentNodes.
+ */
+class ContentChildren extends AbstractContentChildren {
+
+    private Content parent;
+
+    ContentChildren(Content parent) {
+        this.parent = parent;
+    }
+    private static CreateKeysVisitor createKeys = new CreateKeysVisitor();
+
+    @Override
+    protected void addNotify() {
+        setKeys(createKeys.getChildrenKeys(parent));
+    }
+
+    @Override
+    protected void removeNotify() {
+        setKeys(Collections.EMPTY_SET);
+    }
+
+    static private class CreateKeysVisitor extends ContentVisitor.Default<List<? extends Content>> {
+
+        List<Content> getChildrenKeys(Content parent) {
+            List<Content> keys = new ArrayList<Content>();
+
+            List<Content> children;
+
+            try {
+                children = parent.getChildren();
+            } catch (TskException ex) {
+                Log.get(CreateKeysVisitor.class).log(Level.WARNING, "Error getting Content children.", ex);
+                children = Collections.EMPTY_LIST;
+            }
+
+            for (Content c : children) {
+                keys.addAll(c.accept(this));
+            }
+
+            return keys;
+        }
+
+        @Override
+        protected List<Content> defaultVisit(org.sleuthkit.datamodel.Content c) {
+            return Collections.singletonList(c);
+        }
+
+        @Override
+        public List<Content> visit(VolumeSystem vs) {
+            return getChildrenKeys(vs);
+        }
+
+        @Override
+        public List<Content> visit(FileSystem fs) {
+            return getChildrenKeys(fs);
+        }
+
+        @Override
+        public List<? extends Content> visit(Directory dir) {
+            if (dir.isRoot()) {
+                return getChildrenKeys(dir);
+            } else {
+                return Collections.singletonList(dir);
+            }
+        }
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..885bdc51ea21f73261eaad1759b0dd20675f078f
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNode.java
@@ -0,0 +1,105 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.sql.SQLException;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * Interface class that all Data nodes inherit from.
+ * Provides basic information such as ID, parent ID, etc.
+ */
+public interface ContentNode {
+
+    /**
+     * Returns the programmatic name for this node. This is NOT the name to
+     * display to users, or the plain name of the Content object - use
+     * Node.getDisplayName() for that.
+     *
+     * @return name  the programmatic name for this node
+     */
+    public String getName();
+
+    /**
+     * Gets the ID of this node.
+     *
+     * @return ID  the ID of this node
+     */
+    public long getID();
+
+    /**
+     * Gets the row values for this node. The main purpose of this method is to
+     * get the 'x' number of the row values for this node to set the width of each
+     * column of the DataResult Table. Row values is the children and it's properties.
+     *
+     * @param rows              the number of rows we want to show
+     * @return rowValues        the row values for this node.
+     * @throws SQLException
+     */
+    public Object[][] getRowValues(int rows) throws SQLException;
+
+    /**
+     * Reads the content of this node.
+     *
+     * @param offset  the starting offset
+     * @param len     the length
+     * @return        the bytes
+     * @throws TskException
+     */
+    public byte[] read(long offset, long len) throws TskException;
+
+    /**
+     * Returns the location of the file ID / Metadata address on the columns on
+     * the directory table.
+     *
+     * @return
+     */
+    public int getFileIDColumn();
+
+    /**
+     * Returns the content of this node.
+     *
+     * @return content  the content of this node (can be image, volume, directory, or file)
+     */
+    public Content getContent();
+
+    /**
+     * Returns full path to this node.
+     *
+     * @return the path of this node
+     */
+    public String[] getDisplayPath();
+
+    /**
+     * Returns full path to this node.
+     *
+     * @return the path of this node
+     */
+    public String[] getSystemPath();
+
+    /**
+     * Visitor pattern support.
+     * 
+     * @param <T> visitor return type
+     * @param v visitor
+     * @return visitor return value
+     */
+    public <T> T accept(ContentNodeVisitor<T> v);
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e31782487f3909f36a0936c7e78e4338fcc4da7e
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/ContentNodeVisitor.java
@@ -0,0 +1,69 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+/**
+ * Interface for visitor pattern on ContentNodes
+ * @param <T> visit method return type
+ */
+public interface ContentNodeVisitor<T> {
+
+    T visit(DirectoryNode dn);
+
+    T visit(FileNode fn);
+
+    T visit(ImageNode in);
+
+    T visit(VolumeNode vn);
+
+    /**
+     * Visitor with an implementable default behavior for all types. Override
+     * specific visit types to not use the default behavior.
+     * @param <T>
+     */
+    static abstract public class Default<T> implements ContentNodeVisitor<T> {
+
+        /**
+         * Default visit for all types
+         * @param c
+         * @return
+         */
+        protected abstract T defaultVisit(ContentNode c);
+
+        @Override
+        public T visit(DirectoryNode dn) {
+            return defaultVisit(dn);
+        }
+
+        @Override
+        public T visit(FileNode fn) {
+            return defaultVisit(fn);
+        }
+
+        @Override
+        public T visit(ImageNode in) {
+            return defaultVisit(in);
+        }
+
+        @Override
+        public T visit(VolumeNode vn) {
+            return defaultVisit(vn);
+        }
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/DataConversion.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/DataConversion.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4a54cf5a353c22daf5b9e913190cf1644f7479f
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/DataConversion.java
@@ -0,0 +1,189 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.awt.Font;
+import java.util.Arrays;
+
+/**
+ * Helper methods for converting data.
+ */
+public class DataConversion {
+
+    public static String byteArrayToHex(byte[] array, long length, long offset, Font font) {
+        if (array == null) {
+            return "";
+        } else {
+            String base = new String(array);
+            
+            StringBuilder buff = new StringBuilder();
+            int count = 0;
+            int extra = base.length() % 16;
+            String sub = "";
+            char subchar;
+
+            //commented out code can be used as a base for generating hex length based on
+            //offset/length/file size
+            //String hex = Long.toHexString(length + offset);
+            //double hexMax = Math.pow(16, hex.length());
+            double hexMax = Math.pow(16, 6);
+            while (count < base.length() - extra) {
+                buff.append("0x" + Long.toHexString((long) (offset + count + hexMax)).substring(1) + ": ");
+                for (int i = 0; i < 16; i++) {
+                    buff.append(Integer.toHexString((((int) base.charAt(count + i)) & 0xff) + 256).substring(1).toUpperCase() + "  ");
+                    if (i == 7) {
+                        buff.append("  ");
+                    }
+                }
+                sub = base.substring(count, count + 16);
+                for (int i = 0; i < 16; i++) {
+                    subchar = sub.charAt(i);
+                    if (!font.canDisplay(subchar)) {
+                        sub.replace(subchar, '.');
+                    }
+
+                    // replace all unprintable characters with "."
+                    int dec = (int) subchar;
+                    if (dec < 32 || dec > 126) {
+                        sub = sub.replace(subchar, '.');
+                    }
+                }
+                buff.append("  " + sub + "\n");
+                count += 16;
+
+            }
+            if (base.length() % 16 != 0) {
+                buff.append("0x" + Long.toHexString((long) (offset + count + hexMax)).substring(1) + ": ");
+            }
+            for (int i = 0; i < 16; i++) {
+                if (i < extra) {
+                    buff.append(Integer.toHexString((((int) base.charAt(count + i)) & 0xff) + 256).substring(1) + "  ");
+                } else {
+                    buff.append("    ");
+                }
+                if (i == 7) {
+                    buff.append("  ");
+                }
+            }
+            sub = base.substring(count, count + extra);
+            for (int i = 0; i < extra; i++) {
+                subchar = sub.charAt(i);
+                if (!font.canDisplay(subchar)) {
+                    sub.replace(subchar, '.');
+                }
+            }
+            buff.append("  " + sub);
+            return buff.toString();
+        }
+    }
+
+    protected static String charArrayToByte(char[] array) {
+        if (array == null) {
+            return "";
+        } else {
+            String[] binary = new String[array.length];
+
+            for (int i = 0; i < array.length; i++) {
+                binary[i] = Integer.toBinaryString(array[i]);
+            }
+            return Arrays.toString(binary);
+        }
+    }
+
+    /*
+     * Gets only the printable string from the given characters
+     *
+     * The definition of printable are:
+     *  -- All of the letters, numbers, and punctuation.
+     *  -- space and tab
+     *  -- It does NOT include newlines or control chars.
+     *  -- When looking for ASCII strings, they evaluate each byte and when they find four or more printable characters they get printed out with a newline in between each string.
+     *  -- When looking for Unicode strings, they evaluate each two byte sequence and look for four or more printable characters…
+     *
+     * @param args          the bytes that the string read from
+     * @param parameter     the "length" parameter for the string
+     *
+     * @author jantonius
+     */
+    public static String getString(byte[] args, int parameter) {
+
+        /*
+        // these encoding might be needed for later
+        // Note: if not used, can be deleted
+        CharsetEncoder asciiEncoder =
+        Charset.forName("US-ASCII").newEncoder(); // or "ISO-8859-1" for ISO Latin 1
+        
+        CharsetEncoder utf8Encoder =
+        Charset.forName("UTF-8").newEncoder();
+         */
+
+        String result = "";
+        String temp = "";
+        int counter = 0;
+        //char[] converted = new java.lang.System.Text.Encoding.ASCII.GetString(args).ToCharArray();
+
+        char NL = (char) 10; // ASCII char for new line
+
+        for (int i = 0; i < args.length; i++) {
+            char tempChar = (char) args[i];
+            int dec = (int) tempChar;
+
+            // the printable ASCII chars are dec 32-126
+            // and we want to include TAB as well (dec 9)
+            if (!((dec < 32 || dec > 126) && dec != 9)) {
+                temp = temp + Character.toString(tempChar);
+                counter = counter + 1;
+            } else {
+                if (counter >= parameter) {
+                    // add to the result and also add the new line at the end
+                    result = result + temp + Character.toString(NL);
+
+                    // reset the temp and counter
+                    temp = "";
+                    counter = 0;
+                }
+                // reset the temp and counter
+                temp = "";
+                counter = 0;
+            }
+        }
+
+        result = result + temp;
+
+        return result;
+    }
+
+    /**
+     * Converts the given paths into the formatted path. This mainly used for
+     * the paths for the "new directory table" and "new output view".
+     *
+     * @param paths  the given paths
+     * @param index  the starting index of the given paths
+     * @return path  the formatted path
+     *
+     * @author jantonius
+     */
+    public static String getformattedPath(String[] paths, int index) {
+        String result = "";
+        for (int i = index; i < paths.length; i++) {
+            result = result + "\\" + paths[i];
+        }
+        return result;
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d8ac100f0b27b4f2b7b65ca6bc379c517685e24
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/DirectoryNode.java
@@ -0,0 +1,112 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import javax.swing.Action;
+import org.sleuthkit.datamodel.Directory;
+import org.sleuthkit.datamodel.TskData;
+
+/**
+ * This class is used to represent the "Node" for the directory.
+ * Its children are more directories. 
+ */
+public class DirectoryNode extends AbstractFsContentNode<Directory> {
+
+    /**
+     * Helper so that the display name and the name used in building the path
+     * are determined the same way.
+     * @param d Directory to get the name of
+     * @return short name for the directory
+     */
+    static String nameForDirectory(Directory d) {
+        return d.getName();
+    }
+
+    /**
+     * 
+     * @param dir Underlying Content instance
+     */
+    public DirectoryNode(Directory dir) {
+        super(dir);
+
+        // set name, display name, and icon
+        String dirName = nameForDirectory(dir);
+        this.setDisplayName(dirName);
+        if (Directory.dirFlagToValue(dir.getDir_flags()).equals(TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.toString())) {
+            this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-deleted.png");
+        } else {
+            this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png");
+        }
+    }
+
+    /**
+     * Right click action for this node
+     *
+     * @param popup
+     * @return
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+        return new Action[]{};
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) {
+
+        // how many rows are we returning
+        int maxRows = rows;
+        if (this.getChildren().getNodesCount() < maxRows) {
+            maxRows = this.getChildren().getNodesCount();
+        }
+        Object[][] objs = new Object[maxRows][];
+
+        for (int i = 0; i < maxRows; i++) {
+            PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
+            Property[] property = props[0].getProperties();
+            objs[i] = new Object[property.length - 1]; // - 1 because we don't want to show the location property
+
+            // name property
+            try {
+                objs[i][0] = property[0].getValue();
+            } catch (Exception ex) {
+                objs[i][0] = "n/a";
+            }
+
+            // the rest of the properties(not including the location property)
+            for (int j = 1; j < property.length - 1; j++) {
+                try {
+                    objs[i][j] = property[j + 1].getValue();
+                } catch (Exception ex) {
+                    objs[i][j] = "n/a";
+                }
+            }
+        }
+        return objs;
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return 1;
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        return v.visit(this);
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/FileNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/FileNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0105c72f4776518afe497f496c1b7d29176a477e
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/FileNode.java
@@ -0,0 +1,107 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import javax.swing.Action;
+import org.sleuthkit.datamodel.File;
+import org.sleuthkit.datamodel.FsContent;
+import org.sleuthkit.datamodel.TskData;
+
+/**
+ * This class is used to represent the "Node" for the file.
+ * It has no children.
+ *
+ */
+public class FileNode extends AbstractFsContentNode<File> {
+
+    /**
+     * Helper so that the display name and the name used in building the path
+     * are determined the same way.
+     * @param f File to get the name of
+     * @return short name for the File
+     */
+    static String nameForFile(File f) {
+        return f.getName();
+    }
+
+    /**
+     * 
+     * @param file underlying Content
+     */
+    public FileNode(File file) {
+        super(file);
+
+        // set name, display name, and icon
+        String fileName = nameForFile(file);
+        this.setDisplayName(fileName);
+        if (File.dirFlagToValue(file.getDir_flags()).equals(TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.toString())) {
+            this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon-deleted.png");
+        } else {
+            this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-icon.png");
+        }
+    }
+
+    /**
+     * Right click action for this node
+     *
+     * @param popup
+     * @return
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+        return new Action[]{};
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+        FsContent con = content;
+        Object[][] objs = new Object[1][16];
+        Arrays.fill(objs, 0, 1, new Object[]{
+                    con.getName(),
+                    con.getMtimeAsDate(),
+                    con.getCtimeAsDate(),
+                    con.getAtimeAsDate(),
+                    con.getCrtimeAsDate(),
+                    con.getSize(),
+                    con.getDirFlagsAsString(),
+                    con.getMetaFlagsAsString(),
+                    con.getModeAsString(),
+                    con.getUid(),
+                    con.getGid(),
+                    con.getMeta_addr(),
+                    con.getAttr_type() + "-" + con.getAttr_id(),
+                    con.getDirTypeAsString(),
+                    con.getMetaTypeAsString(),
+                    con.getKnown().getName()
+                });
+        return objs;
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return 1; // change this later when it's defined
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        return v.visit(this);
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/ImageNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/ImageNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a2f34362b344027d40a1636d373e90475333b80
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/ImageNode.java
@@ -0,0 +1,130 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.sql.SQLException;
+import javax.swing.Action;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
+import org.sleuthkit.datamodel.Image;
+
+/**
+ * This class is used to represent the "Node" for the image.
+ * The children of this node are volumes.
+ */
+public class ImageNode extends AbstractContentNode<Image> {
+
+    /**
+     * Helper so that the display name and the name used in building the path
+     * are determined the same way.
+     * @param i Image to get the name of
+     * @return short name for the Image
+     */
+    static String nameForImage(Image i) {
+        return i.getName();
+    }
+
+    /**
+     * @param img 
+     */
+    public ImageNode(Image img) {
+        super(img);
+
+        // set name, display name, and icon
+        String imgName = nameForImage(img);
+        this.setDisplayName(imgName);
+        this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hard-drive-icon.jpg");
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+        // how many rows are we returning
+        int maxRows = rows;
+        if (this.getChildren().getNodesCount() < maxRows) {
+            maxRows = this.getChildren().getNodesCount();
+        }
+        Object[][] objs = new Object[maxRows][];
+
+        for (int i = 0; i < maxRows; i++) {
+            PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
+            Property[] property = props[0].getProperties();
+            objs[i] = new Object[property.length];
+
+
+            // the rest of the properties(not including the location property)
+            for (int j = 0; j < property.length; j++) {
+                try {
+                    objs[i][j] = property[j].getValue();
+                } catch (Exception ex) {
+                    objs[i][j] = "n/a";
+                }
+            }
+        }
+        return objs;
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return 0;
+    }
+
+    @Override
+    public Cookie getCookie(Class clazz) {
+        Children ch = getChildren();
+
+        if (clazz.isInstance(ch)) {
+            return (Cookie) ch;
+        }
+
+        return super.getCookie(clazz);
+    }
+
+    /**
+     * Right click action for this node
+     *
+     * @param context
+     * @return
+     */
+    @Override
+    public Action[] getActions(boolean context) {
+        return new Action[]{ //            SystemAction.get( NewAction.class ),
+                //            SystemAction.get( PasteAction.class )
+                };
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        Sheet.Set ss = s.get(Sheet.PROPERTIES);
+        if (ss == null) {
+            ss = Sheet.createPropertiesSet();
+            s.put(ss);
+        }
+
+        ss.put(new NodeProperty("Name", "Name", "no description", ""));
+        // @@@ add more properties here...
+
+        return s;
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        return v.visit(this);
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/Installer.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/Installer.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed065223964017f2c888dc522d94ec2215f2129e
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/Installer.java
@@ -0,0 +1,81 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.awt.Component;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+import org.openide.LifecycleManager;
+import org.openide.modules.ModuleInstall;
+import org.sleuthkit.datamodel.SleuthkitJNI;
+
+/**
+ * Installer checks that the JNI library is working when the module is loaded.
+ */
+public class Installer extends ModuleInstall {
+
+    @Override
+    public void validate() throws IllegalStateException {
+        /*
+         * The NetBeans API specifies that a module should throw an IllegalStateException
+         * if it can't be initalized, but NetBeans doesn't handle that behaviour
+         * well (it just disables the module, and all dependant modules, on the
+         * current and all subsequent application launches). Hence, we deal with
+         * it manually.
+         *
+         */
+
+
+        // Check that the the Sleuth Kit JNI is working by getting the Sleuth Kit version number
+        Logger logger = Logger.getLogger(Installer.class.getName());
+        try {
+            String skVersion = SleuthkitJNI.getVersion();
+
+            if (skVersion == null) {
+                throw new Exception("Sleuth Kit JNI test call returned without error, but version string was null!");
+            } else if (skVersion.length() == 0) {
+                throw new Exception("Sleuth Kit JNI test call returned without error, but version string was \"\"!");
+            } else {
+                logger.log(Level.CONFIG, "Sleuth Kit Version: {0}", skVersion);
+            }
+
+        } catch (Exception e) {
+            logger.log(Level.SEVERE, "Error calling Sleuth Kit library (test call failed)", e);
+
+
+            // Normal error box log handler won't be loaded yet, so show error here.
+            final Component parentComponent = null; // Use default window frame.
+            final String message = "Problem with Sleuth Kit JNI. Test call failed!\n\nDetails: " + e.toString();
+            final String title = "Fatal Error!";
+            final int messageType = JOptionPane.ERROR_MESSAGE;
+
+            JOptionPane.showMessageDialog(
+                    parentComponent,
+                    message,
+                    title,
+                    messageType);
+
+
+            // exit after user exits the error dialog box
+            LifecycleManager.getDefault().exit();
+        }
+
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/NodeProperty.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/NodeProperty.java
new file mode 100644
index 0000000000000000000000000000000000000000..13c91ab436fe7ffb0880c4d1a226f812fa32c450
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/NodeProperty.java
@@ -0,0 +1,43 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.lang.reflect.InvocationTargetException;
+import org.openide.nodes.PropertySupport;
+
+/**
+ * This class is used to represent the properties for each node.
+ *
+ * @author jantonius
+ */
+class NodeProperty extends PropertySupport.ReadOnly {
+
+    private Object value;
+
+    NodeProperty(String name, String displayName, String desc, Object value) {
+        super(name, value.getClass(), displayName, desc);
+        setValue("suppressCustomEditor", Boolean.TRUE); // remove the "..." (editing) button
+        this.value = value;
+    }
+
+    @Override
+    public Object getValue() throws IllegalAccessException, InvocationTargetException {
+        return this.value;
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/RootContentChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/RootContentChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..27e52d9e925c411ba0dbdf09ade1dd1162d1bc53
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/RootContentChildren.java
@@ -0,0 +1,50 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.datamodel;
+
+import java.util.Collection;
+import java.util.Collections;
+import org.sleuthkit.datamodel.Content;
+
+/**
+ * Children implementation for the root node of a ContentNode tree. Accepts a
+ * list of root Content objects for the tree.
+ */
+public class RootContentChildren extends AbstractContentChildren {
+    private Collection<? extends Content> contentKeys;
+    
+    /**
+     * @param contentKeys root Content objects for the Node tree
+     */
+    public RootContentChildren(Collection<? extends Content> contentKeys) {
+        super();
+        this.contentKeys = contentKeys;
+    }
+    
+    @Override
+    protected void addNotify() {
+        setKeys(contentKeys);
+    }
+    
+    @Override
+    protected void removeNotify() {
+        setKeys(Collections.EMPTY_SET);
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf0f06857aa4829ed81b0a77854e5dc34d50cd7f
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/VolumeNode.java
@@ -0,0 +1,134 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.datamodel;
+
+import java.sql.SQLException;
+import javax.swing.Action;
+import org.openide.nodes.Sheet;
+import org.sleuthkit.datamodel.Volume;
+
+/**
+ * This class is used to represent the "Node" for the volume.
+ * Its child is the root directory of a file system
+ */
+public class VolumeNode extends AbstractContentNode<Volume> {
+
+    /**
+     * Helper so that the display name and the name used in building the path
+     * are determined the same way.
+     * @param vol Volume to get the name of
+     * @return short name for the Volume
+     */
+    static String nameForVolume(Volume vol) {
+        return "vol" + Long.toString(vol.getAddr());
+    }
+
+    /**
+     * 
+     * @param vol underlying Content instance
+     */
+    public VolumeNode(Volume vol) {
+        super(vol);
+
+        // set name, display name, and icon
+        String volName = nameForVolume(vol);
+
+        long end = vol.getStart() + vol.getSize();
+        String tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")";
+        this.setDisplayName(tempVolName);
+
+        this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png");
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+
+        // how many rows are we returning
+        int maxRows = rows;
+        if (this.getChildren().getNodesCount() < maxRows) {
+            maxRows = this.getChildren().getNodesCount();
+        }
+        Object[][] objs = new Object[maxRows][];
+
+        for (int i = 0; i < maxRows; i++) {
+            PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
+            Property[] property = props[0].getProperties();
+            objs[i] = new Object[property.length - 1]; // - 1 because we don't want to show the location property
+
+            // name property
+            try {
+                objs[i][0] = property[0].getValue();
+            } catch (Exception ex) {
+                objs[i][0] = "n/a";
+            }
+
+            // the rest of the properties(not including the location property)
+            for (int j = 1; j < property.length - 1; j++) {
+                try {
+                    objs[i][j] = property[j + 1].getValue();
+                } catch (Exception ex) {
+                    objs[i][j] = "n/a";
+                }
+            }
+        }
+        return objs;
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return 1;
+    }
+
+    /**
+     * Right click action for volume node
+     *
+     * @param popup
+     * @return
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+        return new Action[]{ //new ShowDetailAction("Volume Details", this.getName(), this),
+                //new ShowDetailAction("File System Details", this.getName(), this)
+                };
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        Sheet.Set ss = s.get(Sheet.PROPERTIES);
+        if (ss == null) {
+            ss = Sheet.createPropertiesSet();
+            s.put(ss);
+        }
+
+        ss.put(new NodeProperty("Name", "Name", "no description", this.getDisplayName()));
+        ss.put(new NodeProperty("ID", "ID", "no description", content.getAddr()));
+        ss.put(new NodeProperty("Starting Sector", "Starting Sector", "no description", content.getStart()));
+        ss.put(new NodeProperty("Length in Sectors", "Length in Sectors", "no description", content.getLength()));
+        ss.put(new NodeProperty("Description", "Description", "no description", content.getDescription()));
+        ss.put(new NodeProperty("Flags", "Flags", "no description", content.getFlagsAsString()));
+
+        return s;
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        return v.visit(this);
+    }
+}
diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/package.html b/DataModel/src/org/sleuthkit/autopsy/datamodel/package.html
new file mode 100644
index 0000000000000000000000000000000000000000..ce63c11c6d45ca6a09789549a40b9d35d33ddf8d
--- /dev/null
+++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/package.html
@@ -0,0 +1,12 @@
+<body>
+<h2>Overview</h2>
+<p>Autopsy 3 uses NetBeans Nodes to pass data around.  The Sleuth Kit comes with Java datamodel classes in org.sleuthkit.datamodel and it contains classes for files, directories, file systems, volumes, and other data types that can be found in a disk image. These classes are not NetBeans specific. </p>
+
+<p>This package, org.sleuthkit.autopsy.datamodel, contains classes that are NetBeans-specific and map to classes in the Sleuth Kit datamodel.  For example org.sleuthkit.autopsy.datamodel.DirectoryNode is the Node class for the org.sleuthkit.datamodel.Directory class.</p>
+
+<p>ContentNode is the interface class for the data type-specific nodes, just like org.sleuthkit.datamodel.Content is the interface class for the TSK datamodel.  ContentNode provides the standard methods that all nodes must provide. AbstractContentNode implements some of those methods. </p>
+
+<h2>Creating Nodes</h2>
+<p>You should only have to create the root node in a hierarchy.  To do so, use the RootContentChildren class and pass in the list of TSK datamodel objects that you need to encapsulate.  After that, the children will automatically be created as nodes when they are requested.  ContentChildren deals with this.</p>
+
+</body>
\ No newline at end of file
diff --git a/DirectoryTree/build.xml b/DirectoryTree/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..72c3163bdff9f337757666d3885239fd7f9453fb
--- /dev/null
+++ b/DirectoryTree/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.directorytree" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.directorytree.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/DirectoryTree_example.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/DirectoryTree_example.png
new file mode 100644
index 0000000000000000000000000000000000000000..57fa6e100f89af28e72c94dd219665e16e97857d
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/DirectoryTree_example.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/FileSystemDetailHelp.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/FileSystemDetailHelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..01c6c3c67558f1ab1645c5150ff653c274293bd2
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/FileSystemDetailHelp.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/ImageDetailHelp.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/ImageDetailHelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd60598f9ec0a761068ca22bd8d85e3f3c798534
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/ImageDetailHelp.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/VolumeDetailHelp.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/VolumeDetailHelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..984dbacc0a4e798defa857c9f4dce6121594e3b9
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/VolumeDetailHelp.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-about.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..4dc6504dae43a94ddb960654cdf61b7f4ccc990f
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-about.html
@@ -0,0 +1,50 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>About Directory Tree</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About Directory Tree</h2>
+        <p>
+            Directory Tree is one of the main windows in Autopsy. Here, you can see and analyze all the images (also volumes and directories inside that images) which are shown in tree format. You can also see the details of the image, volume, and the file system from directory tree.
+            <br><br>
+        </p>
+
+        <h2>How to Open Directory Tree</h2>
+        <p>
+            To see how to open Directory Tree, click <a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/open-directorytree.html">here</a>.
+            <br><br>
+            <b>Note:</b> The Directory Tree Window is opened and closed automatically. If there's a case opened and there is at least one image inside that case, Directory Tree Window can't be closed.
+            <br><br>
+        </p>
+
+        <h2>How to Use Directory Tree</h2>
+        <p>
+            To see how to use Directory Tree, click <a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/how-to-use-directorytree.html">here</a>.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's an example of a Directory Tree window:
+            &nbsp;&nbsp;<img src="DirectoryTree_example.png" alt="Directory Tree Top Component Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-hs.xml b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-hs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0954595e4bad2d906d5451ba62facbcef6c57a29
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-hs.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN" "http://java.sun.com/products/javahelp/helpset_2_0.dtd">
+<helpset version="2.0">
+    <title>DirectoryTree Help</title>
+    <maps>
+        <homeID>org.sleuthkit.autopsy.directorytree.about</homeID>
+        <mapref location="directorytree-map.xml"/>
+    </maps>
+    <view mergetype="javax.help.AppendMerge">
+        <name>TOC</name>
+        <label>Table of Contents</label>
+        <type>javax.help.TOCView</type>
+        <data>directorytree-toc.xml</data>
+    </view>
+    <view mergetype="javax.help.AppendMerge">
+        <name>Index</name>
+        <label>Index</label>
+        <type>javax.help.IndexView</type>
+        <data>directorytree-idx.xml</data>
+    </view>
+    <view>
+        <name>Search</name>
+        <label>Search</label>
+        <type>javax.help.SearchView</type>
+        <data engine="com.sun.java.help.search.DefaultSearchEngine">JavaHelpSearch</data>
+    </view>
+</helpset>
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35230646f0a4b1534e198f5ff6389a6406a91701
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-idx.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd">
+<index version="2.0">
+    <indexitem text="About Directory Tree" target="org.sleuthkit.autopsy.directorytree.about"/>
+    <indexitem text="How to Open Directory Tree" target="org.sleuthkit.autopsy.directorytree.open-directorytree"/>
+    <indexitem text="How to Use Directory Tree" target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree"/>
+    <indexitem text="Image Details Window" target="org.sleuthkit.autopsy.directorytree.image-details"/>
+    <indexitem text="Volume Details Window" target="org.sleuthkit.autopsy.directorytree.volume-details"/>
+    <indexitem text="File System Details Window" target="org.sleuthkit.autopsy.directorytree.filesystem-details"/>
+</index>
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d8f3b9ce81aa4fb0c48d8b499ac2b1c3c0b7947f
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-map.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE map PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN" "http://java.sun.com/products/javahelp/map_2_0.dtd">
+<map version="2.0">
+    <mapID target="org.sleuthkit.autopsy.directorytree.about" url="directorytree-about.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.open-directorytree" url="open-directorytree.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree" url="how-to-use-directorytree.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.image-details" url="image-details.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.volume-details" url="volume-details.html"/>
+    <mapID target="org.sleuthkit.autopsy.directorytree.filesystem-details" url="filesystem-details.html"/>
+</map>
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-toc.xml b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-toc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ab71cee268f5873716deb2c16d5075fae4b0beb9
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/directorytree-toc.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE toc PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN" "http://java.sun.com/products/javahelp/toc_2_0.dtd">
+<!--
+<toc version="2.0">
+    <tocitem text="DirectoryTree">
+        <tocitem text="About DirectoryTree" target="org.sleuthkit.autopsy.directorytree.about"/>
+        <tocitem text="How to Open Directory Tree" target="org.sleuthkit.autopsy.directorytree.open-directorytree"/>
+        <tocitem text="How to Use Directory Tree" target="org.sleuthkit.autopsy.directorytree.how-to-use-directorytree"/>
+        <tocitem text="Image Details Window" target="org.sleuthkit.autopsy.directorytree.image-details"/>
+        <tocitem text="Volume Details Window" target="org.sleuthkit.autopsy.directorytree.volume-details"/>
+        <tocitem text="File System Details Window" target="org.sleuthkit.autopsy.directorytree.filesystem-details"/>
+    </tocitem>
+</toc>
+-->
\ No newline at end of file
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/filesystem-details.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/filesystem-details.html
new file mode 100644
index 0000000000000000000000000000000000000000..0d83250f7ab342308a389a7e5cd0c892040f715c
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/filesystem-details.html
@@ -0,0 +1,48 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>File System Details Window</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>File System Details Window</h2>
+        <p>
+            File System Details Windows shows the general and detailed information of file system from the selected volume.
+            <br><br>
+        </p>
+
+        <h2>General File System Information</h2>
+        <p>
+            This windows shows the information about file system type, image offset, volume ID, block size, block count, root metadata entry, first metadata entry, and last metadata entry.
+            <br><br>
+        </p>
+
+        <h2>Detailed File System Information</h2>
+        <p>
+            <i>More coming about this information...</i>
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            &nbsp;&nbsp;&nbsp;&nbsp;<img src="FileSystemDetailHelp.png" alt="Example of File System Details Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/how-to-use-directorytree.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/how-to-use-directorytree.html
new file mode 100644
index 0000000000000000000000000000000000000000..4926bad18368d86ee9005fd3b20ca48ce0d1a413
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/how-to-use-directorytree.html
@@ -0,0 +1,54 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>How to Use Directory Tree</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>How to Use Directory Tree</h2>
+        <p>
+            Information on Directory Tree functionality:
+            <br><br>
+            &nbsp; 1. To pass the data and show it on the "Result Viewer". <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To pass the data and show it on the "Result Viewer", select / click the corresponding node on the Directory Tree.
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="node_selected.png" alt="select node on directory tree" />
+            <br><br>
+            &nbsp; 2. To show the "Image Details" <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To see the detail of the image, right click on the image node and select "Image Details".<br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Note:</b> To know more about "Image Detail" window, click <a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/image-details.html">here</a>.
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="rightClick_imageDetails.png" alt="Right click on directory tree to show Image Details" />
+            <br><br>
+            &nbsp; 3. To show the "Volume Details" <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To see the detail of the volume, right click on the volume node and select "Volume Details".<br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Note:</b> To know more about "Volume Detail" window, click <a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/volume-details.html">here</a>.
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="rightClick_volumeDetails.png" alt="Right click on directory tree to show Volume Details" />
+            <br><br>
+            &nbsp; 4. To show the "File System Details" <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To see the detail of the file system of a volume, right click on that volume node and select "File System Details".<br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Note:</b> To know more about "File System Detail" window, click <a href="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/filesystem-details.html">here</a>.
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="rightClick_fileSystemDetails.png" alt="Right click on directory tree to show File System Details" />
+            <br><br>
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/image-details.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/image-details.html
new file mode 100644
index 0000000000000000000000000000000000000000..01c3f4e672be9faa4e8dd5a55dc749500db3db0a
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/image-details.html
@@ -0,0 +1,36 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Image Details Window</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Image Details Window</h2>
+        <p>
+            Image Details Windows shows the information about name, type, and sector size of the selected image.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            &nbsp;&nbsp;&nbsp;&nbsp;<img src="ImageDetailHelp.png" alt="Example of Image Details Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/node_selected.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/node_selected.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf6e31eb56a0b958bcdd60fef40e22d48d9e40ce
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/node_selected.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open-directorytree.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open-directorytree.html
new file mode 100644
index 0000000000000000000000000000000000000000..28812459fff0aebb7c1856aead64ca99f7ec767a
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open-directorytree.html
@@ -0,0 +1,45 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>How to Open Directory Tree</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>How to Open Directory Tree</h2>
+        <p>
+            To open the Directory Tree, you can do one of the following thing:
+            <ul type="circle">
+                <li>
+                    Click the Directory Tree tab.
+                    <br><br>
+                    &nbsp;&nbsp;<img src="open_directoryTree1.png" alt="Open Directory Tree Top Component 1" />
+                    <br><br>
+                </li>
+                <li>
+                    Select the "Tools" -> "Directory Tree"
+                    <br><br>
+                    &nbsp;&nbsp;<img src="open_directoryTree2.png" alt="Open Directory Tree Top Component 2" />
+                    <br><br>
+                </li>
+            </ul>
+
+        <b>Note:</b> The Directory Tree Window is opened and closed automatically. If there's a case opened and there is at least one image inside that case, Directory Tree Window can't be closed.
+    </body>       
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree1.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a25586f31779eb89428367eeb390ca13ffc841c9
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree1.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree2.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree2.png
new file mode 100644
index 0000000000000000000000000000000000000000..f988720bc6be6e5fc2dee476517252a4d24e06df
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/open_directoryTree2.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_fileSystemDetails.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_fileSystemDetails.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa90ba13c1aed398242c3ff6975bf04dcdd0390d
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_fileSystemDetails.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_imageDetails.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_imageDetails.png
new file mode 100644
index 0000000000000000000000000000000000000000..05b922cbd54a65a6f76c579ca136b84914a9dff1
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_imageDetails.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_volumeDetails.png b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_volumeDetails.png
new file mode 100644
index 0000000000000000000000000000000000000000..991eb80dfc48b6b1aac6e76f40078430daec3327
Binary files /dev/null and b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/rightClick_volumeDetails.png differ
diff --git a/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/volume-details.html b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/volume-details.html
new file mode 100644
index 0000000000000000000000000000000000000000..598a30bf40ca8edd6cb8294f7de177b62ac84682
--- /dev/null
+++ b/DirectoryTree/javahelp/org/sleuthkit/autopsy/directorytree/docs/volume-details.html
@@ -0,0 +1,36 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Volume Details Window</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>Volume Details Window</h2>
+        <p>
+            Volume Details Windows shows the information about volume ID, starting sector, the length, description, and flags of the selected volume.
+            <br><br>
+        </p>
+        
+        <h2>Example</h2>
+        <p>
+            &nbsp;&nbsp;&nbsp;&nbsp;<img src="VolumeDetailHelp.png" alt="Example of Volume Details Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/DirectoryTree/manifest.mf b/DirectoryTree/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..3cd61b1c0a41bf40cacaee423fd68432b9611a45
--- /dev/null
+++ b/DirectoryTree/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.directorytree/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/directorytree/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/directorytree/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager, org.netbeans.api.javahelp.Help
+
diff --git a/DirectoryTree/nbproject/build-impl.xml b/DirectoryTree/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3892441abf1983e48f7f8147fce7c1dd3dc6702a
--- /dev/null
+++ b/DirectoryTree/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.directorytree-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/DirectoryTree/nbproject/genfiles.properties b/DirectoryTree/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7c15c292e310fe3902e835da5619d93b8677a864
--- /dev/null
+++ b/DirectoryTree/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=db477856
+build.xml.script.CRC32=6ec7becb
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=db477856
+nbproject/build-impl.xml.script.CRC32=8c5007a7
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/DirectoryTree/nbproject/project.properties b/DirectoryTree/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ad6b9c55802be151d68fada4ffe9890f9978f290
--- /dev/null
+++ b/DirectoryTree/nbproject/project.properties
@@ -0,0 +1,4 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+javahelp.hs=directorytree-hs.xml
+spec.version.base=0.0
diff --git a/DirectoryTree/nbproject/project.xml b/DirectoryTree/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6af52a56ca4c113c905ee3a6544f4c59b6e8f3d8
--- /dev/null
+++ b/DirectoryTree/nbproject/project.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.directorytree</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.15.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.28.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponents</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.directorytree</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/DirectoryTree/nbproject/suite.properties b/DirectoryTree/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/DirectoryTree/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/Bundle.properties b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..de02dec9726bd9956dac4a91e0e286e21c871b19
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/Bundle.properties
@@ -0,0 +1,49 @@
+CTL_DirectoryTreeAction=DirectoryTree
+CTL_DirectoryTreeExplorerAction=DirectoryTreeExplorer
+CTL_DirectoryTreeTopComponent=Directory Tree
+CTL_FileBrowserAction=FileBrowser (new)
+HINT_DirectoryTreeTopComponent=This is a DirectoryTree window
+OpenIDE-Module-Name=DirectoryTree
+FileSystemDetailsPanel.imgOffsetLabel.text=Image Offset:
+FileSystemDetailsPanel.fsTypeLabel.text=FileSystem Type:
+FileSystemDetailsPanel.genInfoLabel.text=General File Information
+FileSystemDetailsPanel.jLabel2.text=bytes
+FileSystemDetailsPanel.jLabel3.text=bytes
+FileSystemDetailsPanel.fsTypeValue.text=...
+FileSystemDetailsPanel.imgOffsetValue.text=...
+FileSystemDetailsPanel.volumeIDValue.text=...
+FileSystemDetailsPanel.blockSizeValue.text=...
+FileSystemDetailsPanel.blockCountValue.text=...
+FileSystemDetailsPanel.rootInumValue.text=...
+FileSystemDetailsPanel.firstInumValue.text=...
+FileSystemDetailsPanel.lastInumValue.text=...
+FileSystemDetailsPanel.jLabel1.text=Detailed File Information
+FileSystemDetailsPanel.volumeIDLabel.text=Volume ID:
+FileSystemDetailsPanel.blockSizeLabel.text=Block Size:
+FileSystemDetailsPanel.blockCountLabel.text=Block Count:
+FileSystemDetailsPanel.rootInumLabel.text=Root Metadata Entry:
+FileSystemDetailsPanel.firstInumLabel.text=First Metadata Entry:
+FileSystemDetailsPanel.lastInumLabel.text=Last Metadata Entry:
+FileSystemDetailsPanel.OKButton.text=OK
+VolumeDetailsPanel.volumeIDLabel.text=Volume ID:
+VolumeDetailsPanel.volumeIDValue.text=...
+VolumeDetailsPanel.startValue.text=...
+VolumeDetailsPanel.lengthValue.text=...
+VolumeDetailsPanel.descValue.text=...
+VolumeDetailsPanel.flagsValue.text=...
+VolumeDetailsPanel.startLabel.text=Starting Sector:
+VolumeDetailsPanel.lengthLabel.text=Length in Sectors:
+VolumeDetailsPanel.descLabel.text=Description:
+VolumeDetailsPanel.flagsLabel.text=Flags:
+VolumeDetailsPanel.jLabel1.text=General Volume Information
+VolumeDetailsPanel.OKButton.text=OK
+ImageDetailsPanel.imageInfoLabel.text=Image Information
+ImageDetailsPanel.imgNameLabel.text=Name:
+ImageDetailsPanel.imgNameValue.text=...
+ImageDetailsPanel.imgTypeLabel.text=Type:
+ImageDetailsPanel.imgTypeValue.text=...
+ImageDetailsPanel.OKButton.text=OK
+ImageDetailsPanel.imgSectorSizeLabel.text=Sector Size:
+ImageDetailsPanel.imgSectorSizeValue.text=...
+DirectoryTreeTopComponent.backButton.text=
+DirectoryTreeTopComponent.forwardButton.text=
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ChangeViewAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ChangeViewAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..6242d633bc85ac8be828ae282b818539162c9a70
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ChangeViewAction.java
@@ -0,0 +1,103 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import org.openide.util.actions.Presenter;
+import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
+import org.sleuthkit.autopsy.corecomponents.DataContentViewerHex;
+import org.sleuthkit.autopsy.corecomponents.DataContentViewerString;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * The actions to change between the "Hex View" and "String View".
+ *
+ * @author jantonius
+ */
+public class ChangeViewAction extends AbstractAction implements Presenter.Popup {
+
+    private int type; // type 1 = hex view, 2 = string view
+    private ContentNode node;
+
+    /** the constructor */
+    public ChangeViewAction(String title, int viewType, ContentNode node) {
+        super(title);
+        this.type = viewType;
+        this.node = node;
+    }
+
+    /**
+     * The action that this class performs. The action is divided into 2 type.
+     * First if the the type is 1, it will change the active output top component
+     * to "Hex View". Another one is if the type is 2, it will change the active
+     * top component to "String View."
+     *
+     * @param e  the action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        DataContentTopComponent dctc = DataContentTopComponent.findInstance();
+        int totalTabs = dctc.getTabPanels().getTabCount();
+
+        // change the output view to hex view
+        if (type == 1) {
+            // find the hex view top component
+//            TopComponent hexWin = WindowManager.getDefault().findTopComponent("HexViewTopComponent"); // Note: HexViewTopComponent = the preffered ID of that top component
+//            hexWin.requestActive(); // set it to become the active top component
+
+            for (int i = 0; i < totalTabs; i++) {
+                if (dctc.getTabPanels().getComponentAt(i) instanceof DataContentViewerHex) {
+                    dctc.getTabPanels().setSelectedIndex(i);
+                }
+            }
+        }
+        // change the output view to string view
+        if (type == 2) {
+            // find the string view top component
+//            TopComponent stringWin = WindowManager.getDefault().findTopComponent("StringViewTopComponent"); // Note: StringViewTopComponent = the preffered ID of that top component
+//            stringWin.requestActive(); // set it to become the active top component
+
+            for (int i = 0; i < totalTabs; i++) {
+                if (dctc.getTabPanels().getComponentAt(i) instanceof DataContentViewerString) {
+                    dctc.getTabPanels().setSelectedIndex(i);
+                }
+            }
+        }
+        // else do nothing
+    }
+
+    /**
+     * To create the sub-menu for "Hex View" and "String View".
+     *
+     * @return menuItem  the menu items
+     */
+    @Override
+    public JMenuItem getPopupPresenter() {
+        JMenu item = new JMenu("View");
+        item.add(new ChangeViewAction("Hex", 1, node));
+        item.add(new ChangeViewAction("String", 2, node));
+        return item;
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/CollapseAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/CollapseAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b18336427fb276120ed1873847ff146e1d15db6
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/CollapseAction.java
@@ -0,0 +1,70 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ *
+ * @author jantonius
+ */
+public class CollapseAction extends AbstractAction {
+
+    CollapseAction(String title) {
+        super(title);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
+        Node[] selectedNode = em.getSelectedNodes();
+
+        // Collapse all
+
+        BeanTreeView tree = DirectoryTreeTopComponent.findInstance().getTree();
+        collapseAll(tree, selectedNode[0]);
+    }
+
+    /**
+     * Collapse all visible children of the given node on the given tree.
+     *
+     * @param tree          the given tree
+     * @param currentNode   the current selectedNode
+     */
+    private void collapseAll(BeanTreeView tree, Node currentNode) {
+
+        Children c = currentNode.getChildren();
+
+        for (Node next : c.getNodes()) {
+            if (tree.isExpanded(next)) {
+                this.collapseAll(tree, next);
+            }
+        }
+
+        tree.collapseNode(currentNode);
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterChildren.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..128889a499a2db9255ffde95169f501c9283c886
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterChildren.java
@@ -0,0 +1,46 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+
+/**
+ * This class is used for the creation of all the children for the
+ * DataResultFilterNode that created in the DataResultFilterNode.java.
+ *
+ * @author jantonius
+ */
+public class DataResultFilterChildren extends FilterNode.Children {
+
+    /** the constructor */
+    public DataResultFilterChildren(Node arg) {
+        super(arg);
+    }
+
+    @Override
+    protected Node copyNode(Node arg0) {
+        return new DataResultFilterNode(arg0);
+    }
+
+    @Override
+    protected Node[] createNodes(Node arg0) {
+        return new Node[]{this.copyNode(arg0)};
+    }
+}
\ No newline at end of file
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..280d32dca4fcd650eeaeac28318461defd8725a0
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java
@@ -0,0 +1,233 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionEvent;
+import java.beans.PropertyVetoException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import org.sleuthkit.autopsy.datamodel.ImageNode;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.datamodel.VolumeNode;
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JPanel;
+import org.openide.explorer.ExplorerManager;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.openide.nodes.Sheet;
+import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * This class wraps nodes as they are passed to the DataResult viewers.  It 
+ * defines the actions that the node should have. 
+ */
+public class DataResultFilterNode extends FilterNode implements ContentNode {
+
+    private Node currentNode;
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** the constructor */
+    public DataResultFilterNode(Node arg) {
+        super(arg, new DataResultFilterChildren(arg));
+        this.currentNode = arg;
+    }
+
+    @Override
+    public Node getOriginal() {
+        return super.getOriginal();
+    }
+
+    /**
+     * Right click action for the nodes that we want to pass to the directory
+     * table and the output view.
+     *
+     * @param popup
+     * @return actionss
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+
+        List<Action> actions = new ArrayList<Action>();
+
+
+        // right click action(s) for image node
+        if (this.currentNode instanceof ImageNode) {
+            actions.add(new NewWindowViewAction("View in New Window", (ImageNode) this.currentNode));
+            actions.addAll(ShowDetailActionVisitor.getActions(((ImageNode) this.currentNode).getContent()));
+        } // right click action(s) for volume node
+        else if (this.currentNode instanceof VolumeNode) {
+            actions.add(new NewWindowViewAction("View in New Window", (VolumeNode) this.currentNode));
+            //new ShowDetailActionVisitor("Volume Details", this.currentNode.getName(), (VolumeNode) this.currentNode),
+            actions.addAll(ShowDetailActionVisitor.getActions(((VolumeNode) this.currentNode).getContent()));
+            actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
+        } // right click action(s) for directory node
+        else if (this.currentNode instanceof DirectoryNode) {
+            actions.add(new NewWindowViewAction("View in New Window", (DirectoryNode) this.currentNode));
+            actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
+            actions.add(new ExtractAction("Extract Directory", (DirectoryNode) this.currentNode));
+        } // right click action(s) for the file node
+        else if (this.currentNode instanceof FileNode) {
+            actions.add(new ExternalViewerAction("Open File in External Viewer", (FileNode) this.currentNode));
+            actions.add(new NewWindowViewAction("View in New Window", (FileNode) this.currentNode));
+            actions.add(new ExtractAction("Extract", (FileNode) this.currentNode));
+            actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
+        }
+
+        return actions.toArray(new Action[actions.size()]);
+    }
+
+    /**
+     * Double click action for the nodes that we want to pass to the directory
+     * table and the output view.
+     *
+     * @return action
+     */
+    @Override
+    public Action getPreferredAction() {
+        // double click action(s) for volume node or directory node
+        if (this.currentNode instanceof VolumeNode || (this.currentNode instanceof DirectoryNode && !this.currentNode.getDisplayName().equals("."))) {
+
+            if (this.currentNode instanceof DirectoryNode && this.currentNode.getDisplayName().equals("..")) {
+                ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
+                Node[] selectedNode = em.getSelectedNodes();
+                Node selectedContext = selectedNode[0];
+                final Node parentNode = selectedContext.getParentNode();
+
+                return new AbstractAction() {
+
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        try {
+                            DirectoryTreeTopComponent.findInstance().getExplorerManager().setSelectedNodes(new Node[]{parentNode});
+                        } catch (PropertyVetoException ex) {
+                            Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
+                            logger.log(Level.WARNING, "Error: can't open the parent directory.", ex);
+                        }
+                    }
+                };
+            } else {
+                ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
+                final Node[] parentNode = em.getSelectedNodes();
+                final Node parentContext = parentNode[0];
+
+                return new AbstractAction() {
+
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        if (parentContext != null) {
+                            ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
+                            for (int i = 0; i < parentContext.getChildren().getNodesCount(); i++) {
+                                Node selectedNode = parentContext.getChildren().getNodeAt(i);
+                                if (selectedNode != null && selectedNode.getName().equals(currentNode.getName())) {
+                                    try {
+                                        em.setExploredContextAndSelection(selectedNode, new Node[]{selectedNode});
+                                    } catch (PropertyVetoException ex) {
+                                        // throw an error here
+                                        Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
+                                        logger.log(Level.WARNING, "Error: can't open the selected directory.", ex);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                };
+            }
+
+        } //        // right click action(s) for the file node
+        //        if(this.currentNode instanceof FileNode){
+        //            // .. put the code here
+        //        }
+        else {
+            return null;
+        }
+    }
+
+    @Override
+    public Node.PropertySet[] getPropertySets() {
+        Node.PropertySet[] propertySets = super.getPropertySets();
+
+        for (int i = 0; i < propertySets.length; i++) {
+            Node.PropertySet ps = propertySets[i];
+
+            if (ps.getName().equals(Sheet.PROPERTIES)) {
+                Sheet.Set newPs = new Sheet.Set();
+                newPs.setName(ps.getName());
+                newPs.setDisplayName(ps.getDisplayName());
+                newPs.setShortDescription(ps.getShortDescription());
+
+                newPs.put(ps.getProperties());
+                newPs.remove(FileNode.PROPERTY_LOCATION);
+                propertySets[i] = newPs;
+            }
+        }
+
+        return propertySets;
+    }
+
+    @Override
+    public long getID() {
+        return ((ContentNode) currentNode).getID();
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+        return ((ContentNode) currentNode).getRowValues(rows);
+    }
+
+    @Override
+    public byte[] read(long offset, long len) throws TskException {
+        return ((ContentNode) currentNode).read(offset, len);
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return ((ContentNode) currentNode).getFileIDColumn();
+    }
+
+    @Override
+    public Content getContent() {
+        return ((ContentNode) currentNode).getContent();
+    }
+
+    @Override
+    public String[] getDisplayPath() {
+        return ((ContentNode) currentNode).getDisplayPath();
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        // TODO: Figure out how visitors should be delegated
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public String[] getSystemPath() {
+        return ((ContentNode) currentNode).getSystemPath();
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterChildren.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f365354e4ec905330c8335232c2ff94728cbbeb
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterChildren.java
@@ -0,0 +1,70 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import org.openide.nodes.Children;
+import org.sleuthkit.autopsy.datamodel.ImageNode;
+import org.sleuthkit.autopsy.datamodel.VolumeNode;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.sleuthkit.datamodel.Directory;
+
+/**
+ * This class wraps around nodes that are displayed in the directory tree and 
+ * hides files, '..', and other children that should not be displayed. 
+ * 
+ * @author jantonius
+ */
+class DirectoryTreeFilterChildren extends FilterNode.Children {
+
+    /** the constructor */
+    public DirectoryTreeFilterChildren(Node arg) {
+        super(arg);
+    }
+
+    @Override
+    protected Node copyNode(Node arg0) {
+        return new DirectoryTreeFilterNode(arg0);
+    }
+
+    @Override
+    protected Node[] createNodes(Node arg0) {
+        // filter out the FileNode and the "." and ".." directories
+        if (arg0 != null && (arg0 instanceof ImageNode
+                || arg0 instanceof VolumeNode || (arg0 instanceof DirectoryNode
+                && !((Directory) ((DirectoryNode) arg0).getContent()).getName().equals(".")
+                && !((Directory) ((DirectoryNode) arg0).getContent()).getName().equals("..")))) {
+            return new Node[]{this.copyNode(arg0)};
+        } else {
+            return new Node[]{};
+        }
+    }
+
+    /**
+     * Return the children based on the current node given. If the node doesn't
+     * have any directory or volume or image node inside it, it just returns leaf.
+     * 
+     * @param arg        the node
+     * @return children  the children
+     */
+    public static Children createInstance(Node arg) {
+        return new DirectoryTreeFilterChildren(arg);
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d23f82ee50e1b1500ba3a15b564c74c9c8763fd
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeFilterNode.java
@@ -0,0 +1,74 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.Action;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.sleuthkit.datamodel.Content;
+
+/**
+ * This class sets the actions for the nodes in the directory tree and creates
+ * the children filter so that files and such are hidden from the tree. 
+ *
+ */
+public class DirectoryTreeFilterNode extends FilterNode {
+
+    private static final Action collapseAll = new CollapseAction("Collapse All");
+
+    /** the constructor */
+    public DirectoryTreeFilterNode(Node arg) {
+        super(arg, DirectoryTreeFilterChildren.createInstance(arg));
+    }
+
+    // TODO This seems bad.  We should have this return the real original and modify code somewhere else to wrap it
+    @Override
+    public Node getOriginal() {
+        return new DataResultFilterNode(super.getOriginal());
+    }
+
+    /**
+     * Right click action for the nodes in the directory tree.
+     *
+     * @param popup
+     * @return
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+        List<Action> actions = new ArrayList<Action>();
+
+        Content content = super.getOriginal().getLookup().lookup(Content.class);
+        if (content != null) {
+            actions.addAll(DirectoryTreeFilterNode.getActions(content));
+            actions.add(collapseAll);
+        }
+
+        return actions.toArray(new Action[actions.size()]);
+    }
+
+    private static List<Action> getActions(Content c) {
+        List<Action> actions = new ArrayList<Action>();
+
+        actions.addAll(ShowDetailActionVisitor.getActions(c));
+
+        return actions;
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form
new file mode 100644
index 0000000000000000000000000000000000000000..f5128e7c560d0735392a05e1c6b8e81b38cc4889
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.form
@@ -0,0 +1,91 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
+              <Component id="backButton" min="-2" pref="26" max="-2" attributes="0"/>
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Component id="forwardButton" min="-2" pref="27" max="-2" attributes="0"/>
+              <EmptySpace pref="199" max="32767" attributes="0"/>
+          </Group>
+          <Component id="jScrollPane1" alignment="0" pref="262" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                  <Component id="forwardButton" min="0" pref="0" max="32767" attributes="1"/>
+                  <Component id="backButton" alignment="0" pref="26" max="32767" attributes="1"/>
+              </Group>
+              <EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
+              <Component id="jScrollPane1" pref="846" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView()"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+    </Container>
+    <Component class="javax.swing.JButton" name="backButton">
+      <Properties>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+          <Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/arrow_left.gif"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.backButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[55, 100]"/>
+        </Property>
+        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[5, 5]"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="backButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="forwardButton">
+      <Properties>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+          <Image iconType="3" name="/org/sleuthkit/autopsy/directorytree/arrow_right.gif"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="DirectoryTreeTopComponent.forwardButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[55, 100]"/>
+        </Property>
+        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[5, 5]"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="forwardButtonActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f691f39e65825464e6b63018518aafd8ce260426
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java
@@ -0,0 +1,643 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.Cursor;
+import java.awt.EventQueue;
+import java.beans.PropertyVetoException;
+import java.io.IOException;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.Action;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.tree.TreeSelectionModel;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.explorer.view.TreeView;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
+import org.sleuthkit.autopsy.datamodel.RootContentChildren;
+
+/**
+ * Top component which displays something.
+ */
+// Registered as a service provider for DataExplorer in layer.xml
+public final class DirectoryTreeTopComponent extends TopComponent implements DataExplorer, ExplorerManager.Provider {
+
+    private transient ExplorerManager em = new ExplorerManager();
+    private static DirectoryTreeTopComponent instance;
+    private DataResultTopComponent dataResult = new DataResultTopComponent(true, "Directory Listing");
+    private boolean backFwdFlag; // flag whether the back or forward button is pressed
+    private ArrayList<Node> backList;
+    private ArrayList<Node> forwardList;
+    /** path to the icon used by the component and its open action */
+//    static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
+    private static final String PREFERRED_ID = "DirectoryTreeTopComponent";
+    private PropertyChangeSupport pcs;
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** the constructor */
+    private DirectoryTreeTopComponent() {
+        initComponents();
+
+        // only allow one item to be selected at a time
+        ((BeanTreeView) jScrollPane1).setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+        // remove the close button
+        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
+        setName(NbBundle.getMessage(DirectoryTreeTopComponent.class, "CTL_DirectoryTreeTopComponent"));
+        setToolTipText(NbBundle.getMessage(DirectoryTreeTopComponent.class, "HINT_DirectoryTreeTopComponent"));
+
+        setListener();
+        associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
+
+
+        this.pcs = new PropertyChangeSupport(this);
+        this.backFwdFlag = false;
+
+        // set the back & forward list and also disable the back & forward button
+        this.backList = new ArrayList<Node>();
+        this.forwardList = new ArrayList<Node>();
+        backButton.setEnabled(false);
+        forwardButton.setEnabled(false);
+    }
+
+    /**
+     * Set the FileBrowserTopComponent as the listener to any property changes
+     * in the Case.java class
+     */
+    private void setListener() {
+        Case.addPropertyChangeListener(this);// add this class to listen to any changes in the Case.java class
+        this.em.addPropertyChangeListener(this);
+    }
+
+    public void setDirectoryListingActive() {
+        this.dataResult.requestActive();
+    }
+
+    public void openDirectoryListing() {
+        this.dataResult.open();
+    }
+
+    public DataResultTopComponent getDirectoryListing() {
+        return this.dataResult;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new BeanTreeView();
+        backButton = new javax.swing.JButton();
+        forwardButton = new javax.swing.JButton();
+
+        backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/arrow_left.gif"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(backButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.backButton.text")); // NOI18N
+        backButton.setMaximumSize(new java.awt.Dimension(55, 100));
+        backButton.setMinimumSize(new java.awt.Dimension(5, 5));
+        backButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                backButtonActionPerformed(evt);
+            }
+        });
+
+        forwardButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/directorytree/arrow_right.gif"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(forwardButton, org.openide.util.NbBundle.getMessage(DirectoryTreeTopComponent.class, "DirectoryTreeTopComponent.forwardButton.text")); // NOI18N
+        forwardButton.setMaximumSize(new java.awt.Dimension(55, 100));
+        forwardButton.setMinimumSize(new java.awt.Dimension(5, 5));
+        forwardButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                forwardButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(4, 4, 4)
+                .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(199, Short.MAX_VALUE))
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 262, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(4, 4, 4)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                    .addComponent(forwardButton, 0, 0, Short.MAX_VALUE)
+                    .addComponent(backButton, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE))
+                .addGap(4, 4, 4)
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 846, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void backButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backButtonActionPerformed
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+//        try {
+        // update the back and forward List
+        int currentIndex = backList.size() - 1;
+        Node currentNode = backList.get(currentIndex);
+        Node newCurrentNode = backList.get(currentIndex - 1);
+        backList.remove(currentIndex);
+        forwardList.add(currentNode);
+
+        // enable / disable the back and forward button
+        if (backList.size() > 1) {
+            backButton.setEnabled(true);
+        } else {
+            backButton.setEnabled(false);
+        }
+        this.forwardButton.setEnabled(true);
+
+        this.backFwdFlag = true; // set the flag
+
+        // update the selection on directory tree
+        try {
+            em.setExploredContextAndSelection(newCurrentNode.getParentNode(), new Node[]{newCurrentNode});
+        } catch (PropertyVetoException ex) {
+            Logger.getLogger(this.className).log(Level.WARNING, "Error: can't go back to the previous selected node.", ex);
+        }
+
+        this.backFwdFlag = false; // reset the flag
+//        }
+//        finally {
+        this.setCursor(null);
+//        }
+    }//GEN-LAST:event_backButtonActionPerformed
+
+    private void forwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_forwardButtonActionPerformed
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+//        try {
+        // update the back and forward List
+        int newCurrentIndex = forwardList.size() - 1;
+        Node newCurrentNode = forwardList.get(newCurrentIndex);
+        forwardList.remove(newCurrentIndex);
+        backList.add(newCurrentNode);
+
+        // enable / disable the back and forward button
+        if (forwardList.size() > 0) {
+            forwardButton.setEnabled(true);
+        } else {
+            forwardButton.setEnabled(false);
+        }
+        this.backButton.setEnabled(true);
+
+        this.backFwdFlag = true; // set the flag
+
+        // update the selection on directory tree
+        try {
+            em.setExploredContextAndSelection(newCurrentNode.getParentNode(), new Node[]{newCurrentNode});
+        } catch (PropertyVetoException ex) {
+            Logger.getLogger(this.className).log(Level.WARNING, "Error: can't go forward to the previous selected node.", ex);
+        }
+
+        this.backFwdFlag = false; // reset the flag
+//        }
+//        finally {
+        this.setCursor(null);
+//    }
+    }//GEN-LAST:event_forwardButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton backButton;
+    private javax.swing.JButton forwardButton;
+    private javax.swing.JScrollPane jScrollPane1;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link #findInstance}.
+     */
+    public static synchronized DirectoryTreeTopComponent getDefault() {
+        if (instance == null) {
+            instance = new DirectoryTreeTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the DirectoryTreeTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized DirectoryTreeTopComponent findInstance() {
+        WindowManager winManager = WindowManager.getDefault();
+        TopComponent win = winManager.findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            Logger.getLogger(DirectoryTreeTopComponent.class.getName()).warning(
+                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof DirectoryTreeTopComponent) {
+            return (DirectoryTreeTopComponent) win;
+        }
+        Logger.getLogger(DirectoryTreeTopComponent.class.getName()).warning(
+                "There seem to be multiple components with the '" + PREFERRED_ID
+                + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    /**
+     * Overwrite when you want to change default persistence type. Default
+     * persistence type is PERSISTENCE_ALWAYS
+     * 
+     * @return TopComponent.PERSISTENCE_ALWAYS
+     */
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    /**
+     * Called only when top component was closed on all workspaces before and
+     * now is opened for the first time on some workspace. The intent is to
+     * provide subclasses information about TopComponent's life cycle across all
+     * existing workspaces. Subclasses will usually perform initializing tasks
+     * here.
+     */
+    @Override
+    public void componentOpened() {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            if (Case.existsCurrentCase()) {
+                Case currentCase = Case.getCurrentCase();
+
+                // close the top component if there's no image in this case
+                if (currentCase.getImageIDs().length == 0) {
+                    //this.close();
+                    ((BeanTreeView) this.jScrollPane1).setRootVisible(false); // hide the root
+                } else {
+                    // if there's at least one image, load the image and open the top component
+                    Node root = new AbstractNode(new RootContentChildren(currentCase.getRootObjects())) {
+
+                        /** to override the right click action in the white blank space
+                         * area on the directory tree window
+                         */
+                        @Override
+                        public Action[] getActions(boolean popup) {
+                            return new Action[]{};
+                        }
+
+                        // Overide the AbstractNode use of DefaultHandle to return
+                        // a handle which can be serialized without a parent
+                        @Override
+                        public Node.Handle getHandle() {
+                            return new Node.Handle() {
+
+                                @Override
+                                public Node getNode() throws IOException {
+                                    return em.getRootContext();
+                                }
+                            };
+                        }
+                    };
+                    /*try {
+                    root = new DirectoryTreeFilterNode(root);
+                    } catch (SQLException ex) {
+                    JOptionPane.showMessageDialog(caller, "Error: problem making directory filter node.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
+                    }*/
+
+
+                    // TODO It seems that we can get rid of the first condition. root is an abstract node
+                    if (root instanceof DirectoryTreeFilterNode) {
+                        root = ((DirectoryTreeFilterNode) root).getOriginal();
+                    } else {
+//                    try {
+                        root = new DirectoryTreeFilterNode(root);
+//                    } catch (SQLException ex) {
+//                        JOptionPane.showMessageDialog(caller, "Error: problem making directory filter node.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
+//                    }
+                    }
+
+                    em.setRootContext(root);
+                    em.getRootContext().setName(currentCase.getName());
+                    em.getRootContext().setDisplayName(currentCase.getName());
+                    ((BeanTreeView) this.jScrollPane1).setRootVisible(false); // hide the root
+
+
+                    Children imageNodes = em.getRootContext().getChildren();
+                    TreeView tree = getTree();
+
+                    // expand until image node
+                    for (Node image : imageNodes.getNodes()) {
+                        tree.expandNode(image);
+                    }
+
+                    // if the dataResult is not opened
+                    if (!dataResult.isOpened()) {
+                        dataResult.open(); // open the data result top component as well when the directory tree is opened
+                    }
+
+
+                    // select the first image node, if there is one
+                    // (this has to happen after dataResult is opened, because the event
+                    // of changing the selected node fires a handler that tries to make
+                    // dataResult active)
+                    if (imageNodes.getNodesCount() > 0) {
+                        try {
+                            em.setSelectedNodes(new Node[]{imageNodes.getNodeAt(0)});
+                        } catch (Exception ex) {
+                            Logger logger = Logger.getLogger(DirectoryTreeTopComponent.class.getName());
+                            logger.log(Level.SEVERE, "Error setting default selected node.", ex);
+                        }
+                    }
+
+                }
+            }
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    /**
+     * Called only when top component was closed so that now it is closed on all
+     * workspaces in the system. The intent is to provide subclasses information
+     * about TopComponent's life cycle across workspaces. Subclasses will usually
+     * perform cleaning tasks here.
+     */
+    @Override
+    public void componentClosed() {
+        //@@@ push the selection node to null?
+    }
+
+    void writeProperties(java.util.Properties p) {
+        // better to version settings since initial version as advocated at
+        // http://wiki.apidesign.org/wiki/PropertyFiles
+        p.setProperty("version", "1.0");
+        // TODO store your settings
+    }
+
+    Object readProperties(java.util.Properties p) {
+        if (instance == null) {
+            instance = this;
+        }
+        instance.readPropertiesImpl(p);
+        return instance;
+    }
+
+    private void readPropertiesImpl(java.util.Properties p) {
+        String version = p.getProperty("version");
+        // TODO read your settings according to their version
+    }
+
+    /**
+     * Returns the unique ID of this TopComponent
+     *
+     * @return PREFERRED_ID  the unique ID of this TopComponent
+     */
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public boolean canClose() {
+        return !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
+    }
+
+    /**
+     * Gets the explorer manager.
+     *
+     * @return the explorer manager
+     */
+    public ExplorerManager getExplorerManager() {
+        return this.em;
+    }
+
+    /**
+     * Right click action for this top component window
+     *
+     * @return actions  the list of actions
+     */
+    @Override
+    public Action[] getActions() {
+        return new Action[]{};
+    }
+
+    /**
+     * Gets the original selected node on the explorer manager
+     *
+     * @return node the original selected Node
+     */
+    // TODO Rename or get rid of it entirely. 
+    public Node getOriginalSelectedNode() {
+        Node result = null;
+
+        Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
+        if (selectedNodes.length > 0) {
+            result = selectedNodes[0];
+            if (result != null && result instanceof DirectoryTreeFilterNode) {
+                result = ((DirectoryTreeFilterNode) result).getOriginal();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * The "listener" that listens to any changes made in the Case.java class.
+     * It will do something based on the changes in the Case.java class.
+     *
+     * @param evt  the property change event
+     */
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        String changed = evt.getPropertyName();
+        Object oldValue = evt.getOldValue();
+        Object newValue = evt.getNewValue();
+
+        // change in the case name
+        if (changed.equals(Case.CASE_NAME)) {
+            // set the main title of the window
+            String oldCaseName = oldValue.toString();
+            String newCaseName = newValue.toString();
+
+
+            // update the case name
+            if ((!oldCaseName.equals("")) && (!newCaseName.equals(""))) {
+                // change the root name and display name
+                em.getRootContext().setName(newCaseName);
+                em.getRootContext().setDisplayName(newCaseName);
+            }
+        }
+        
+        // changed current case
+        if (changed.equals(Case.CASE_CURRENT_CASE)) {
+            
+            // case opened
+            if (newValue != null) {
+                resetHistoryListAndButtons();
+            }
+        }
+
+        // if the image is added to the case
+        if (changed.equals(Case.CASE_ADD_IMAGE)) {
+            componentOpened();
+//            Image img = (Image)newValue;
+//
+//            int[] imageIDs = Case.getCurrentCase().getImageIDs();
+//
+//            // add the first image
+//            if(imageIDs.length == 1){
+//                
+//            }
+//            else{
+//                // add the additional images
+//                ImageNode newNode = new ImageNode(img);
+//                ((ImageChildren)getOriginalRootContent().getChildren()).addNode(newNode);
+//
+//                // expand the new added node
+//                int count = em.getRootContext().getChildren().getNodesCount();
+//                em.setExploredContext(em.getRootContext().getChildren().getNodeAt(count - 1));
+//            }
+        }
+// not supporting deleting images for now
+//        // if the image is removed from the case
+//        if(changed.equals(Case.CASE_DEL_IMAGE)){
+//            if(Case.getCurrentCase().getImageIDs().length > 0){
+//                // just remove the given image from the directory tree
+//                Image img = (Image)newValue;
+//                int ID = Integer.parseInt(oldValue.toString());
+//                ImageNode tempNode = new ImageNode(img);
+//                ((ImageChildren)getOriginalRootContent().getChildren()).removeNode(tempNode);
+//            }
+//        }
+
+        // change in node selection
+        if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
+
+
+            // Some lock that prevents certian Node operations is set during the
+            // ExplorerManager selection-change, so we must handle changes after the
+            // selection-change event is processed.
+            EventQueue.invokeLater(new Runnable() {
+
+                @Override
+                public void run() {
+                    // change the cursor to "waiting cursor" for this operation
+                    DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                    try {
+
+                        // make sure dataResult is open
+                        dataResult.open();
+
+                        ContentNode node = (ContentNode) DirectoryTreeTopComponent.this.getOriginalSelectedNode();
+                        if (node != null) {
+
+                            //pcs.firePropertyChange(DataExplorer.EXPLORER_NODE_SELECTION_CHANGED, "", node);
+                            int count = ((Node) node).getChildren().getNodesCount(true);
+                            if (count > 1000) {
+                                DirectoryTreeTopComponent.this.setCursor(null);
+                                JOptionPane.showMessageDialog(caller, "Note: The selected directory contains " + count + " child files and folders. It may take some time to display them.\n\nAlso note that in the current version of Autopsy this will also make certain functions very slow (thumbnail view in particular, should be fixed in a future version)", "Large Data", JOptionPane.INFORMATION_MESSAGE);
+                                DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                            }
+                            DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                            DirectoryTreeTopComponent.this.dataResult.setNode(node);
+                        }
+
+                        // set the directory listing to be active
+                        dataResult.requestActive();
+                    } finally {
+                        DirectoryTreeTopComponent.this.setCursor(null);
+                    }
+                }
+            });
+
+            // update the back and forward list
+            Node[] selectedNode = em.getSelectedNodes();
+            if (selectedNode.length > 0 && !backFwdFlag) {
+                Node selectedContext = selectedNode[0];
+
+                backList.add(selectedContext); // add the node to the "backList"
+                if (backList.size() > 1) {
+                    backButton.setEnabled(true);
+                } else {
+                    backButton.setEnabled(false);
+                }
+
+                forwardList.clear(); // clear the "forwardList"
+                forwardButton.setEnabled(false); // disable the forward Button
+            }
+        }
+    }
+
+    @Override
+    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+        pcs.addPropertyChangeListener(listener);
+    }
+
+    @Override
+    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+        pcs.removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Resets the back and forward list, and also disable the back and forward
+     * buttons.
+     */
+    private void resetHistoryListAndButtons() {
+        // clear the back and forward list
+        backList.clear();
+        forwardList.clear();
+        backButton.setEnabled(false);
+        forwardButton.setEnabled(false);
+    }
+
+    /**
+     * Gets the tree on this DirectoryTreeTopComponent.
+     *
+     * @return tree  the BeanTreeView
+     */
+    public BeanTreeView getTree() {
+        return (BeanTreeView) this.jScrollPane1;
+    }
+
+    @Override
+    public TopComponent getTopComponent() {
+        return this;
+    }
+//    private class HistoryManager<T> {
+//        private Stack<T> past, future;
+//
+//    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentSettings.xml b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentSettings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c3c9c60090e461fc40f201d489f6dc469d789dc3
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentSettings.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="org.sleuthkit.autopsy.directorytree" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent"/>
+    <instance class="org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent" method="getDefault"/>
+</settings>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentWstcref.xml b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentWstcref.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a33969d893a0477bbe3634795cf050d208cdcdfd
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponentWstcref.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="org.sleuthkit.autopsy.directorytree" spec="1.0"/>
+    <tc-id id="DirectoryTreeTopComponent"/>
+    <state opened="false"/>
+</tc-ref>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b149605d7c7731af85f98a838a3749787d270b8
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java
@@ -0,0 +1,124 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.Desktop;
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ *
+ * @author jantonius
+ */
+public class ExternalViewerAction extends AbstractAction {
+
+    private byte[] content;
+    private FileNode fileNode;
+    private String fileName;
+    private String extension;
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** the constructor */
+    public ExternalViewerAction(String title, FileNode fileNode) {
+        super(title);
+        this.fileNode = fileNode;
+
+        long size = fileNode.getContent().getSize();
+        String fullFileName = ((Node)fileNode).getDisplayName();
+        if (fullFileName.contains(".") && size > 0) {
+            String tempFileName = fullFileName.substring(0, fullFileName.indexOf("."));
+            String tempExtension = fullFileName.substring(fullFileName.indexOf("."));
+            this.fileName = tempFileName;
+            this.extension = tempExtension;
+        } else {
+            this.fileName = fullFileName;
+            this.extension = "";
+            this.setEnabled(false); // fix this later (right now only extract a file with extension)
+        }
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        try {
+            // @@@ Thing to do: maybe throw confirmation first???
+
+            // the menu should be disabled if we can't read the content (for example: on zero-sized file).
+            // Therefore, it should never throw the TSKException.
+            try {
+                this.content = fileNode.getContent().read(0, fileNode.getContent().getSize());
+            } catch (TskException ex) {
+                Logger.getLogger(this.className).log(Level.WARNING, "Error: can't read the content of the file.", ex);
+            }
+
+            // Get the temp folder path of the case
+            String tempPath = Case.getCurrentCase().getTempDirectory();
+            tempPath = tempPath + File.separator + this.fileName + this.extension;
+
+            // create the temporary file
+            File file = new File(tempPath);
+            if (file.exists()) {
+                file.delete();
+            }
+
+            file.createNewFile();
+
+            // convert char to byte
+            byte[] dataSource = new byte[content.length];
+            for (int i = 0; i < content.length; i++) {
+                dataSource[i] = (byte) content[i];
+            }
+
+            FileOutputStream fos = new FileOutputStream(file);
+            //fos.write(dataSource);
+            fos.write(dataSource);
+            fos.close();
+
+            try {
+                Desktop.getDesktop().open(file);
+            } catch (IOException ex) {
+                // if can't open the file, throw the error saying: "File type not supported."
+                JOptionPane.showMessageDialog(caller, "Error: File type not supported.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
+            }
+
+            // delete the file on exit
+            file.deleteOnExit();
+
+        } catch (IOException ex) {
+            // throw an error here
+            Logger.getLogger(this.className).log(Level.WARNING, "Error: can't open the external viewer for this file.", ex);
+        }
+
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1c4adf529f07428c71cb901c08a0bfcb6d4dddd
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExtractAction.java
@@ -0,0 +1,218 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import java.io.*;
+import java.awt.event.ActionEvent;
+import javax.swing.JFileChooser;
+import java.io.File;
+import java.awt.Component;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import javax.swing.JPanel;
+import javax.swing.filechooser.FileFilter;
+import org.openide.nodes.Node;
+import org.sleuthkit.autopsy.casemodule.GeneralFilter;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ * This is an action class to extract and save the bytes given as a file.
+ *
+ * @author jantonius
+ */
+public final class ExtractAction extends AbstractAction {
+
+    private JFileChooser fc = new JFileChooser();
+    private byte[] source;
+    private ContentNode contentNode;
+    private String fileName;
+    private String extension;
+    // for error handling
+    private JPanel caller;
+    private String className = this.getClass().toString();
+
+    /** the constructor */
+    public ExtractAction(String title, ContentNode contentNode) {
+        super(title);
+        
+        String fullFileName = ((Node)contentNode).getDisplayName();
+
+        if (fullFileName.equals(".")) {
+            // . folders are not associated with their children in the database,
+            // so get original
+            Node parentNode = ((Node) contentNode).getParentNode();            
+            this.contentNode = (ContentNode) parentNode;
+            fullFileName = parentNode.getDisplayName();
+        } else {
+            this.contentNode = contentNode;
+        }
+        long size = contentNode.getContent().getSize();
+        
+
+
+        /**
+         * Checks first if the the selected it file or directory. If it's a file,
+         * check if the file size is bigger than 0. If it's a directory, check
+         * if it's not referring to the parent directory. Disables the menu otherwise.
+         */
+        if ((contentNode instanceof FileNode && size > 0) || (contentNode instanceof DirectoryNode && !fullFileName.equals(".."))) {
+            if (contentNode instanceof FileNode && fullFileName.contains(".")) {
+                String tempFileName = fullFileName.substring(0, fullFileName.indexOf("."));
+                String tempExtension = fullFileName.substring(fullFileName.indexOf("."));
+                this.fileName = tempFileName;
+                this.extension = tempExtension;
+            } else {
+                this.fileName = fullFileName;
+                this.extension = "";
+            }
+        } else {
+            this.fileName = fullFileName;
+            this.extension = "";
+            this.setEnabled(false); // can't extract zero-sized file or ".." directory
+        }
+
+    }
+
+    /**
+     * Converts and saves the bytes into the file.
+     *
+     * @param e  the action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+
+        // set the filter for FileNode
+        if (contentNode instanceof FileNode && !extension.equals("")) {
+            //FileFilter filter = new ExtensionFileFilter(extension.substring(1).toUpperCase() + " File (*" + extension + ")", new String[]{extension.substring(1)});
+            String[] fileExt = {extension};
+            FileFilter filter = new GeneralFilter(fileExt, extension.substring(1).toUpperCase() + " File (*" + extension + ")", false);
+            fc.setFileFilter(filter);
+        }
+
+
+        fc.setSelectedFile(new File(this.fileName));
+
+        int returnValue = fc.showSaveDialog((Component) e.getSource());
+        if (returnValue == JFileChooser.APPROVE_OPTION) {
+            String path = fc.getSelectedFile().getPath() + extension;
+
+            try {
+                // file extraction
+                if (contentNode instanceof FileNode) {
+                    extractFile(path, (FileNode) contentNode);
+                }
+
+                // directory extraction
+                if (contentNode instanceof DirectoryNode) {
+                    extractDirectory(path, (DirectoryNode) contentNode);
+                }
+            } catch (Exception ex) {
+                Logger.getLogger(this.className).log(Level.WARNING, "Error: Couldn't extract file/directory.", ex);
+            }
+
+        }
+
+    }
+
+    /**
+     * Extracts the content of the given fileNode into the given path.
+     *
+     * @param givenPath  the path to extract the file
+     * @param fileNode   the file node that contain the file
+     */
+    private void extractFile(String givenPath, FileNode fileNode) throws Exception {
+        try {
+            if (fileNode.getContent().getSize() > 0) {
+                try {
+                    this.source = fileNode.getContent().read(0, fileNode.getContent().getSize());
+                } catch (TskException ex) {
+                    throw new Exception("Error: can't read the content of the file.", ex);
+                }
+            } else {
+                this.source = new byte[0];
+            }
+
+            String path = givenPath;
+
+            File file = new File(path);
+            if (file.exists()) {
+                file.delete();
+            }
+            file.createNewFile();
+            // convert char to byte
+            byte[] dataSource = new byte[source.length];
+            for (int i = 0; i < source.length; i++) {
+                dataSource[i] = (byte) source[i];
+            }
+            FileOutputStream fos = new FileOutputStream(file);
+            //fos.write(dataSource);
+            fos.write(dataSource);
+            fos.close();
+        } catch (IOException ex) {
+            throw new Exception("Error while trying to extract the file.", ex);
+        }
+    }
+
+    /**
+     * Extracts the content of the given directoryNode into the given path.
+     *
+     * @param givenPath  the path to extract the directory
+     * @param dirNode    the directory node that contain the directory
+     */
+    private void extractDirectory(String givenPath, DirectoryNode dirNode) throws Exception {
+        String path = givenPath;
+        File dir = new File(path);
+        if (!dir.exists()) {
+            dir.mkdir();
+        }
+
+        int totalChildren = dirNode.getChildren().getNodesCount();
+        for (int i = 0; i < totalChildren; i++) {
+            Node childNode = dirNode.getChildren().getNodeAt(i);
+
+            if (childNode instanceof FileNode) {
+                FileNode fileNode = (FileNode) childNode;
+                String tempPath = path + File.separator + ((Node)fileNode).getDisplayName();
+                try {
+                    extractFile(tempPath, fileNode);
+                } catch (Exception ex) {
+                    throw ex;
+                }
+            }
+
+            if (childNode instanceof DirectoryNode) {
+                DirectoryNode dirNode2 = (DirectoryNode) childNode;
+                String dirNode2Name = ((Node)dirNode2).getDisplayName();
+                
+                if (!dirNode2Name.trim().equals(".") && !dirNode2Name.trim().equals("..")) {
+                    String tempPath = path + File.separator + dirNode2Name;
+                    extractDirectory(tempPath, dirNode2);
+                }
+            }
+        }
+
+
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..6892af7264a0a6805ec18bde5c628d99458cddd3
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.form
@@ -0,0 +1,384 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace min="-2" pref="367" max="-2" attributes="0"/>
+                      <Component id="OKButton" min="-2" pref="93" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="jSplitPane1" min="-2" pref="786" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jSplitPane1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="OKButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="32767" attributes="1"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JButton" name="OKButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.OKButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Container class="javax.swing.JSplitPane" name="jSplitPane1">
+      <Properties>
+        <Property name="dividerLocation" type="int" value="180"/>
+        <Property name="orientation" type="int" value="0"/>
+      </Properties>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
+      <SubComponents>
+        <Container class="javax.swing.JPanel" name="genInfoPanel">
+          <Properties>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+              <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
+                <EtchetBorder/>
+              </Border>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[815, 170]"/>
+            </Property>
+          </Properties>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+              <JSplitPaneConstraints position="top"/>
+            </Constraint>
+          </Constraints>
+
+          <Layout>
+            <DimensionLayout dim="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="-2" pref="95" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="fsTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="imgOffsetLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="volumeIDLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="blockSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace min="-2" pref="108" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="genInfoLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Group type="102" alignment="0" attributes="0">
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="blockSizeValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="volumeIDValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="imgOffsetValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="fsTypeValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+                                  <Component id="jLabel3" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <EmptySpace min="-2" pref="33" max="-2" attributes="0"/>
+                              <Component id="jSeparator1" min="-2" pref="10" max="-2" attributes="0"/>
+                              <EmptySpace min="-2" pref="31" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="blockCountLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="rootInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="firstInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="lastInumLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <EmptySpace min="-2" pref="111" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="lastInumValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="firstInumValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="rootInumValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="blockCountValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                          </Group>
+                      </Group>
+                      <EmptySpace min="-2" pref="245" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+            </DimensionLayout>
+            <DimensionLayout dim="1">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="1" attributes="0">
+                      <EmptySpace pref="23" max="32767" attributes="0"/>
+                      <Component id="genInfoLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Group type="103" groupAlignment="1" attributes="0">
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Group type="102" alignment="0" attributes="0">
+                                      <Component id="fsTypeLabel" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Component id="imgOffsetLabel" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Component id="volumeIDLabel" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Component id="blockSizeLabel" min="-2" max="-2" attributes="0"/>
+                                  </Group>
+                                  <Group type="102" alignment="0" attributes="0">
+                                      <Component id="fsTypeValue" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Group type="103" groupAlignment="3" attributes="0">
+                                          <Component id="imgOffsetValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                                          <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+                                      </Group>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Component id="volumeIDValue" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                      <Group type="103" groupAlignment="3" attributes="0">
+                                          <Component id="blockSizeValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                                          <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
+                                      </Group>
+                                  </Group>
+                              </Group>
+                              <Group type="102" alignment="1" attributes="0">
+                                  <Component id="blockCountValue" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="rootInumValue" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="firstInumValue" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="lastInumValue" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <Group type="102" alignment="1" attributes="0">
+                                  <Component id="blockCountLabel" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="rootInumLabel" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="firstInumLabel" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                                  <Component id="lastInumLabel" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                          </Group>
+                          <Component id="jSeparator1" pref="101" max="32767" attributes="1"/>
+                      </Group>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+            </DimensionLayout>
+          </Layout>
+          <SubComponents>
+            <Component class="javax.swing.JLabel" name="fsTypeLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.fsTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="imgOffsetLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.imgOffsetLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="volumeIDLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.volumeIDLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="blockSizeLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.blockSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="blockCountLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.blockCountLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="rootInumLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.rootInumLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="firstInumLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.firstInumLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="lastInumLabel">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.lastInumLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="fsTypeValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.fsTypeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="imgOffsetValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.imgOffsetValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="volumeIDValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.volumeIDValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="blockSizeValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.blockSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="blockCountValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.blockCountValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="rootInumValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.rootInumValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="firstInumValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.firstInumValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="lastInumValue">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.lastInumValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="genInfoLabel">
+              <Properties>
+                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+                  <Font name="Tahoma" size="18" style="1"/>
+                </Property>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.genInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JSeparator" name="jSeparator1">
+              <Properties>
+                <Property name="orientation" type="int" value="1"/>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="jLabel2">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+            <Component class="javax.swing.JLabel" name="jLabel3">
+              <Properties>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Container class="javax.swing.JPanel" name="detailInfoPanel">
+          <Properties>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+              <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
+                <EtchetBorder/>
+              </Border>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[516, 293]"/>
+            </Property>
+          </Properties>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+              <JSplitPaneConstraints position="right"/>
+            </Constraint>
+          </Constraints>
+
+          <Layout>
+            <DimensionLayout dim="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="1" attributes="0">
+                      <EmptySpace pref="278" max="32767" attributes="0"/>
+                      <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="276" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+            </DimensionLayout>
+            <DimensionLayout dim="1">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
+                      <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace pref="235" max="32767" attributes="0"/>
+                  </Group>
+              </Group>
+            </DimensionLayout>
+          </Layout>
+          <SubComponents>
+            <Component class="javax.swing.JLabel" name="jLabel1">
+              <Properties>
+                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+                  <Font name="Tahoma" size="18" style="1"/>
+                </Property>
+                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="FileSystemDetailsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..31a51334c9bffcc3e80396f44a2e943b5919f0e7
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/FileSystemDetailsPanel.java
@@ -0,0 +1,367 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionListener;
+
+/**
+ * This is the form / panel to show the File System Details.
+ *
+ * @author jantonius
+ */
+class FileSystemDetailsPanel extends javax.swing.JPanel {
+
+    /** Creates new form FileSystemDetailsPanel */
+    FileSystemDetailsPanel() {
+        initComponents();
+    }
+
+    /** 
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        OKButton = new javax.swing.JButton();
+        jSplitPane1 = new javax.swing.JSplitPane();
+        genInfoPanel = new javax.swing.JPanel();
+        fsTypeLabel = new javax.swing.JLabel();
+        imgOffsetLabel = new javax.swing.JLabel();
+        volumeIDLabel = new javax.swing.JLabel();
+        blockSizeLabel = new javax.swing.JLabel();
+        blockCountLabel = new javax.swing.JLabel();
+        rootInumLabel = new javax.swing.JLabel();
+        firstInumLabel = new javax.swing.JLabel();
+        lastInumLabel = new javax.swing.JLabel();
+        fsTypeValue = new javax.swing.JLabel();
+        imgOffsetValue = new javax.swing.JLabel();
+        volumeIDValue = new javax.swing.JLabel();
+        blockSizeValue = new javax.swing.JLabel();
+        blockCountValue = new javax.swing.JLabel();
+        rootInumValue = new javax.swing.JLabel();
+        firstInumValue = new javax.swing.JLabel();
+        lastInumValue = new javax.swing.JLabel();
+        genInfoLabel = new javax.swing.JLabel();
+        jSeparator1 = new javax.swing.JSeparator();
+        jLabel2 = new javax.swing.JLabel();
+        jLabel3 = new javax.swing.JLabel();
+        detailInfoPanel = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+
+        OKButton.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.OKButton.text")); // NOI18N
+
+        jSplitPane1.setDividerLocation(180);
+        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
+
+        genInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+        genInfoPanel.setPreferredSize(new java.awt.Dimension(815, 170));
+
+        fsTypeLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.fsTypeLabel.text")); // NOI18N
+
+        imgOffsetLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.imgOffsetLabel.text")); // NOI18N
+
+        volumeIDLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.volumeIDLabel.text")); // NOI18N
+
+        blockSizeLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.blockSizeLabel.text")); // NOI18N
+
+        blockCountLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.blockCountLabel.text")); // NOI18N
+
+        rootInumLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.rootInumLabel.text")); // NOI18N
+
+        firstInumLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.firstInumLabel.text")); // NOI18N
+
+        lastInumLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.lastInumLabel.text")); // NOI18N
+
+        fsTypeValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.fsTypeValue.text")); // NOI18N
+
+        imgOffsetValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.imgOffsetValue.text")); // NOI18N
+
+        volumeIDValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.volumeIDValue.text")); // NOI18N
+
+        blockSizeValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.blockSizeValue.text")); // NOI18N
+
+        blockCountValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.blockCountValue.text")); // NOI18N
+
+        rootInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.rootInumValue.text")); // NOI18N
+
+        firstInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.firstInumValue.text")); // NOI18N
+
+        lastInumValue.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.lastInumValue.text")); // NOI18N
+
+        genInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
+        genInfoLabel.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.genInfoLabel.text")); // NOI18N
+
+        jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
+
+        jLabel2.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.jLabel2.text")); // NOI18N
+
+        jLabel3.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.jLabel3.text")); // NOI18N
+
+        javax.swing.GroupLayout genInfoPanelLayout = new javax.swing.GroupLayout(genInfoPanel);
+        genInfoPanel.setLayout(genInfoPanelLayout);
+        genInfoPanelLayout.setHorizontalGroup(
+            genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(genInfoPanelLayout.createSequentialGroup()
+                .addGap(95, 95, 95)
+                .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(fsTypeLabel)
+                    .addComponent(imgOffsetLabel)
+                    .addComponent(volumeIDLabel)
+                    .addComponent(blockSizeLabel))
+                .addGap(108, 108, 108)
+                .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(genInfoLabel)
+                    .addGroup(genInfoPanelLayout.createSequentialGroup()
+                        .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(blockSizeValue)
+                            .addComponent(volumeIDValue)
+                            .addComponent(imgOffsetValue)
+                            .addComponent(fsTypeValue))
+                        .addGap(31, 31, 31)
+                        .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(jLabel2)
+                            .addComponent(jLabel3))
+                        .addGap(33, 33, 33)
+                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(31, 31, 31)
+                        .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(blockCountLabel)
+                            .addComponent(rootInumLabel)
+                            .addComponent(firstInumLabel)
+                            .addComponent(lastInumLabel))
+                        .addGap(111, 111, 111)
+                        .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(lastInumValue)
+                            .addComponent(firstInumValue)
+                            .addComponent(rootInumValue)
+                            .addComponent(blockCountValue))))
+                .addGap(245, 245, 245))
+        );
+        genInfoPanelLayout.setVerticalGroup(
+            genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, genInfoPanelLayout.createSequentialGroup()
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(genInfoLabel)
+                .addGap(18, 18, 18)
+                .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                        .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(genInfoPanelLayout.createSequentialGroup()
+                                .addComponent(fsTypeLabel)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(imgOffsetLabel)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(volumeIDLabel)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(blockSizeLabel))
+                            .addGroup(genInfoPanelLayout.createSequentialGroup()
+                                .addComponent(fsTypeValue)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                                    .addComponent(imgOffsetValue)
+                                    .addComponent(jLabel2))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(volumeIDValue)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addGroup(genInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                                    .addComponent(blockSizeValue)
+                                    .addComponent(jLabel3))))
+                        .addGroup(genInfoPanelLayout.createSequentialGroup()
+                            .addComponent(blockCountValue)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(rootInumValue)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(firstInumValue)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(lastInumValue))
+                        .addGroup(genInfoPanelLayout.createSequentialGroup()
+                            .addComponent(blockCountLabel)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(rootInumLabel)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(firstInumLabel)
+                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                            .addComponent(lastInumLabel)))
+                    .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 89, Short.MAX_VALUE))
+                .addContainerGap())
+        );
+
+        jSplitPane1.setTopComponent(genInfoPanel);
+
+        detailInfoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+        detailInfoPanel.setPreferredSize(new java.awt.Dimension(516, 293));
+
+        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
+        jLabel1.setText(org.openide.util.NbBundle.getMessage(FileSystemDetailsPanel.class, "FileSystemDetailsPanel.jLabel1.text")); // NOI18N
+
+        javax.swing.GroupLayout detailInfoPanelLayout = new javax.swing.GroupLayout(detailInfoPanel);
+        detailInfoPanel.setLayout(detailInfoPanelLayout);
+        detailInfoPanelLayout.setHorizontalGroup(
+            detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, detailInfoPanelLayout.createSequentialGroup()
+                .addContainerGap(278, Short.MAX_VALUE)
+                .addComponent(jLabel1)
+                .addGap(276, 276, 276))
+        );
+        detailInfoPanelLayout.setVerticalGroup(
+            detailInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(detailInfoPanelLayout.createSequentialGroup()
+                .addGap(23, 23, 23)
+                .addComponent(jLabel1)
+                .addContainerGap(259, Short.MAX_VALUE))
+        );
+
+        jSplitPane1.setRightComponent(detailInfoPanel);
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(367, 367, 367)
+                        .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addContainerGap()
+                        .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 786, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(18, 18, 18)
+                .addComponent(OKButton)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * Sets the FileSystem type value on this panel.
+     *
+     * @param arg  the file system type
+     */
+    public void setFileSystemTypeValue(String arg) {
+        fsTypeValue.setText(arg);
+    }
+
+    /**
+     * Sets the image offset value on this panel.
+     *
+     * @param arg  the image offset
+     */
+    public void setImageOffsetValue(String arg) {
+        imgOffsetValue.setText(arg);
+    }
+
+    /**
+     * Sets the volume ID value on this panel.
+     *
+     * @param arg  the volume ID
+     */
+    public void setVolumeIDValue(String arg) {
+        volumeIDValue.setText(arg);
+    }
+
+    /**
+     * Sets the block size value on this panel.
+     *
+     * @param arg the block size value
+     */
+    public void setBlockSizeValue(String arg) {
+        blockSizeValue.setText(arg);
+    }
+
+    /**
+     * Sets the block count value on this panel.
+     *
+     * @param arg  the block count value
+     */
+    public void setBlockCountValue(String arg) {
+        blockCountValue.setText(arg);
+    }
+
+    /**
+     * Sets the root Inum value on this panel.
+     *
+     * @param arg  the root Inum value
+     */
+    public void setRootInumValue(String arg) {
+        rootInumValue.setText(arg);
+    }
+
+    /**
+     * Sets the first Inum value on this panel.
+     *
+     * @param arg  the first Inum value
+     */
+    public void setFirstInumValue(String arg) {
+        firstInumValue.setText(arg);
+    }
+
+    /**
+     * Sets the last Inum value on this panel.
+     *
+     * @param arg  the last Inum value
+     */
+    public void setLastInumValue(String arg) {
+        lastInumValue.setText(arg);
+    }
+
+    /**
+     * Sets the action listener on the OK button on this panel.
+     *
+     * @param e  the action listener
+     */
+    public void setOKButtonActionListener(ActionListener e) {
+        OKButton.addActionListener(e);
+    }
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton OKButton;
+    private javax.swing.JLabel blockCountLabel;
+    private javax.swing.JLabel blockCountValue;
+    private javax.swing.JLabel blockSizeLabel;
+    private javax.swing.JLabel blockSizeValue;
+    private javax.swing.JPanel detailInfoPanel;
+    private javax.swing.JLabel firstInumLabel;
+    private javax.swing.JLabel firstInumValue;
+    private javax.swing.JLabel fsTypeLabel;
+    private javax.swing.JLabel fsTypeValue;
+    private javax.swing.JLabel genInfoLabel;
+    private javax.swing.JPanel genInfoPanel;
+    private javax.swing.JLabel imgOffsetLabel;
+    private javax.swing.JLabel imgOffsetValue;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JSeparator jSeparator1;
+    private javax.swing.JSplitPane jSplitPane1;
+    private javax.swing.JLabel lastInumLabel;
+    private javax.swing.JLabel lastInumValue;
+    private javax.swing.JLabel rootInumLabel;
+    private javax.swing.JLabel rootInumValue;
+    private javax.swing.JLabel volumeIDLabel;
+    private javax.swing.JLabel volumeIDValue;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.form b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..7913ee465fe15415e10b4a0f386265f8277869e7
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.form
@@ -0,0 +1,138 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace min="-2" pref="89" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="imgNameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="imgTypeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="imgSectorSizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="imgNameValue" min="-2" max="-2" attributes="0"/>
+                          <Component id="imgTypeValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="imgSectorSizeValue" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="-2" pref="118" max="-2" attributes="0"/>
+                      <Component id="OKButton" min="-2" pref="80" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="-2" pref="71" max="-2" attributes="0"/>
+                      <Component id="imageInfoLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace pref="75" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="38" max="-2" attributes="0"/>
+              <Component id="imageInfoLabel" 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="imgNameLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="imgTypeLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="imgSectorSizeLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" attributes="0">
+                      <Component id="imgNameValue" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="imgTypeValue" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Component id="imgSectorSizeValue" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace pref="29" max="32767" attributes="0"/>
+              <Component id="OKButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="22" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="imageInfoLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="18" style="1"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imageInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgNameLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgTypeLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgSectorSizeLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgSectorSizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgNameValue">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgNameValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgTypeValue">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgTypeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="imgSectorSizeValue">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.imgSectorSizeValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="OKButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="ImageDetailsPanel.OKButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..eeadbee6d4fe554ed6266c22c88b08af9ea9cc69
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ImageDetailsPanel.java
@@ -0,0 +1,174 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ImageDetailsPanel.java
+ *
+ * Created on May 2, 2011, 3:53:49 PM
+ */
+
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionListener;
+
+/**
+ *
+ * @author jantonius
+ */
+class ImageDetailsPanel extends javax.swing.JPanel {
+
+    /** Creates new form ImageDetailsPanel */
+    ImageDetailsPanel() {
+        initComponents();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        imageInfoLabel = new javax.swing.JLabel();
+        imgNameLabel = new javax.swing.JLabel();
+        imgTypeLabel = new javax.swing.JLabel();
+        imgSectorSizeLabel = new javax.swing.JLabel();
+        imgNameValue = new javax.swing.JLabel();
+        imgTypeValue = new javax.swing.JLabel();
+        imgSectorSizeValue = new javax.swing.JLabel();
+        OKButton = new javax.swing.JButton();
+
+        imageInfoLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
+        imageInfoLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imageInfoLabel.text")); // NOI18N
+
+        imgNameLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgNameLabel.text")); // NOI18N
+
+        imgTypeLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgTypeLabel.text")); // NOI18N
+
+        imgSectorSizeLabel.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgSectorSizeLabel.text")); // NOI18N
+
+        imgNameValue.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgNameValue.text")); // NOI18N
+
+        imgTypeValue.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgTypeValue.text")); // NOI18N
+
+        imgSectorSizeValue.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.imgSectorSizeValue.text")); // NOI18N
+
+        OKButton.setText(org.openide.util.NbBundle.getMessage(ImageDetailsPanel.class, "ImageDetailsPanel.OKButton.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(89, 89, 89)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(imgNameLabel)
+                            .addComponent(imgTypeLabel)
+                            .addComponent(imgSectorSizeLabel))
+                        .addGap(29, 29, 29)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(imgNameValue)
+                            .addComponent(imgTypeValue)
+                            .addComponent(imgSectorSizeValue)))
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(118, 118, 118)
+                        .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(71, 71, 71)
+                        .addComponent(imageInfoLabel)))
+                .addContainerGap(75, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(38, 38, 38)
+                .addComponent(imageInfoLabel)
+                .addGap(18, 18, 18)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(imgNameLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(imgTypeLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(imgSectorSizeLabel))
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(imgNameValue)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(imgTypeValue)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addComponent(imgSectorSizeValue)))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE)
+                .addComponent(OKButton)
+                .addGap(22, 22, 22))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton OKButton;
+    private javax.swing.JLabel imageInfoLabel;
+    private javax.swing.JLabel imgNameLabel;
+    private javax.swing.JLabel imgNameValue;
+    private javax.swing.JLabel imgSectorSizeLabel;
+    private javax.swing.JLabel imgSectorSizeValue;
+    private javax.swing.JLabel imgTypeLabel;
+    private javax.swing.JLabel imgTypeValue;
+    // End of variables declaration//GEN-END:variables
+
+
+    /**
+     * Sets the image name value on this panel.
+     *
+     * @param arg  the new image name value
+     */
+    public void setImgNameValue(String arg){
+        imgNameValue.setText(arg);
+    }
+
+    /**
+     * Sets the image type value on this panel.
+     *
+     * @param arg  the new image type value
+     */
+    public void setImgTypeValue(String arg){
+        imgTypeValue.setText(arg);
+    }
+
+    /**
+     * Sets the image size value on this panel.
+     * 
+     * @param arg  the new image size value
+     */
+    public void setImgSectorSizeValue(String arg){
+        imgSectorSizeValue.setText(arg);
+    }
+
+    /**
+     * Sets the OK button action listener.
+     *
+     * @param e  the action listener
+     */
+    public void setOKButtonActionListener(ActionListener e){
+        OKButton.addActionListener(e);
+    }
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/NewWindowViewAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/NewWindowViewAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..81d40916e70d968937844c759b509241a81a002c
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/NewWindowViewAction.java
@@ -0,0 +1,66 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.AbstractAction;
+import org.openide.windows.Mode;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.datamodel.DataConversion;
+import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
+import org.sleuthkit.autopsy.logging.Log;
+
+/**
+ * Opens new ContentViewer pane in a detached window
+ */
+class NewWindowViewAction extends AbstractAction{
+
+    private ContentNode contentNode ;
+
+    NewWindowViewAction(String title, ContentNode contentNode){
+        super(title);
+        this.contentNode = contentNode;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+        
+        String[] filePaths = this.contentNode.getDisplayPath();
+        String filePath = DataConversion.getformattedPath(filePaths, 0);
+
+        DataContentTopComponent dctc = DataContentTopComponent.createUndocked(filePath, this.contentNode);
+
+        Mode m = WindowManager.getDefault().findMode("output");
+        m.dockInto(dctc);
+        dctc.open();
+
+        // Undocked it (right now, I do it by pressing the "Alt+Shift+D" to undock.
+        // If there's a better way, change the code below..
+        dctc.requestActive();
+        KeyEvent evt = new KeyEvent(dctc, 401, System.currentTimeMillis(), 585, 68, 'D');
+        WindowManager.getDefault().getMainWindow().dispatchEvent(evt);
+    }
+
+    
+
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ShowDetailActionVisitor.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ShowDetailActionVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..84e678cb1e19f20c963a978c64cbf8ad46fc5e45
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ShowDetailActionVisitor.java
@@ -0,0 +1,301 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.directorytree;
+
+import javax.swing.*;
+import java.awt.Toolkit;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import org.sleuthkit.autopsy.logging.Log;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.ContentVisitor;
+import org.sleuthkit.datamodel.FileSystem;
+import org.sleuthkit.datamodel.Image;
+import org.sleuthkit.datamodel.TskException;
+import org.sleuthkit.datamodel.Volume;
+
+/**
+ * 
+ *
+ * @author jantonius
+ */
+class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Action>> {
+    
+    private static ShowDetailActionVisitor instance = new ShowDetailActionVisitor();
+   
+    public static List<Action> getActions(Content c) {
+        List<Action> actions = new ArrayList<Action>();
+        
+        actions.addAll(c.accept(instance));
+        
+        while (c.isOnto()) {
+            try {
+                List<Content> children = c.getChildren();
+                if (!children.isEmpty()) {
+                    c = c.getChildren().get(0);
+                } else {
+                   return actions;
+                }
+            } catch (TskException ex) {
+                Log.get(ShowDetailActionVisitor.class).log(Level.WARNING, "Error getting show detail actions.", ex);
+                return actions;
+            }
+            actions.addAll(c.accept(instance));
+        }
+        return actions;
+    }
+
+    ShowDetailActionVisitor() {}
+
+    @Override
+    public List<? extends Action> visit(final Image img) {
+        final String title = "Image Details";
+
+        return Collections.singletonList(new AbstractAction(title) {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // TODO: fix log action
+                Log.noteAction(this.getClass());
+
+                final JFrame frame = new JFrame(title);
+                final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
+                // if we select the Image Details menu
+
+                Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+
+                // set the popUp window / JFrame
+                popUpWindow.setSize(750, 400);
+
+                int w = popUpWindow.getSize().width;
+                int h = popUpWindow.getSize().height;
+
+                // set the location of the popUp Window on the center of the screen
+                popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
+
+                ImageDetailsPanel imgDetailPanel = new ImageDetailsPanel();
+                Boolean counter = false;
+
+                imgDetailPanel.setImgNameValue(img.getName());
+                imgDetailPanel.setImgTypeValue(Image.imageTypeToString(img.getType()));
+                imgDetailPanel.setImgSectorSizeValue(Long.toString(img.getSsize()));
+                counter = true;
+
+                if (counter) {
+                    // add the volume detail panel to the popUp window
+                    popUpWindow.add(imgDetailPanel);
+                } else {
+                    // error handler if no volume matches
+                    JLabel error = new JLabel("Error: No Volume Matches.");
+                    error.setFont(new Font("Arial", Font.BOLD, 24));
+                    popUpWindow.add(error);
+                }
+
+                // add the command to close the window to the button on the Volume Detail Panel
+                imgDetailPanel.setOKButtonActionListener(new ActionListener() {
+
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        popUpWindow.dispose();
+                    }
+                });
+
+
+                popUpWindow.pack();
+                popUpWindow.setResizable(false);
+                popUpWindow.setVisible(true);
+            }
+        });
+    }
+
+    @Override
+    public List<? extends Action> visit(final FileSystem fs) {
+        final String title = "File System Details";
+
+        return Collections.singletonList(new AbstractAction(title) {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+
+                // TODO: fix log action
+                Log.noteAction(this.getClass());
+
+                final JFrame frame = new JFrame(title);
+                final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
+
+                // set the popUp window / JFrame
+
+                popUpWindow.setSize(1000, 500);
+
+                int w = popUpWindow.getSize().width;
+                int h = popUpWindow.getSize().height;
+
+                // set the location of the popUp Window on the center of the screen
+                popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
+
+                String[] columnNames = new String[]{
+                    "fs_id",
+                    "img_offset",
+                    "par_id",
+                    "fs_type",
+                    "block_size",
+                    "block_count",
+                    "root_inum",
+                    "first_inum",
+                    "last_inum"
+                };
+
+
+
+
+                Object[][] rowValues = new Object[1][9];
+
+                Arrays.fill(rowValues, 0, 1, new Object[]{
+                            fs.getId(),
+                            fs.getImg_offset(),
+                            fs.getParent().getId(),
+                            fs.getFs_type(),
+                            fs.getBlock_size(),
+                            fs.getBlock_count(),
+                            fs.getRoot_inum(),
+                            fs.getFirst_inum(),
+                            fs.getLast_inum()
+                        });
+
+
+                JTable table = new JTable(new DefaultTableModel(rowValues, columnNames));
+
+                FileSystemDetailsPanel fsdPanel = new FileSystemDetailsPanel();
+
+                // add the command to close the window to the button on the Volume Detail Panel
+                fsdPanel.setOKButtonActionListener(new ActionListener() {
+
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        popUpWindow.dispose();
+                    }
+                });
+
+                try {
+                    fsdPanel.setFileSystemTypeValue(table.getValueAt(0, 3).toString());
+                    fsdPanel.setImageOffsetValue(table.getValueAt(0, 1).toString());
+                    fsdPanel.setVolumeIDValue(table.getValueAt(0, 2).toString());  //TODO: fix this to parent id, not vol id
+                    fsdPanel.setBlockSizeValue(table.getValueAt(0, 4).toString());
+                    fsdPanel.setBlockCountValue(table.getValueAt(0, 5).toString());
+                    fsdPanel.setRootInumValue(table.getValueAt(0, 6).toString());
+                    fsdPanel.setFirstInumValue(table.getValueAt(0, 7).toString());
+                    fsdPanel.setLastInumValue(table.getValueAt(0, 8).toString());
+
+                    popUpWindow.add(fsdPanel);
+                } catch (Exception ex) {
+                    Log.get(ShowDetailActionVisitor.class).log(Level.WARNING, "Error setting up File System Details panel.", ex);
+                }
+
+                popUpWindow.pack();
+                popUpWindow.setResizable(false);
+                popUpWindow.setVisible(true);
+
+            }
+        });
+    }
+
+    @Override
+    public List<? extends Action> visit(final Volume vol) {
+        final String title = "Volume Details";
+
+        return Collections.singletonList(new AbstractAction(title) {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+
+                // TODO: fix log action
+                Log.noteAction(this.getClass());
+
+                final JFrame frame = new JFrame(title);
+                final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
+
+
+                Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+
+                // set the popUp window / JFrame
+                popUpWindow.setSize(800, 400);
+
+                int w = popUpWindow.getSize().width;
+                int h = popUpWindow.getSize().height;
+
+                // set the location of the popUp Window on the center of the screen
+                popUpWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
+
+                VolumeDetailsPanel volumeDetailPanel = new VolumeDetailsPanel();
+                Boolean counter = false;
+
+                volumeDetailPanel.setVolumeIDValue(Long.toString(vol.getAddr()));
+                volumeDetailPanel.setStartValue(Long.toString(vol.getStart()));
+                volumeDetailPanel.setLengthValue(Long.toString(vol.getLength()));
+                volumeDetailPanel.setDescValue(vol.getDescription());
+                volumeDetailPanel.setFlagsValue(vol.getFlagsAsString());
+                counter = true;
+
+                if (counter) {
+                    // add the volume detail panel to the popUp window
+                    popUpWindow.add(volumeDetailPanel);
+                } else {
+                    // error handler if no volume matches
+                    JLabel error = new JLabel("Error: No Volume Matches.");
+                    error.setFont(new Font("Arial", Font.BOLD, 24));
+                    popUpWindow.add(error);
+                }
+
+                // add the command to close the window to the button on the Volume Detail Panel
+                volumeDetailPanel.setOKButtonActionListener(new ActionListener() {
+
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        popUpWindow.dispose();
+                    }
+                });
+
+
+                popUpWindow.pack();
+                popUpWindow.setResizable(false);
+                popUpWindow.setVisible(true);
+
+            }
+        });
+    }
+
+    @Override
+    protected List<? extends Action> defaultVisit(Content c) {
+        return Collections.EMPTY_LIST;
+    }
+}
\ No newline at end of file
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.form b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..5c73074beb305b49f9dee75feab1b6f076318ce5
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.form
@@ -0,0 +1,215 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <Component id="jPanel1" max="32767" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="OKButton" min="-2" pref="100" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="145" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Component id="jPanel1" max="32767" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="OKButton" min="-2" pref="23" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="-2" pref="112" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Component id="startLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="volumeIDLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="lengthLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="descLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                              <Component id="flagsLabel" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Component id="flagsValue" min="-2" max="-2" attributes="0"/>
+                              <Component id="descValue" min="-2" max="-2" attributes="0"/>
+                              <Component id="lengthValue" min="-2" max="-2" attributes="0"/>
+                              <Component id="startValue" min="-2" max="-2" attributes="0"/>
+                              <Component id="volumeIDValue" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="-2" pref="59" max="-2" attributes="0"/>
+                          <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <EmptySpace pref="58" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="jLabel1" min="-2" pref="35" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="volumeIDLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="volumeIDValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="startLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="startValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="lengthLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="lengthValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Group type="102" attributes="0">
+                          <Component id="descLabel" min="-2" pref="14" max="-2" attributes="0"/>
+                          <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="flagsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="flagsValue" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                      <Group type="102" alignment="1" attributes="0">
+                          <Component id="descValue" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <EmptySpace pref="15" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="flagsValue">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.flagsValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="descValue">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.descValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="lengthValue">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.lengthValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="startValue">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.startValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="startLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.startLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="lengthLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.lengthLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel1">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="18" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="volumeIDLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.volumeIDLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="VolumeDetailsPanel_volumeIDLabel"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JLabel" name="volumeIDValue">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.volumeIDValue.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="descLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.descLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="flagsLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.flagsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="OKButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/directorytree/Bundle.properties" key="VolumeDetailsPanel.OKButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a4aa9660f8e64837cfe0e537c184c289f04f1ad
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/VolumeDetailsPanel.java
@@ -0,0 +1,205 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.directorytree;
+
+import java.awt.event.ActionListener;
+
+
+/**
+ * This is the form / panel to show the Volume Details.
+ */
+class VolumeDetailsPanel extends javax.swing.JPanel {
+
+    /** Creates new form VolumeDetailPanel */
+    VolumeDetailsPanel() {
+        initComponents();
+    }
+
+    /** 
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always 
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        flagsValue = new javax.swing.JLabel();
+        descValue = new javax.swing.JLabel();
+        lengthValue = new javax.swing.JLabel();
+        startValue = new javax.swing.JLabel();
+        startLabel = new javax.swing.JLabel();
+        lengthLabel = new javax.swing.JLabel();
+        jLabel1 = new javax.swing.JLabel();
+        volumeIDLabel = new javax.swing.JLabel();
+        volumeIDValue = new javax.swing.JLabel();
+        descLabel = new javax.swing.JLabel();
+        flagsLabel = new javax.swing.JLabel();
+        OKButton = new javax.swing.JButton();
+
+        flagsValue.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.flagsValue.text")); // NOI18N
+
+        descValue.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.descValue.text")); // NOI18N
+
+        lengthValue.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.lengthValue.text")); // NOI18N
+
+        startValue.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.startValue.text")); // NOI18N
+
+        startLabel.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.startLabel.text")); // NOI18N
+
+        lengthLabel.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.lengthLabel.text")); // NOI18N
+
+        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 18));
+        jLabel1.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.jLabel1.text")); // NOI18N
+
+        volumeIDLabel.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.volumeIDLabel.text")); // NOI18N
+
+        volumeIDValue.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.volumeIDValue.text")); // NOI18N
+
+        descLabel.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.descLabel.text")); // NOI18N
+
+        flagsLabel.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.flagsLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addGap(112, 112, 112)
+                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(startLabel)
+                            .addComponent(volumeIDLabel)
+                            .addComponent(lengthLabel)
+                            .addComponent(descLabel)
+                            .addComponent(flagsLabel))
+                        .addGap(18, 18, 18)
+                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(flagsValue)
+                            .addComponent(descValue)
+                            .addComponent(lengthValue)
+                            .addComponent(startValue)
+                            .addComponent(volumeIDValue)))
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addGap(59, 59, 59)
+                        .addComponent(jLabel1)))
+                .addContainerGap(58, Short.MAX_VALUE))
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(11, 11, 11)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(volumeIDLabel)
+                    .addComponent(volumeIDValue))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(startLabel)
+                    .addComponent(startValue))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(lengthLabel)
+                    .addComponent(lengthValue))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addComponent(descLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                            .addComponent(flagsLabel)
+                            .addComponent(flagsValue)))
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addComponent(descValue)
+                        .addGap(25, 25, 25)))
+                .addContainerGap(15, Short.MAX_VALUE))
+        );
+
+        OKButton.setText(org.openide.util.NbBundle.getMessage(VolumeDetailsPanel.class, "VolumeDetailsPanel.OKButton.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addContainerGap())
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(145, 145, 145))))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addGap(18, 18, 18)
+                .addComponent(OKButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap())
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    public void setVolumeIDValue(String arg){
+        volumeIDValue.setText(arg);
+    }
+
+    public void setStartValue(String arg){
+        startValue.setText(arg);
+    }
+
+    public void setLengthValue(String arg){
+        lengthValue.setText(arg);
+    }
+
+    public void setDescValue(String arg){
+        descValue.setText(arg);
+    }
+
+    public void setFlagsValue(String arg){
+        flagsValue.setText(arg);
+    }
+
+    public void setOKButtonActionListener(ActionListener e){
+        OKButton.addActionListener(e);
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton OKButton;
+    private javax.swing.JLabel descLabel;
+    private javax.swing.JLabel descValue;
+    private javax.swing.JLabel flagsLabel;
+    private javax.swing.JLabel flagsValue;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JLabel lengthLabel;
+    private javax.swing.JLabel lengthValue;
+    private javax.swing.JLabel startLabel;
+    private javax.swing.JLabel startValue;
+    private javax.swing.JLabel volumeIDLabel;
+    private javax.swing.JLabel volumeIDValue;
+    // End of variables declaration//GEN-END:variables
+
+}
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_left.gif b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_left.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d0d85dba4b9abc810f454a014fafc142f97f5f16
Binary files /dev/null and b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_left.gif differ
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_right.gif b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_right.gif
new file mode 100644
index 0000000000000000000000000000000000000000..85272ad99cc0df252748b08468d0649a9c90fcda
Binary files /dev/null and b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/arrow_right.gif differ
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/back-button.png b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/back-button.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6c02aa3dd41f715b488ee3ac11425ccf12a0142
Binary files /dev/null and b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/back-button.png differ
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/directorytree-helpset.xml b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/directorytree-helpset.xml
new file mode 100644
index 0000000000000000000000000000000000000000..70b8cfd113dbc8926d2e69138cd84bdc075ecf4f
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/directorytree-helpset.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpsetref PUBLIC "-//NetBeans//DTD JavaHelp Help Set Reference 1.0//EN" "http://www.netbeans.org/dtds/helpsetref-1_0.dtd">
+<helpsetref url="nbdocs:/org/sleuthkit/autopsy/directorytree/docs/directorytree-hs.xml"/>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/explorerWsmode.xml b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/explorerWsmode.xml
new file mode 100644
index 0000000000000000000000000000000000000000..92b65d8d47da9cc9792b43565e0c342b37b30eb9
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/explorerWsmode.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE mode PUBLIC
+          "-//NetBeans//DTD Mode Properties 2.0//EN"
+          "http://www.netbeans.org/dtds/mode-properties2_0.dtd">
+
+<mode version="2.0">
+    <module name="org.netbeans.core.ui/1" spec="1.2" />
+    <name unique="explorer" />
+    <kind type="view" />
+    <state type="joined" />
+    <constraints>
+        <path orientation="horizontal" number="20" weight="0.3" />
+        <path orientation="vertical" number="20" weight="0.5" />
+    </constraints>
+    <relative-bounds x="10" y="22" width="32" height="50" />
+    <empty-behavior permanent="true" />
+</mode>
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/forward-button.png b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/forward-button.png
new file mode 100644
index 0000000000000000000000000000000000000000..f89271f1485ca4835f407c4635fe84363877a866
Binary files /dev/null and b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/forward-button.png differ
diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/layer.xml b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3b34adc2d7b42c2be879e0c2262327eb91f21065
--- /dev/null
+++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/layer.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Window">
+            <!--<file name="org-sleuthkit-autopsy-directorytree-DirectoryTreeAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.directorytree.Bundle#CTL_DirectoryTreeAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>-->
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <!--<file name="DirectoryTreeAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/org-sleuthkit-autopsy-directorytree-DirectoryTreeAction.instance"/>
+            </file>-->
+        </folder>
+    </folder>
+    <folder name="Services">
+        <folder name="JavaHelp">
+            <file name="directorytree-helpset.xml" url="directorytree-helpset.xml">
+                <attr name="position" intvalue="3086"/>
+            </file>
+        </folder>
+        <file name="org-sleuthkit-autopsy-directorytree-DirectoryTreeTopComponent.instance">
+            <attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer"/>
+            <attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent.getDefault"/>
+        </file>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="DirectoryTreeTopComponent.settings" url="DirectoryTreeTopComponentSettings.xml"/>
+        </folder>
+        <!-- Not letting NetBeans manage docking for us at all. It's all handled in CoreComponentInterfaces:CoreComponentControl
+        <folder name="Modes">
+            <folder name="explorer">
+                <file name="DirectoryTreeTopComponent.wstcref" url="DirectoryTreeTopComponentWstcref.xml"/>
+            </folder>
+            <file name="explorer.wsmode" url="explorerWsmode.xml"/>
+        </folder-->
+    </folder>
+</filesystem>
diff --git a/FileSearch/build.xml b/FileSearch/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..78e6fe7c494bc8efede68d924934fc9bd53a6314
--- /dev/null
+++ b/FileSearch/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.filesearch" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.filesearch.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_example.png b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_example.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9cb8a80f2b73946c2626c67d495d77c56f9a2d1
Binary files /dev/null and b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_example.png differ
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_usage.png b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_usage.png
new file mode 100644
index 0000000000000000000000000000000000000000..33072549c19123ed1ea25bc1b75b92890aa7eb08
Binary files /dev/null and b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/FileSearch_usage.png differ
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-about.html b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-about.html
new file mode 100644
index 0000000000000000000000000000000000000000..f47136dbbb29a01c4b77bd073e13fc35883abb32
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-about.html
@@ -0,0 +1,54 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>About File Search</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>About File Search</h2>
+        <p>
+            File Search is one of the main windows in Autopsy.
+            By using File Search, you can specify, filter, and show the directories and files that you want to see from the images in the current opened case.
+            <br><br>
+            Currently, Autopsy only supports 3 categories in File Search: Name, Size, and Date based search.<br>
+            <b>Note</b>: For now, Autopsy doesn't support keyword search and regular expression.
+            <br><br>
+        </p>
+
+        <h2>How to Open File Search</h2>
+        <p>
+            To see how to open File Search, click <a href="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html">here</a>.
+            <br><br>
+            <b>Note:</b> The File Search Window is opened and closed automatically. If there's a case opened and there is at least one image inside that case, File Search Window can't be closed.
+            <br><br>
+        </p>
+
+        <h2>How to Use File Search</h2>
+        <p>
+            To see how to use File Search, click <a href="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/how-to-use-filesearch.html">here</a>.
+            <br><br>
+        </p>
+
+        <h2>Example</h2>
+        <p>
+            Here's an example of a File Search window:
+            &nbsp;&nbsp;<img src="FileSearch_example.png" alt="File Search Top Component Window" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-hs.xml b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-hs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..13bffc15c5972c776f17d8630d0fbd5a14e6a6e9
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-hs.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 2.0//EN" "http://java.sun.com/products/javahelp/helpset_2_0.dtd">
+<helpset version="2.0">
+    <title>FileSearch Help</title>
+    <maps>
+        <homeID>org.sleuthkit.autopsy.filesearch.about</homeID>
+        <mapref location="filesearch-map.xml"/>
+    </maps>
+    <view mergetype="javax.help.AppendMerge">
+        <name>TOC</name>
+        <label>Table of Contents</label>
+        <type>javax.help.TOCView</type>
+        <data>filesearch-toc.xml</data>
+    </view>
+    <view mergetype="javax.help.AppendMerge">
+        <name>Index</name>
+        <label>Index</label>
+        <type>javax.help.IndexView</type>
+        <data>filesearch-idx.xml</data>
+    </view>
+    <view>
+        <name>Search</name>
+        <label>Search</label>
+        <type>javax.help.SearchView</type>
+        <data engine="com.sun.java.help.search.DefaultSearchEngine">JavaHelpSearch</data>
+    </view>
+</helpset>
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-idx.xml b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-idx.xml
new file mode 100644
index 0000000000000000000000000000000000000000..34807378c23f9326dc3d71211242fe7df4362524
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-idx.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 2.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd">
+<index version="2.0">
+    <indexitem text="About FileSearch" target="org.sleuthkit.autopsy.filesearch.about"/>
+    <indexitem text="How to Open FileSearch" target="org.sleuthkit.autopsy.filesearch.open-filesearch"/>
+    <indexitem text="How to Use FileSearch" target="org.sleuthkit.autopsy.filesearch.how-to-use-filesearch"/>
+</index>
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-map.xml b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-map.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ee1c91f8c3ed241383f6b063dc6163eedc64ad62
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-map.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE map PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN" "http://java.sun.com/products/javahelp/map_2_0.dtd">
+<map version="2.0">
+    <mapID target="org.sleuthkit.autopsy.filesearch.about" url="filesearch-about.html"/>
+</map>
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-toc.xml b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-toc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bc5d1b9d058458dd90a9702794cf742263ee6187
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/filesearch-toc.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE toc PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN" "http://java.sun.com/products/javahelp/toc_2_0.dtd">
+<!--
+<toc version="2.0">
+    <tocitem text="FileSearch">
+        <tocitem text="About FileSearch" target="org.sleuthkit.autopsy.filesearch.about"/>
+    </tocitem>
+</toc>
+-->
\ No newline at end of file
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/how-to-use-filesearch.html b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/how-to-use-filesearch.html
new file mode 100644
index 0000000000000000000000000000000000000000..5d7839f9f959fa4375ba1ab1b5999ec6f9ed48a3
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/how-to-use-filesearch.html
@@ -0,0 +1,52 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>How to Use File Search</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>How to Use File Search</h2>
+        <p>
+            Currently, there are 3 categories that you can use to filter and show the directories and files within the images in the current opened case.
+            <br><br>
+            The categories are:
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp; 1. Name <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Search for all files and directory whose name contains the pattern given.<bR>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>Note</b>: it doesn't support regular expression and keyword matching.
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp; 2. Size <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Search for all files and directory whose size matches the pattern given. The pattern can be "equal to", "greater than", and "less than". The unit for the size can be "Byte(s)", "KB", "MB", "GB", and "TB".
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp; 3. Date <br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Search for all files and directory whose "date property" is within the date range given. The "date properties" are "Modified Date", "Accessed Date", "Changed Date", and "Created Date". You must also specify the timezone for the date given.
+            <br><br><br>
+            To use any of these filters, check the box next to the category and click "Search" button to start the search process. The result will show up in the "<a href="nbdocs:/org/sleuthkit/autopsy/corecomponents/docs/dataresult-about.html">Result Viewer</a>".
+            <br><br>
+        </p>
+        
+        <h2>Example</h2>
+        <p>
+            Here's an example where I try to get all the directories and files whose name contains "hello", has a size greater than 1000 Bytes, and was created between 06/15/2010 and 06/16/2010 (in GMT-5 timezone):
+            <br><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;<img src="FileSearch_usage.png" alt="Example of File Search usage" />
+        </p>
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html
new file mode 100644
index 0000000000000000000000000000000000000000..1f765812b8b53e8e07b833f16f6016722fd2cdea
--- /dev/null
+++ b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open-filesearch.html
@@ -0,0 +1,45 @@
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>How to Open File Search</title>
+        <link rel="stylesheet" href="nbdocs:/org/netbeans/modules/usersguide/ide.css" type="text/css">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <h2>How to Open File Search</h2>
+        <p>
+            To open the File Search, you can do one of the following thing:
+            <ul type="circle">
+                <li>
+                    Click the File Search tab.
+                    <br><br>
+                    &nbsp;&nbsp;<img src="open_fileSearch1.png" alt="Open File Search Top Component 1" />
+                    <br><br>
+                </li>
+                <li>
+                    Select the "Tools" -> "File Search"
+                    <br><br>
+                    &nbsp;&nbsp;<img src="open_fileSearch2.png" alt="Open File Search Top Component 2" />
+                    <br><br>
+                </li>
+            </ul>
+
+        <b>Note:</b> The File Search Window is opened and closed automatically. If there's a case opened and there is at least one image inside that case, File Search Window can't be closed.
+    </body>
+</html>
+<!--
+Tip: to create a link which will open in an external web browser, try:
+<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
+    <param name="content" value="http://www.netbeans.org/">
+    <param name="text" value="<html><u>http://www.netbeans.org/</u></html>">
+    <param name="textFontSize" value="medium">
+    <param name="textColor" value="blue">
+</object>
+To create a link to a help set from another module, you need to know the code name base and path, e.g.:
+<a href="nbdocs://org.netbeans.modules.usersguide/org/netbeans/modules/usersguide/configure/configure_options.html">Using the Options Window</a>
+(This link will behave sanely if that module is disabled or missing.)
+-->
\ No newline at end of file
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch1.png b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch1.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d86d1340881b387b0aefad36ed5409ef2112cef
Binary files /dev/null and b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch1.png differ
diff --git a/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch2.png b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch2.png
new file mode 100644
index 0000000000000000000000000000000000000000..afdfc0fb8d81a61af1baaec5ba3aa565d1bf2822
Binary files /dev/null and b/FileSearch/javahelp/org/sleuthkit/autopsy/filesearch/docs/open_fileSearch2.png differ
diff --git a/FileSearch/manifest.mf b/FileSearch/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..ee8e710a5e23c9231d9ffd301bef305819006b3a
--- /dev/null
+++ b/FileSearch/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.filesearch/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/filesearch/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/filesearch/Bundle.properties
+OpenIDE-Module-Requires: org.openide.windows.WindowManager, org.netbeans.api.javahelp.Help
+
diff --git a/FileSearch/nbproject/build-impl.xml b/FileSearch/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..84890932f969652f5918ec409e655d57d9f20d28
--- /dev/null
+++ b/FileSearch/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.filesearch-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/FileSearch/nbproject/genfiles.properties b/FileSearch/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..39ec6d5464ff8a38d31c859c4333c8a7c291a71b
--- /dev/null
+++ b/FileSearch/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=782bf133
+build.xml.script.CRC32=c0009852
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=782bf133
+nbproject/build-impl.xml.script.CRC32=2e520747
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/FileSearch/nbproject/project.properties b/FileSearch/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..cd238545fed2ef837e84a8fbc0f69ea22927ace2
--- /dev/null
+++ b/FileSearch/nbproject/project.properties
@@ -0,0 +1,5 @@
+file.reference.jcalendarbutton-1.4.5.jar=release/modules/ext/jcalendarbutton-1.4.5.jar
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+javahelp.hs=filesearch-hs.xml
+spec.version.base=0.0
diff --git a/FileSearch/nbproject/project.xml b/FileSearch/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ad25ec5fca78994abca42455757faacc9c4c7e96
--- /dev/null
+++ b/FileSearch/nbproject/project.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.filesearch</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.15.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.28.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponents</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.datamodel</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.directorytree</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.filesearch</package>
+            </public-packages>
+            <class-path-extension>
+                <runtime-relative-path>ext/jcalendarbutton-1.4.5.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/jcalendarbutton-1.4.5.jar</binary-origin>
+            </class-path-extension>
+        </data>
+    </configuration>
+</project>
diff --git a/FileSearch/nbproject/suite.properties b/FileSearch/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/FileSearch/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/FileSearch/release/modules/ext/jcalendarbutton-1.4.5.jar b/FileSearch/release/modules/ext/jcalendarbutton-1.4.5.jar
new file mode 100644
index 0000000000000000000000000000000000000000..4128ca1e05a3e57d1b1a98cf56643daca8e102f2
Binary files /dev/null and b/FileSearch/release/modules/ext/jcalendarbutton-1.4.5.jar differ
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a65e650d4ed5653d521e1c2e0dc9bdbf58961f46
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/AbstractFileSearchFilter.java
@@ -0,0 +1,40 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import javax.swing.JComponent;
+
+/**
+ * Implements common functionality of file search filters
+ * @param <T> Type of component to display in file search panel
+ * @author pmartel
+ */
+abstract class AbstractFileSearchFilter<T extends JComponent> implements FileSearchFilter {
+
+    final private T component;
+
+    AbstractFileSearchFilter(T component) {
+        this.component = component;
+    }
+
+    @Override
+    public T getComponent() {
+        return this.component;
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/Bundle.properties b/FileSearch/src/org/sleuthkit/autopsy/filesearch/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..73aa883be85a675a804611d91829939e4a1b763a
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/Bundle.properties
@@ -0,0 +1,45 @@
+CTL_FileSearchAction=FileSearch
+CTL_FileSearchTopComponent=File Search
+HINT_FileSearchTopComponent=This is a FileSearch window
+OpenIDE-Module-Name=FileSearch
+FileSearchTopComponent.searchTermLabel1.text=Search for files that match the following criteria:
+FileSearchTopComponent.searchButton1.text=Search
+FileSearchTopComponent.sizeCheckBox1.text=Size:
+FileSearchTopComponent.noteNameLabel1.text=<html>*Note: Name match is case insensitive and matches<br/> any part of the file name. Regular expressions are<br/> not currently supported. </html>
+FileSearchTopComponent.searchTextField1.text=
+FileSearchTopComponent.nameCheckBox1.text=Name:
+FileSearchTopComponent.jLabel8.text=Timezone:
+FileSearchTopComponent.jLabel7.text=*The date format is mm/dd/yyyy
+FileSearchTopComponent.jLabel6.text=*Empty fields mean "No Limit"
+FileSearchTopComponent.createdCheckBox1.text=Created
+FileSearchTopComponent.accessedCheckBox1.text=Accessed
+FileSearchTopComponent.changedCheckBox1.text=Changed
+FileSearchTopComponent.modifiedCheckBox1.text=Modified
+FileSearchTopComponent.dateToButtonCalendar1.text=
+FileSearchTopComponent.dateToTextField1.text=
+FileSearchTopComponent.jLabel5.text=to
+FileSearchTopComponent.dateFromTextField1.text=
+FileSearchTopComponent.dateFromButtonCalendar1.text=
+FileSearchTopComponent.dateCheckBox1.text=Date:
+FileSearchTopComponent.dateFiltersButton1.text=Date Filters
+KnownStatusSearchPanel.knownCheckBox.text=Known Status:
+KnownStatusSearchPanel.knownBadOptionCheckBox.text=Known bad
+KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL)
+KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown
+DateSearchPanel.dateCheckBox.text=Date:
+DateSearchPanel.jLabel4.text=Timezone:
+DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy
+DateSearchPanel.jLabel2.text=*Empty fields mean "No Limit"
+DateSearchPanel.createdCheckBox.text=Created
+DateSearchPanel.accessedCheckBox.text=Accessed
+DateSearchPanel.changedCheckBox.text=Changed
+DateSearchPanel.modifiedCheckBox.text=Modified
+DateSearchPanel.dateToButtonCalendar.text=
+DateSearchPanel.dateToTextField.text=
+DateSearchPanel.jLabel1.text=to
+DateSearchPanel.dateFromTextField.text=
+DateSearchPanel.dateFromButtonCalendar.text=
+NameSearchPanel.nameCheckBox.text=Name:
+NameSearchPanel.noteNameLabel.text=<html>*Note: Name match is case insensitive and matches<br/> any part of the file name. Regular expressions are<br/> not currently supported. </html>
+NameSearchPanel.searchTextField.text=
+SizeSearchPanel.sizeCheckBox.text=Size:
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterChildren.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..30b56966ca686a602772a35f7b119324882e5d32
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterChildren.java
@@ -0,0 +1,46 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+
+/**
+ * This class is used for the creation of all the children for the
+ * DataResultFilterNode that created in the DataResultFilterNode.java.
+ *
+ * @author jantonius
+ */
+public class DataResultFilterChildren extends FilterNode.Children {
+
+    /** the constructor */
+    public DataResultFilterChildren(Node arg) {
+        super(arg);
+    }
+
+    @Override
+    protected Node copyNode(Node arg0) {
+        return new DataResultFilterNode(arg0);
+    }
+
+    @Override
+    protected Node[] createNodes(Node arg0) {
+        return new Node[]{this.copyNode(arg0)};
+    }
+}
\ No newline at end of file
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..973d0a43433e66df7bb94b47edbacb9509d1753a
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java
@@ -0,0 +1,139 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
+import org.sleuthkit.autopsy.datamodel.ImageNode;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.datamodel.VolumeNode;
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import java.sql.SQLException;
+import javax.swing.Action;
+import org.openide.nodes.FilterNode;
+import org.openide.nodes.Node;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.TskException;
+import org.sleuthkit.autopsy.directorytree.ChangeViewAction;
+import org.sleuthkit.autopsy.directorytree.ExtractAction;
+
+/**
+ * This class wraps nodes as they are passed to the DataResult viewers.  It 
+ * defines the actions that the node should have. 
+ */
+public class DataResultFilterNode extends FilterNode implements ContentNode {
+
+    private Node currentNode;
+
+    /** the constructor */
+    public DataResultFilterNode(Node arg) {
+        super(arg, new DataResultFilterChildren(arg));
+        this.currentNode = arg;
+    }
+
+    @Override
+    public Node getOriginal() {
+        return super.getOriginal();
+    }
+
+    /**
+     * Right click action for the nodes that we want to pass to the directory
+     * table and the output view.
+     *
+     * @param popup
+     * @return actions
+     */
+    @Override
+    public Action[] getActions(boolean popup) {
+        // right click action(s) for image node
+        if (this.currentNode instanceof ImageNode) {
+            return new Action[]{};
+        } // right click action(s) for volume node
+        else if (this.currentNode instanceof VolumeNode) {
+            return new Action[]{};
+        } // right click action(s) for directory node
+        else if (this.currentNode instanceof DirectoryNode) {
+            return new Action[]{
+                        new ChangeViewAction("View", 0, (ContentNode) currentNode),
+                        new OpenParentFolderAction("Open Parent Directory", ((ContentNode) currentNode).getSystemPath())
+                    };
+        } // right click action(s) for the file node
+        else if (this.currentNode instanceof FileNode) {
+            return new Action[]{
+                        new ExtractAction("Extract", (FileNode) this.currentNode),
+                        new ChangeViewAction("View", 0, (ContentNode) currentNode),
+                        new OpenParentFolderAction("Open Parent Directory", ((ContentNode) currentNode).getSystemPath())
+                    };
+        } else {
+            return new Action[]{};
+        }
+    }
+
+    /**
+     * Double click action for the nodes that we want to pass to the directory
+     * table and the output view.
+     *
+     * @return action
+     */
+    @Override
+    public Action getPreferredAction() {
+        return null;
+    }
+
+    @Override
+    public long getID() {
+        return ((ContentNode) currentNode).getID();
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+        return ((ContentNode) currentNode).getRowValues(rows);
+    }
+
+    @Override
+    public byte[] read(long offset, long len) throws TskException {
+        return ((ContentNode) currentNode).read(offset, len);
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return ((ContentNode) currentNode).getFileIDColumn();
+    }
+
+    @Override
+    public Content getContent() {
+        return ((ContentNode) currentNode).getContent();
+    }
+
+    @Override
+    public String[] getDisplayPath() {
+        return ((ContentNode) currentNode).getDisplayPath();
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        //TODO: figure out how to deal with visitors
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public String[] getSystemPath() {
+        return ((ContentNode) currentNode).getSystemPath();
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a7e12a66076010ed11f437409a53c5da8114b6d
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchFilter.java
@@ -0,0 +1,254 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JSeparator;
+import javax.swing.ListCellRenderer;
+import javax.swing.border.EmptyBorder;
+import org.sleuthkit.autopsy.casemodule.Case;
+
+/**
+ * Filters file date properties (modified/created/etc.. times)
+ * @author pmartel
+ */
+class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
+
+    private static final String NONE_SELECTED_MESSAGE = "At least one date type must be selected!";
+    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
+    private static final String SEPARATOR = "SEPARATOR";
+
+    /**
+     * New DateSearchFilter with the default panel
+     */
+    DateSearchFilter() {
+        this(new DateSearchPanel(DATE_FORMAT, DateSearchFilter.createTimeZoneList()));
+    }
+
+    private DateSearchFilter(DateSearchPanel panel) {
+        super(panel);
+        Case.addPropertyChangeListener(this.new CasePropertyChangeListener());
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.getComponent().getDateCheckBox().isSelected();
+    }
+
+    @Override
+    public String getPredicate() throws FilterValidationException {
+        String addQuery = "1";
+        DateSearchPanel panel = this.getComponent();
+
+        // first, get the selected timeZone from the dropdown list
+        String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
+        String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
+        TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
+
+        // convert the date from the selected timezone to get the GMT
+        long fromDate = 0;
+        String startDateValue = panel.getDateFromTextField().getText();
+        Calendar startDate = null;
+        try {
+            DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
+            sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
+            Date temp = sdf.parse(startDateValue);
+
+            startDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
+            startDate.setTime(temp); // convert to GMT
+        } catch (ParseException ex) {
+            // for now, no need to show the error message to the user her
+        }
+        if (!startDateValue.equals("")) {
+            if (startDate != null) {
+                fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
+            }
+        }
+
+        long toDate = Date.parse(DATE_FORMAT.format(Calendar.getInstance().getTime())); // get today's date
+        String endDateValue = panel.getDateToTextField().getText();
+        Calendar endDate = null;
+        try {
+            DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
+            sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
+            Date temp2 = sdf.parse(endDateValue);
+
+            endDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT"));
+            endDate.setTime(temp2); // convert to GMT
+            endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24); // get the next 24 hours
+        } catch (ParseException ex) {
+            // for now, no need to show the error message to the user here
+        }
+        if (!endDateValue.equals("")) {
+            if (endDate != null) {
+                toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
+            }
+        }
+
+        final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected();
+        final boolean changedChecked = panel.getChangedCheckBox().isSelected();
+        final boolean accessedChecked = panel.getAccessedCheckBox().isSelected();
+        final boolean createdChecked = panel.getAccessedCheckBox().isSelected();
+
+
+        if (modifiedChecked || changedChecked || accessedChecked || createdChecked) {
+
+            String subQuery = "0";
+
+            if (modifiedChecked) {
+                subQuery += " or mtime between " + fromDate + " and " + toDate;
+            }
+
+            if (changedChecked) {
+                subQuery += " or ctime between " + fromDate + " and " + toDate;
+            }
+
+            if (accessedChecked) {
+                subQuery += " or atime between " + fromDate + " and " + toDate;
+            }
+
+            if (createdChecked) {
+                subQuery += " or crtime between " + fromDate + " and " + toDate;
+            }
+
+            addQuery += " and (" + subQuery + ")";
+        } else {
+            throw new FilterValidationException(NONE_SELECTED_MESSAGE);
+        }
+
+        return addQuery;
+
+    }
+
+    private void updateTimeZoneList() {
+        this.getComponent().setTimeZones(DateSearchFilter.createTimeZoneList());
+    }
+
+    private static List<String> createTimeZoneList() {
+
+        List<String> timeZones = new ArrayList<String>();
+
+        if (Case.existsCurrentCase()) {
+            // get the latest case
+            Case currentCase = Case.getCurrentCase(); // get the most updated case
+
+            Set<TimeZone> caseTimeZones = currentCase.getTimeZone();
+            Iterator<TimeZone> iterator = caseTimeZones.iterator();
+            while (iterator.hasNext()) {
+                TimeZone zone = iterator.next();
+                int offset = zone.getRawOffset() / 1000;
+                int hour = offset / 3600;
+                int minutes = (offset % 3600) / 60;
+                String item = String.format("(GMT%+d:%02d) %s", hour, minutes, zone.getID());
+                timeZones.add(item);
+            }
+
+            if (caseTimeZones.size() > 0) {
+                timeZones.add(SEPARATOR);
+            }
+
+            // load and add all timezone
+            String[] ids = SimpleTimeZone.getAvailableIDs();
+            for (String id : ids) {
+                TimeZone zone = TimeZone.getTimeZone(id);
+                int offset = zone.getRawOffset() / 1000;
+                int hour = offset / 3600;
+                int minutes = (offset % 3600) / 60;
+                String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id);
+                timeZones.add(item);
+            }
+        }
+
+        return timeZones;
+    }
+
+    /**
+     * Inner class to put the separator inside the combo box.
+     */
+    static class ComboBoxRenderer extends JLabel implements ListCellRenderer {
+
+        JSeparator separator;
+
+        ComboBoxRenderer() {
+            setOpaque(true);
+            setBorder(new EmptyBorder(1, 1, 1, 1));
+            separator = new JSeparator(JSeparator.HORIZONTAL);
+        }
+
+        @Override
+        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+            String str = (value == null) ? "" : value.toString();
+            if (SEPARATOR.equals(str)) {
+                return separator;
+            }
+            if (isSelected) {
+                setBackground(list.getSelectionBackground());
+                setForeground(list.getSelectionForeground());
+            } else {
+                setBackground(list.getBackground());
+                setForeground(list.getForeground());
+            }
+            setFont(list.getFont());
+            setText(str);
+            return this;
+        }
+    }
+
+    private class CasePropertyChangeListener implements PropertyChangeListener {
+
+        @Override
+        public void propertyChange(PropertyChangeEvent evt) {
+            String changed = evt.getPropertyName();
+            Object oldValue = evt.getOldValue();
+            Object newValue = evt.getNewValue();
+
+            if (changed.equals(Case.CASE_CURRENT_CASE)) {
+                // create or open a case
+                if (newValue != null) {
+                    DateSearchFilter.this.updateTimeZoneList();
+                }
+            }
+
+            // if the image is added to the case
+            if (changed.equals(Case.CASE_ADD_IMAGE)) {
+                DateSearchFilter.this.updateTimeZoneList();
+            }
+
+            // if the image is removed from the case
+            if (changed.equals(Case.CASE_DEL_IMAGE)) {
+                DateSearchFilter.this.updateTimeZoneList();
+            }
+        }
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..4d5fad97244eb3a62b1ba41d22a215fc2b6f6c4f
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.form
@@ -0,0 +1,234 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <Component id="dateCheckBox" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="dateFromTextField" min="-2" pref="92" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+              <Component id="dateFromButtonCalendar" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="dateToTextField" min="-2" pref="92" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
+              <Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/>
+          </Group>
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="21" pref="21" max="21" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="changedCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="modifiedCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="accessedCheckBox" min="-2" max="-2" attributes="0"/>
+                          <Component id="createdCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="jLabel4" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="timeZoneComboBox" min="-2" pref="193" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="0" attributes="0">
+                      <EmptySpace min="21" pref="21" max="21" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="dateCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="dateFromTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Group type="103" alignment="1" groupAlignment="3" attributes="0">
+                          <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
+                          <Component id="dateToTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="1" attributes="0">
+                          <Component id="dateToButtonCalendar" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="-2" pref="1" max="-2" attributes="0"/>
+                      </Group>
+                      <Component id="dateFromButtonCalendar" alignment="1" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="timeZoneComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="1" attributes="0">
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="modifiedCheckBox" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="changedCheckBox" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="accessedCheckBox" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="23" pref="23" max="23" attributes="0"/>
+                  </Group>
+                  <Component id="createdCheckBox" alignment="1" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jLabel3" min="-2" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JFormattedTextField" name="dateToTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateToTextFieldFocusLost"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel4">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="dateCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JComboBox" name="timeZoneComboBox">
+      <Properties>
+        <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+          <StringArray count="0"/>
+        </Property>
+      </Properties>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JComboBox(this.timeZones.toArray());"/>
+        <AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="timeZoneComboBox.setRenderer(new DateSearchFilter.ComboBoxRenderer());"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel3">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JFormattedTextField" name="dateFromTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="dateFromTextFieldFocusLost"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(this.dateFormat);"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel2">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="org.sourceforge.jcalendarbutton.JCalendarButton" name="dateFromButtonCalendar">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateFromPopupChanged"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="modifiedCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.modifiedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="changedCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.changedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="accessedCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.accessedCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="createdCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.createdCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="org.sourceforge.jcalendarbutton.JCalendarButton" name="dateToButtonCalendar">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToButtonCalendar.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="propertyChange" listener="java.beans.PropertyChangeListener" parameters="java.beans.PropertyChangeEvent" handler="dateToPopupChanged"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..9af85af157f953ce9c4afd114db74f29eb10df95
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DateSearchPanel.java
@@ -0,0 +1,313 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.filesearch;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFormattedTextField;
+
+/**
+ * Subpanel with controls for file data filtering.
+ */
+class DateSearchPanel extends javax.swing.JPanel {
+
+    DateFormat dateFormat;
+    List<String> timeZones;
+
+    DateSearchPanel(DateFormat dateFormat, List<String> timeZones) {
+        this.dateFormat = dateFormat;
+        this.timeZones = timeZones;
+
+        initComponents();
+    }
+
+    JCheckBox getAccessedCheckBox() {
+        return accessedCheckBox;
+    }
+
+    JCheckBox getChangedCheckBox() {
+        return changedCheckBox;
+    }
+
+    JCheckBox getCreatedCheckBox() {
+        return createdCheckBox;
+    }
+
+    JCheckBox getDateCheckBox() {
+        return dateCheckBox;
+    }
+
+    JFormattedTextField getDateFromTextField() {
+        return dateFromTextField;
+    }
+
+    JFormattedTextField getDateToTextField() {
+        return dateToTextField;
+    }
+
+    JCheckBox getModifiedCheckBox() {
+        return modifiedCheckBox;
+    }
+
+    JComboBox getTimeZoneComboBox() {
+        return timeZoneComboBox;
+    }
+
+    void setTimeZones(List<String> newTimeZones) {
+        this.timeZones = newTimeZones;
+        this.timeZoneComboBox.removeAllItems();
+        for (String tz : newTimeZones) {
+            this.timeZoneComboBox.addItem(tz);
+        }
+    }
+
+    //TODO: calendar button stuff
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        dateToTextField = new JFormattedTextField(this.dateFormat);
+        jLabel1 = new javax.swing.JLabel();
+        jLabel4 = new javax.swing.JLabel();
+        dateCheckBox = new javax.swing.JCheckBox();
+        timeZoneComboBox = new JComboBox(this.timeZones.toArray());
+        timeZoneComboBox.setRenderer(new DateSearchFilter.ComboBoxRenderer());
+        jLabel3 = new javax.swing.JLabel();
+        dateFromTextField = new JFormattedTextField(this.dateFormat);
+        jLabel2 = new javax.swing.JLabel();
+        dateFromButtonCalendar = new org.sourceforge.jcalendarbutton.JCalendarButton();
+        modifiedCheckBox = new javax.swing.JCheckBox();
+        changedCheckBox = new javax.swing.JCheckBox();
+        accessedCheckBox = new javax.swing.JCheckBox();
+        createdCheckBox = new javax.swing.JCheckBox();
+        dateToButtonCalendar = new org.sourceforge.jcalendarbutton.JCalendarButton();
+
+        dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N
+        dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() {
+            public void focusLost(java.awt.event.FocusEvent evt) {
+                dateToTextFieldFocusLost(evt);
+            }
+        });
+
+        jLabel1.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel1.text")); // NOI18N
+
+        jLabel4.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel4.text")); // NOI18N
+
+        dateCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateCheckBox.text")); // NOI18N
+
+        jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
+
+        dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
+        dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() {
+            public void focusLost(java.awt.event.FocusEvent evt) {
+                dateFromTextFieldFocusLost(evt);
+            }
+        });
+
+        jLabel2.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel2.text")); // NOI18N
+
+        dateFromButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromButtonCalendar.text")); // NOI18N
+        dateFromButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
+            public void propertyChange(java.beans.PropertyChangeEvent evt) {
+                dateFromPopupChanged(evt);
+            }
+        });
+
+        modifiedCheckBox.setSelected(true);
+        modifiedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.modifiedCheckBox.text")); // NOI18N
+
+        changedCheckBox.setSelected(true);
+        changedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.changedCheckBox.text")); // NOI18N
+
+        accessedCheckBox.setSelected(true);
+        accessedCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.accessedCheckBox.text")); // NOI18N
+
+        createdCheckBox.setSelected(true);
+        createdCheckBox.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.createdCheckBox.text")); // NOI18N
+
+        dateToButtonCalendar.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToButtonCalendar.text")); // NOI18N
+        dateToButtonCalendar.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
+            public void propertyChange(java.beans.PropertyChangeEvent evt) {
+                dateToPopupChanged(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(dateCheckBox)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(0, 0, 0)
+                .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(jLabel1)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(0, 0, 0)
+                .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+            .addGroup(layout.createSequentialGroup()
+                .addGap(21, 21, 21)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(changedCheckBox)
+                            .addComponent(modifiedCheckBox))
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(accessedCheckBox)
+                            .addComponent(createdCheckBox)))
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jLabel4)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(21, 21, 21)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(jLabel3)
+                            .addComponent(jLabel2)))))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                        .addComponent(dateCheckBox)
+                        .addComponent(dateFromTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                            .addComponent(jLabel1)
+                            .addComponent(dateToTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addGroup(layout.createSequentialGroup()
+                            .addComponent(dateToButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                            .addGap(1, 1, 1))
+                        .addComponent(dateFromButtonCalendar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                .addGap(4, 4, 4)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel4)
+                    .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(modifiedCheckBox)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(changedCheckBox))
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(accessedCheckBox)
+                        .addGap(23, 23, 23))
+                    .addComponent(createdCheckBox))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(jLabel2)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jLabel3))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void dateFromTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateFromTextFieldFocusLost
+        // set the "from" calendar button to listen to change in the text field
+        String fromDateString = this.dateFromTextField.getText();
+        if (!fromDateString.equals("")) {
+            try {
+                Date fromDate = dateFormat.parse(fromDateString);
+                dateFromButtonCalendar.setTargetDate(fromDate);
+            } catch (ParseException ex) {
+                // for now, no need to show the error message to the user her
+            }
+        }
+    }//GEN-LAST:event_dateFromTextFieldFocusLost
+
+    private void dateToTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_dateToTextFieldFocusLost
+        // set the "to" calendar button to listen to change in the text field
+        String toDateString = this.dateToTextField.getText();
+        if (!toDateString.equals("")) {
+            try {
+                Date toDate = dateFormat.parse(toDateString);
+                dateToButtonCalendar.setTargetDate(toDate);
+            } catch (ParseException ex) {
+                // for now, no need to show the error message to the user here
+            }
+        }
+    }//GEN-LAST:event_dateToTextFieldFocusLost
+
+    private void dateFromPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateFromPopupChanged
+        if (evt.getNewValue() instanceof Date) {
+            setFromDate((Date) evt.getNewValue());
+        }
+    }//GEN-LAST:event_dateFromPopupChanged
+
+    private void dateToPopupChanged(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_dateToPopupChanged
+        if (evt.getNewValue() instanceof Date) {
+            setToDate((Date) evt.getNewValue());
+        }
+    }//GEN-LAST:event_dateToPopupChanged
+
+    /**
+     * Validate and set the datetime field on the screen given a datetime string.
+     * @param date The date object
+     */
+    private void setFromDate(Date date) {
+        String dateStringResult = "";
+        if (date != null) {
+            dateStringResult = dateFormat.format(date);
+        }
+        dateFromTextField.setText(dateStringResult);
+        dateFromButtonCalendar.setTargetDate(date);
+    }
+
+    /**
+     * Validate and set the datetime field on the screen given a date.
+     * @param date The date object
+     */
+    private void setToDate(Date date) {
+        String dateStringResult = "";
+        if (date != null) {
+            dateStringResult = dateFormat.format(date);
+        }
+        dateToTextField.setText(dateStringResult);
+        dateToButtonCalendar.setTargetDate(date);
+    }
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox accessedCheckBox;
+    private javax.swing.JCheckBox changedCheckBox;
+    private javax.swing.JCheckBox createdCheckBox;
+    private javax.swing.JCheckBox dateCheckBox;
+    private org.sourceforge.jcalendarbutton.JCalendarButton dateFromButtonCalendar;
+    private javax.swing.JFormattedTextField dateFromTextField;
+    private org.sourceforge.jcalendarbutton.JCalendarButton dateToButtonCalendar;
+    private javax.swing.JFormattedTextField dateToTextField;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JLabel jLabel4;
+    private javax.swing.JCheckBox modifiedCheckBox;
+    private javax.swing.JComboBox timeZoneComboBox;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5159ae020a6c9735bc07db5d90dcb94ca4198794
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchFilter.java
@@ -0,0 +1,62 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import javax.swing.JComponent;
+
+/**
+ * Provides a filter and the panel to display it to the FileSearchTopComponent
+ */
+interface FileSearchFilter {
+
+    /**
+     * Gets the panel to put in the File Search pane.
+     * @return component that provides input to filter
+     */
+    JComponent getComponent();
+
+    /**
+     * Checks if this filter is currently enabled.
+     * @return true if it should be included in the search
+     */
+    boolean isEnabled();
+
+    /**
+     * Gets predicate expression to include in the SQL filter expression
+     * @return SQL expression that evaluates to a boolean true if the
+     * filter matches the file, otherwise false
+     * @throws FilterValidationException with a message if the filter is in an
+     * invalid state
+     */
+    String getPredicate() throws FilterValidationException;
+
+    /**
+     * Thrown if a filter's inputs are invalid
+     */
+    static class FilterValidationException extends Exception {
+
+        FilterValidationException(String message) {
+            super(message);
+        }
+
+        FilterValidationException(String message, Exception cause) {
+            super(message, cause);
+        }
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponent.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..d02e2919744716411c8bdc83faefaa1ab5629095
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponent.java
@@ -0,0 +1,342 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.EmptyBorder;
+import org.openide.nodes.Node;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
+import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
+import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
+import org.sleuthkit.datamodel.FsContent;
+import org.sleuthkit.datamodel.SleuthkitCase;
+
+/**
+ * Top component which displays something.
+ */
+//@ConvertAsProperties(dtd = "-//org.sleuthkit.autopsy.filesearch//FileSearch//EN", autostore = false)
+// Registered as a service provider for DataExplorer in layer.xml
+public final class FileSearchTopComponent extends TopComponent implements DataExplorer {
+
+    private List<FilterArea> filterAreas = new ArrayList();
+    private JButton searchButton;
+    private static FileSearchTopComponent instance;
+    private PropertyChangeSupport pcs;
+    private int index;
+    private static ArrayList<DataResultTopComponent> searchResults = new ArrayList<DataResultTopComponent>();
+    private static final String PREFERRED_ID = "FileSearchTopComponent";
+
+    private FileSearchTopComponent() {
+        initComponents();
+        setListener();
+        setName(NbBundle.getMessage(FileSearchTopComponent.class, "CTL_FileSearchTopComponent"));
+        setToolTipText(NbBundle.getMessage(FileSearchTopComponent.class, "HINT_FileSearchTopComponent"));
+
+        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
+
+        this.pcs = new PropertyChangeSupport(this);
+
+        this.index = 1;
+    }
+
+    /**
+     * This method is called from within the constructor to
+     * initialize the form.
+     */
+    private void initComponents() {
+
+        this.setLayout(new BorderLayout());
+
+        JPanel filterPanel = new JPanel();
+        filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.Y_AXIS));
+        filterPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
+
+        JScrollPane scrollPane = new JScrollPane(filterPanel);
+        scrollPane.setPreferredSize(this.getSize());
+        this.add(scrollPane, BorderLayout.CENTER);
+
+        JLabel label = new JLabel("Search for files that match the following criteria:");
+        label.setAlignmentX(Component.LEFT_ALIGNMENT);
+        label.setBorder(new EmptyBorder(0, 0, 10, 0));
+        filterPanel.add(label);
+
+        // Create and add filter areas
+        this.filterAreas.add(new FilterArea("Name", new NameSearchFilter()));
+
+        List<FileSearchFilter> metadataFilters = new ArrayList<FileSearchFilter>();
+        metadataFilters.add(new SizeSearchFilter());
+        metadataFilters.add(new DateSearchFilter());
+        this.filterAreas.add(new FilterArea("Metadata", metadataFilters));
+
+        this.filterAreas.add(new FilterArea("Known Status", new KnownStatusSearchFilter()));
+
+        for (FilterArea fa : this.filterAreas) {
+            fa.setMaximumSize(new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height));
+            fa.setAlignmentX(Component.LEFT_ALIGNMENT);
+            filterPanel.add(fa);
+        }
+
+        // Create and add search button
+        this.searchButton = new JButton("Search");
+        this.searchButton.setAlignmentX(Component.LEFT_ALIGNMENT);
+        this.searchButton.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                FileSearchTopComponent.this.search();
+            }
+        });
+
+        filterPanel.add(searchButton);
+    }
+
+    /**
+     * @return true if any of the filters in the panel are enabled (checked)
+     */
+    private boolean anyFiltersEnabled() {
+        for (FileSearchFilter filter : this.getFilters()) {
+            if (filter.isEnabled()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Action when the "Search" button is pressed.
+     *
+     * @param evt  the action event
+     */
+    private void search() {
+        // change the cursor to "waiting cursor" for this operation
+        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        try {
+            if (this.anyFiltersEnabled()) {
+                String title = "File Search Results " + index;
+                String pathText = "Filename Search Results:";
+
+                // try to get the number of matches first
+                Case currentCase = Case.getCurrentCase(); // get the most updated case
+                int totalMatches = 0;
+                ArrayList<FsContent> fsContentList = new ArrayList<FsContent>();
+                try {
+                    List<FsContent> currentDbList;
+                    SleuthkitCase tempDb = currentCase.getSleuthkitCase();
+                    ResultSet rs = tempDb.runQuery(this.getQuery("count(*) as TotalMatches"));
+                    totalMatches = totalMatches + rs.getInt("TotalMatches");
+                    rs = tempDb.runQuery(this.getQuery(null));
+                    currentDbList = tempDb.resultSetToFsContents(rs);
+                    fsContentList.addAll(currentDbList);
+                } catch (SQLException ex) {
+                    Logger logger = Logger.getLogger(this.getClass().getName());
+                    logger.log(Level.WARNING, "Error while trying to get the number of matches.", ex);
+                }
+
+                TopComponent searchResultWin = DataResultTopComponent.createInstance(title, pathText, new SearchNode(fsContentList), totalMatches);
+
+                searchResultWin.requestActive(); // make it the active top component
+
+                searchResultWin.addPropertyChangeListener(this);
+                searchResults.add((DataResultTopComponent) searchResultWin);
+                index++;
+
+                /**
+                 * If total matches more than 1000, pop up a dialog box that say
+                 * the performance maybe be slow and to increase the performance,
+                 * tell the users to refine their search.
+                 */
+                if (totalMatches > 1000) {
+                    // show the confirmation
+                    NotifyDescriptor d = new NotifyDescriptor.Message("Note: " + totalMatches + " matches found. Due to the large number of search results, performance may be slow for some operations. (In particular the thumbnail view in this version of Autospy, should be fixed in a future version) \n\nPlease refine your search to get better search results and improve performance.");
+                    DialogDisplayer.getDefault().notify(d);
+                }
+            } else {
+                throw new FilterValidationException("At least one filter must be selected.");
+            }
+        } catch (FilterValidationException ex) {
+            NotifyDescriptor d = new NotifyDescriptor.Message("Validation Error: " + ex.getMessage());
+            DialogDisplayer.getDefault().notify(d);
+        } finally {
+            this.setCursor(null);
+        }
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link #findInstance}.
+     */
+    public static synchronized FileSearchTopComponent getDefault() {
+        if (instance == null) {
+            instance = new FileSearchTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the FileSearchTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized FileSearchTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            Logger.getLogger(FileSearchTopComponent.class.getName()).warning(
+                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof FileSearchTopComponent) {
+            return (FileSearchTopComponent) win;
+        }
+        Logger.getLogger(FileSearchTopComponent.class.getName()).warning(
+                "There seem to be multiple components with the '" + PREFERRED_ID
+                + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+
+    @Override
+    public void componentOpened() {
+    }
+
+    @Override
+    public void componentClosed() {
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public boolean canClose() {
+        return !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
+    }
+
+    @Override
+    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+        pcs.addPropertyChangeListener(listener);
+    }
+
+    @Override
+    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+        pcs.removePropertyChangeListener(listener);
+    }
+
+    private void setListener() {
+        Case.addPropertyChangeListener((PropertyChangeListener) this); // add this class to listen to any changes in the Case.java class
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        String changed = evt.getPropertyName();
+        Object newValue = evt.getNewValue();
+
+        // if the one of the "FileSearchResult" window is closed
+        if (changed.equals(DataResultTopComponent.REMOVE_FILESEARCH)) {
+            searchResults.remove((DataResultTopComponent) newValue);
+        }
+
+    }
+
+    public static ArrayList<DataResultTopComponent> getFileSearchResultList() {
+        return searchResults;
+    }
+
+    /**
+     * Gets the SQL query to get the data from the database based on the
+     * criteria that user chooses on the FileSearch.
+     *
+     * @param addition  the additional selection for query. If nothing/null, will select all.
+     * @return query  the SQL query
+     * @throws org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException  if an enabled filter is in an invalid state
+     */
+    private String getQuery(String addition) throws FilterValidationException {
+        String tempQuery = "*";
+        if (addition != null && !addition.equals("")) {
+            tempQuery = addition;
+        }
+
+        String query = "select " + tempQuery + " from tsk_files where 1";
+
+        for (FileSearchFilter f : this.getEnabledFilters()) {
+            query += " and (" + f.getPredicate() + ")";
+        }
+
+        return query;
+    }
+
+    private Collection<FileSearchFilter> getFilters() {
+        Collection<FileSearchFilter> filters = new ArrayList<FileSearchFilter>();
+
+        for (FilterArea fa : this.filterAreas) {
+            filters.addAll(fa.getFilters());
+        }
+
+        return filters;
+    }
+
+    private Collection<FileSearchFilter> getEnabledFilters() {
+        Collection<FileSearchFilter> enabledFilters = new ArrayList<FileSearchFilter>();
+
+        for (FileSearchFilter f : this.getFilters()) {
+            if (f.isEnabled()) {
+                enabledFilters.add(f);
+            }
+        }
+
+        return enabledFilters;
+    }
+
+    @Override
+    public TopComponent getTopComponent() {
+        return this;
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentSettings.xml b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentSettings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1e1aace257675a9ea109fb684eca446005286da2
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentSettings.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="org.sleuthkit.autopsy.filesearch" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="org.sleuthkit.autopsy.filesearch.FileSearchTopComponent"/>
+    <instance class="org.sleuthkit.autopsy.filesearch.FileSearchTopComponent" method="getDefault"/>
+</settings>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentWstcref.xml b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentWstcref.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e492dd24f7d054dc33e567223f9c82d58f39957a
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FileSearchTopComponentWstcref.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="org.sleuthkit.autopsy.filesearch" spec="1.0"/>
+    <tc-id id="FileSearchTopComponent"/>
+    <state opened="false"/>
+</tc-ref>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/FilterArea.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FilterArea.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1e8e625cb897c817feeb3b5f8555c5e9c552fc1
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/FilterArea.java
@@ -0,0 +1,126 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import java.awt.Component;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.BoxLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+/**
+ * Holds the filters in one category (and in the future controls toggling the
+ * visibility of the category in the search panel) 
+ * @author pmartel
+ */
+class FilterArea extends JPanel {
+
+//    private JButton toggleButton;
+//    private boolean collapsed;
+    private final String title;
+    private List<FileSearchFilter> filters;
+    private JPanel filtersPanel;
+
+    /**
+     * Filter areas with one filter
+     * @param title name of the area
+     * @param filter single filter
+     */
+    FilterArea(String title, FileSearchFilter filter) {
+        this(title, Collections.singletonList(filter));
+    }
+
+    /**
+     * Filter area with multiple filters
+     * @param title name of the area
+     * @param filters multiple filters
+     */
+    FilterArea(String title, List<FileSearchFilter> filters) {
+        this.title = title;
+        this.filters = filters;
+//        this.collapsed = false;
+        this.init();
+        this.refresh();
+    }
+
+    /**
+     * Get the filters for this area
+     * @return all the filters
+     */
+    List<FileSearchFilter> getFilters() {
+        return filters;
+    }
+
+    private void init() {
+
+        // TODO: this icon (and its twin) should be used in the toggle button
+        // this.dateFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/filesearch/arrow_down.gif"))); // NOI18N
+
+//        toggleButton = new JButton();
+//        toggleButton.setAlignmentX(Component.CENTER_ALIGNMENT);
+//        toggleButton.addActionListener(new ActionListener() {
+//
+//            @Override
+//            public void actionPerformed(ActionEvent e) {
+//                FilterArea.this.toggle();
+//                FilterArea.this.refresh();
+//            }
+//        });
+//
+//        this.add(toggleButton);
+
+        filtersPanel = new JPanel();
+        filtersPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+        BoxLayout filtersPanelLayout = new BoxLayout(filtersPanel, BoxLayout.Y_AXIS);
+        filtersPanel.setLayout(filtersPanelLayout);
+
+        for (FileSearchFilter f : filters) {
+            JComponent filterComponent = f.getComponent();
+            filterComponent.setAlignmentX(Component.LEFT_ALIGNMENT);
+            filterComponent.setBorder(new EmptyBorder(0, 0, 20, 0));
+            filtersPanel.add(filterComponent);
+        }
+
+        this.add(filtersPanel);
+
+        BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
+        this.setLayout(layout);
+    }
+
+    private void refresh() {
+//        int height = toggleButton.getHeight();
+//        toggleButton.setMaximumSize(new Dimension(Integer.MAX_VALUE, height));
+//        
+//        filtersPanel.setVisible(!collapsed);
+//        toggleButton.setText(title);
+//        
+//        filtersPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, filtersPanel.getHeight()));
+//        
+//        this.setPreferredSize(this.getPreferredSize());
+//        
+//        this.revalidate();
+//        this.repaint();
+    }
+//    private void toggle() {
+//        collapsed = !collapsed;
+//    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a55bd2b9970d1d2d74ca447bf8d7a9913f051cc
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchFilter.java
@@ -0,0 +1,76 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import org.sleuthkit.datamodel.TskData.FileKnown;
+
+/**
+ * Filters on the known status of a file (known/unknown/known-bad)
+ */
+class KnownStatusSearchFilter extends AbstractFileSearchFilter<KnownStatusSearchPanel> {
+
+    private static final String NONE_SELECTED_MESSAGE = "At least one known status must be selected!";
+
+    KnownStatusSearchFilter(KnownStatusSearchPanel panel) {
+        super(panel);
+    }
+
+    KnownStatusSearchFilter() {
+        this(new KnownStatusSearchPanel());
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.getComponent().getKnownCheckBox().isSelected();
+    }
+
+    @Override
+    public String getPredicate() throws FilterValidationException {
+        KnownStatusSearchPanel panel = this.getComponent();
+
+        boolean unknown = panel.getUnknownOptionCheckBox().isSelected();
+        boolean known = panel.getKnownOptionCheckBox().isSelected();
+        boolean knownBad = panel.getKnownBadOptionCheckBox().isSelected();
+
+        if (!(unknown || known || knownBad)) {
+            throw new FilterValidationException(NONE_SELECTED_MESSAGE);
+        }
+
+        String expr = "0";
+        if (unknown) {
+            expr += " or " + predicateHelper(FileKnown.UKNOWN);
+        }
+        if (known) {
+            expr += " or " + predicateHelper(FileKnown.KNOWN);
+        }
+        if (knownBad) {
+            expr += " or " + predicateHelper(FileKnown.BAD);
+        }
+        return expr;
+    }
+
+    /**
+     * Make the predicate fragment for a file known status
+     * @param knownStatus status for the file to match
+     * @return un-padded SQL boolean expression
+     */
+    private String predicateHelper(FileKnown knownStatus) {
+        return "known is " + knownStatus.toLong();
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.form b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..8eb2e5fe2c3c76582c33c0960644b998a28a5e66
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.form
@@ -0,0 +1,77 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="knownCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="21" pref="21" max="21" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="knownBadOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Component id="unknownOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+                  <Component id="knownOptionCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="knownCheckBox" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="unknownOptionCheckBox" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="knownOptionCheckBox" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="knownBadOptionCheckBox" min="-2" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JCheckBox" name="knownCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="unknownOptionCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.unknownOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="knownOptionCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="knownBadOptionCheckBox">
+      <Properties>
+        <Property name="selected" type="boolean" value="true"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="KnownStatusSearchPanel.knownBadOptionCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..28475e690c9919e42774f88b35f2b221c14f2c15
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/KnownStatusSearchPanel.java
@@ -0,0 +1,111 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * KnownStatusSearchPanel.java
+ *
+ * Created on Oct 19, 2011, 11:45:44 AM
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import javax.swing.JCheckBox;
+
+/**
+ *
+ * @author pmartel
+ */
+class KnownStatusSearchPanel extends javax.swing.JPanel {
+
+    /** Creates new form KnownStatusSearchPanel */
+    KnownStatusSearchPanel() {
+        initComponents();
+    }
+
+    JCheckBox getKnownCheckBox() {
+        return knownCheckBox;
+    }
+
+    JCheckBox getKnownBadOptionCheckBox() {
+        return knownBadOptionCheckBox;
+    }
+
+    JCheckBox getKnownOptionCheckBox() {
+        return knownOptionCheckBox;
+    }
+
+    JCheckBox getUnknownOptionCheckBox() {
+        return unknownOptionCheckBox;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        knownCheckBox = new javax.swing.JCheckBox();
+        unknownOptionCheckBox = new javax.swing.JCheckBox();
+        knownOptionCheckBox = new javax.swing.JCheckBox();
+        knownBadOptionCheckBox = new javax.swing.JCheckBox();
+
+        knownCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownCheckBox.text")); // NOI18N
+
+        unknownOptionCheckBox.setSelected(true);
+        unknownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.unknownOptionCheckBox.text")); // NOI18N
+
+        knownOptionCheckBox.setSelected(true);
+        knownOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownOptionCheckBox.text")); // NOI18N
+
+        knownBadOptionCheckBox.setSelected(true);
+        knownBadOptionCheckBox.setText(org.openide.util.NbBundle.getMessage(KnownStatusSearchPanel.class, "KnownStatusSearchPanel.knownBadOptionCheckBox.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(knownCheckBox)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(21, 21, 21)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(knownBadOptionCheckBox)
+                    .addComponent(unknownOptionCheckBox)
+                    .addComponent(knownOptionCheckBox)))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(knownCheckBox)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(unknownOptionCheckBox)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(knownOptionCheckBox)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(knownBadOptionCheckBox))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox knownBadOptionCheckBox;
+    private javax.swing.JCheckBox knownCheckBox;
+    private javax.swing.JCheckBox knownOptionCheckBox;
+    private javax.swing.JCheckBox unknownOptionCheckBox;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbe39971709f263f9dea50230d895142fff1d9f4
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchFilter.java
@@ -0,0 +1,57 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
+
+/**
+ *
+ * @author pmartel
+ */
+class NameSearchFilter extends AbstractFileSearchFilter<NameSearchPanel> {
+
+    private static final String EMPTY_NAME_MESSAGE = "Must enter something for name search.";
+
+    public NameSearchFilter() {
+        this(new NameSearchPanel());
+    }
+
+    public NameSearchFilter(NameSearchPanel component) {
+        super(component);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.getComponent().getNameCheckBox().isSelected();
+    }
+
+    @Override
+    public String getPredicate() throws FilterValidationException {
+        String keyword = this.getComponent().getSearchTextField().getText();
+
+        if (keyword.isEmpty()) {
+            throw new FilterValidationException(EMPTY_NAME_MESSAGE);
+        }
+
+        keyword.replace("'", "''"); // escape quotes in string        
+        //TODO: escaping might not be enough, would ideally be part of a prepared statement
+
+        return "name like '%" + keyword + "%'";
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.form b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..52702f54dd10bdafbba2ff128ca5a51a1b33a174
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.form
@@ -0,0 +1,77 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="nameCheckBox" min="-2" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                  <Group type="102" attributes="0">
+                      <EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
+                      <Component id="noteNameLabel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" attributes="1">
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="searchTextField" max="32767" attributes="0"/>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="nameCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="searchTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="noteNameLabel" min="-2" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JCheckBox" name="nameCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.nameCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="searchTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.searchTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="searchTextFieldMouseClicked"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JLabel" name="noteNameLabel">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="10" style="0"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="NameSearchPanel.noteNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7e34c745c16557cdec359a584b6aa0e0e20282f
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/NameSearchPanel.java
@@ -0,0 +1,108 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NameSearchPanel.java
+ *
+ * Created on Oct 19, 2011, 11:58:53 AM
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import javax.swing.JCheckBox;
+import javax.swing.JTextField;
+
+/**
+ *
+ * @author pmartel
+ */
+class NameSearchPanel extends javax.swing.JPanel {
+
+    /** Creates new form NameSearchPanel */
+    NameSearchPanel() {
+        initComponents();
+    }
+
+    JCheckBox getNameCheckBox() {
+        return nameCheckBox;
+    }
+
+    JTextField getSearchTextField() {
+        return searchTextField;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        nameCheckBox = new javax.swing.JCheckBox();
+        searchTextField = new javax.swing.JTextField();
+        noteNameLabel = new javax.swing.JLabel();
+
+        nameCheckBox.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.nameCheckBox.text")); // NOI18N
+
+        searchTextField.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.searchTextField.text")); // NOI18N
+        searchTextField.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                searchTextFieldMouseClicked(evt);
+            }
+        });
+
+        noteNameLabel.setFont(new java.awt.Font("Tahoma", 0, 10));
+        noteNameLabel.setText(org.openide.util.NbBundle.getMessage(NameSearchPanel.class, "NameSearchPanel.noteNameLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(nameCheckBox)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGap(12, 12, 12)
+                        .addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addContainerGap())
+                    .addGroup(layout.createSequentialGroup()
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(searchTextField))))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(nameCheckBox)
+                    .addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(noteNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void searchTextFieldMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_searchTextFieldMouseClicked
+
+        this.nameCheckBox.setSelected(true);     }//GEN-LAST:event_searchTextFieldMouseClicked
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox nameCheckBox;
+    private javax.swing.JLabel noteNameLabel;
+    private javax.swing.JTextField searchTextField;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/OpenParentFolderAction.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/OpenParentFolderAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..781e1366421da1a909a895476630a66372147838
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/OpenParentFolderAction.java
@@ -0,0 +1,88 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.filesearch;
+
+
+import java.awt.event.ActionEvent;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.AbstractAction;
+import org.openide.explorer.ExplorerManager;
+import org.openide.nodes.Node;
+import org.openide.nodes.NodeOp;
+import org.openide.windows.TopComponent;
+import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
+import org.sleuthkit.autopsy.logging.Log;
+
+
+/**
+ * The action to open the parent folder of the given Node
+ */
+public class OpenParentFolderAction extends AbstractAction{
+
+    private String[] paths;
+
+    // for error handling
+    private String className = this.getClass().toString();
+
+    public OpenParentFolderAction(String title, String[] paths){
+        super(title);
+        this.paths = paths;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        Log.noteAction(this.getClass());
+        
+        try {
+
+            ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
+            Node root = em.getRootContext();
+
+            if(paths.length > 1 && root != null) {
+                String[] parentPath = Arrays.copyOf(paths, paths.length - 1);
+                
+                Node parentNode = NodeOp.findPath(root, parentPath);
+                
+                em.setExploredContextAndSelection(parentNode, new Node[]{parentNode});
+                TopComponent dirTree = DirectoryTreeTopComponent.findInstance();
+                if(!dirTree.isOpened()){ dirTree.open(); }
+                dirTree.requestActive(); // make the directory tree the active top component
+
+//                TopComponent resultTable = new DataResultTopComponent();
+//                if(!resultTable.isOpened()){ resultTable.open(); }
+//                resultTable.requestActive(); // make the directory tree the active top component
+                ((DirectoryTreeTopComponent)dirTree).setDirectoryListingActive();
+
+                // make the node table the active top component
+                // @@@ Make the node table the active top component
+
+
+                }
+        
+        } catch (Exception ex) {
+            // throw an error here
+           Logger.getLogger(this.className).log(Level.WARNING, "Error: error while trying to open the parent directory.", ex);
+        }
+    }
+
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchChildren.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchChildren.java
new file mode 100644
index 0000000000000000000000000000000000000000..d13811e214bd312b43c3fefd09cec2d74fd81842
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchChildren.java
@@ -0,0 +1,61 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.filesearch;
+
+
+import java.util.ArrayList;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.sleuthkit.datamodel.Directory;
+import org.sleuthkit.autopsy.datamodel.DirectoryNode;
+import org.sleuthkit.datamodel.File;
+import org.sleuthkit.autopsy.datamodel.FileNode;
+import org.sleuthkit.datamodel.FsContent;
+
+
+/**
+ * Makes nodes for search results.
+ */
+class SearchChildren extends Children.Keys<FsContent> {
+
+    SearchChildren(boolean lazy, ArrayList<FsContent> fsContentList) {
+        super(lazy);
+        this.setKeys(fsContentList);
+    }
+
+
+    @Override
+    protected Node[] createNodes(FsContent t) {
+        Node[] node = new Node[1];
+            if(t.isDir()){
+                node[0] = new DataResultFilterNode(new DirectoryNode((Directory) t));
+
+                //node[0] = new DirectoryNode((Directory)t);
+                return node;
+            }
+            else{
+                node[0] = new DataResultFilterNode(new FileNode((File)t));
+                //node[0] = new FileNode((File)t);
+                return node;
+            }
+    }
+
+    
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchNode.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..f38d584e7a60a366493a545fcfbbc41f7b0fde68
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SearchNode.java
@@ -0,0 +1,119 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.filesearch;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Node.Property;
+import org.sleuthkit.autopsy.datamodel.ContentNode;
+import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.FsContent;
+import org.sleuthkit.datamodel.TskException;
+
+/**
+ *
+ * @author jantonius
+ */
+class SearchNode extends AbstractNode implements ContentNode {
+
+    private SearchChildren children;
+
+    SearchNode(ArrayList<FsContent> keys) {
+        super(new SearchChildren(true, keys));
+        this.children = (SearchChildren)this.getChildren();
+    }
+
+    @Override
+    public String getName() {
+        return "Search Result";
+    }
+
+    @Override
+    public long getID() {
+        return -1; // change this later when needed
+    }
+
+    @Override
+    public Object[][] getRowValues(int rows) throws SQLException {
+        int totalNodes = children.getNodesCount();
+
+        Object[][] objs;
+        int maxRows = 0;
+        if(totalNodes > rows){
+            objs = new Object[rows][];
+            maxRows = rows;
+        }
+        else{
+            objs = new Object[totalNodes][];
+            maxRows = totalNodes;
+        }
+
+        for(int i = 0; i < maxRows; i++){
+            PropertySet[] props = children.getNodeAt(i).getPropertySets();
+            Property[] property = props[0].getProperties();
+            objs[i] = new Object[property.length];
+
+            for(int j = 0; j < property.length; j++){
+                try {
+                    objs[i][j] = property[j].getValue();
+                } catch (Exception ex) {
+                    objs[i][j] = "n/a";
+                }
+            }
+        }
+        return objs;
+    }
+
+
+    @Override
+    public byte[] read(long offset, long len) throws TskException {
+        // change this in the future when needed
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public int getFileIDColumn() {
+        return -1; // change this later when needed
+    }
+
+    @Override
+    public Content getContent() {
+        return null;
+    }
+
+    @Override
+    public String[] getDisplayPath() {
+        return new String[]{"KeyWord Search Result:"};
+    }
+
+    @Override
+    public <T> T accept(ContentNodeVisitor<T> v) {
+        //TODO: figure out how to deal with visitors
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+    
+    @Override
+    public String[] getSystemPath() {
+        // Shouldn't be used
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b960a679c39f55878cbb79bd4bfa5de71b7f93e8
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchFilter.java
@@ -0,0 +1,66 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.filesearch;
+
+import javax.swing.JComboBox;
+import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
+
+/**
+ *
+ * @author pmartel
+ */
+class SizeSearchFilter extends AbstractFileSearchFilter<SizeSearchPanel> {
+
+    SizeSearchFilter() {
+        this(new SizeSearchPanel());
+    }
+
+    SizeSearchFilter(SizeSearchPanel component) {
+        super(component);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.getComponent().getSizeCheckBox().isSelected();
+    }
+
+    @Override
+    public String getPredicate() throws FilterValidationException {
+        int size = ((Number) this.getComponent().getSizeTextField().getValue()).intValue(); // note: already only allow number to the text field
+        String operator = compareComboBoxToOperator(this.getComponent().getSizeCompareComboBox());
+        int unit = this.getComponent().getSizeUnitComboBox().getSelectedIndex();
+        int divider = (int) Math.pow(2, (unit * 10));
+        size = size * divider;
+        return "size " + operator + " " + size;
+    }
+
+    private String compareComboBoxToOperator(JComboBox compare) {
+        String compareSize = compare.getSelectedItem().toString();
+
+        if (compareSize.equals("equal to")) {
+            return "=";
+        } else if (compareSize.equals("greater than")) {
+            return ">";
+        } else if (compareSize.equals("less than")) {
+            return "<";
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.form b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.form
new file mode 100644
index 0000000000000000000000000000000000000000..4c4414ff5c250a4e62042df5344a700e903977dc
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.form
@@ -0,0 +1,87 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="sizeCheckBox" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="sizeCompareComboBox" min="-2" pref="95" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="sizeTextField" min="-2" pref="79" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="sizeUnitComboBox" min="-2" pref="72" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="103" alignment="0" groupAlignment="3" attributes="0">
+              <Component id="sizeCompareComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
+              <Component id="sizeTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+              <Component id="sizeUnitComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
+              <Component id="sizeCheckBox" alignment="3" min="-2" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JComboBox" name="sizeUnitComboBox">
+      <Properties>
+        <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+          <StringArray count="5">
+            <StringItem index="0" value="Byte(s)"/>
+            <StringItem index="1" value="KB"/>
+            <StringItem index="2" value="MB"/>
+            <StringItem index="3" value="GB"/>
+            <StringItem index="4" value="TB"/>
+          </StringArray>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JFormattedTextField" name="sizeTextField">
+      <Properties>
+        <Property name="value" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+          <Connection code="0" type="code"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="sizeTextFieldMouseClicked"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new JFormattedTextField(NumberFormat.getIntegerInstance())"/>
+      </AuxValues>
+    </Component>
+    <Component class="javax.swing.JComboBox" name="sizeCompareComboBox">
+      <Properties>
+        <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+          <StringArray count="3">
+            <StringItem index="0" value="equal to"/>
+            <StringItem index="1" value="greater than"/>
+            <StringItem index="2" value="less than"/>
+          </StringArray>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="sizeCheckBox">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="SizeSearchPanel.sizeCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca97944e4280dd15a32006e5e8729ec74dad18b1
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/SizeSearchPanel.java
@@ -0,0 +1,114 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.filesearch;
+
+import java.text.NumberFormat;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFormattedTextField;
+
+/**
+ *
+ * @author pmartel
+ */
+class SizeSearchPanel extends javax.swing.JPanel {
+
+    /** Creates new form SizeSearchPanel */
+    SizeSearchPanel() {
+        initComponents();
+    }
+
+    JCheckBox getSizeCheckBox() {
+        return sizeCheckBox;
+    }
+
+    JComboBox getSizeCompareComboBox() {
+        return sizeCompareComboBox;
+    }
+
+    JFormattedTextField getSizeTextField() {
+        return sizeTextField;
+    }
+
+    JComboBox getSizeUnitComboBox() {
+        return sizeUnitComboBox;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        sizeUnitComboBox = new javax.swing.JComboBox();
+        sizeTextField = new JFormattedTextField(NumberFormat.getIntegerInstance());
+        sizeCompareComboBox = new javax.swing.JComboBox();
+        sizeCheckBox = new javax.swing.JCheckBox();
+
+        sizeUnitComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Byte(s)", "KB", "MB", "GB", "TB" }));
+
+        sizeTextField.setValue(0);
+        sizeTextField.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                sizeTextFieldMouseClicked(evt);
+            }
+        });
+
+        sizeCompareComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "equal to", "greater than", "less than" }));
+
+        sizeCheckBox.setText(org.openide.util.NbBundle.getMessage(SizeSearchPanel.class, "SizeSearchPanel.sizeCheckBox.text")); // NOI18N
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(sizeCheckBox)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(sizeCompareComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(sizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(sizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                .addComponent(sizeCompareComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addComponent(sizeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addComponent(sizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addComponent(sizeCheckBox))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void sizeTextFieldMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sizeTextFieldMouseClicked
+        this.sizeCheckBox.setSelected(true);
+        this.sizeTextField.selectAll(); // select all so user can change it easily
+    }//GEN-LAST:event_sizeTextFieldMouseClicked
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox sizeCheckBox;
+    private javax.swing.JComboBox sizeCompareComboBox;
+    private javax.swing.JFormattedTextField sizeTextField;
+    private javax.swing.JComboBox sizeUnitComboBox;
+    // End of variables declaration//GEN-END:variables
+}
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_down.gif b/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_down.gif
new file mode 100644
index 0000000000000000000000000000000000000000..1151f48f9a1122e8c97c4a468f36de44bb0e8722
Binary files /dev/null and b/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_down.gif differ
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_right.gif b/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_right.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f85fe5e22577aeb8047714a2d6e21a3c235c44ea
Binary files /dev/null and b/FileSearch/src/org/sleuthkit/autopsy/filesearch/arrow_right.gif differ
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/filesearch-helpset.xml b/FileSearch/src/org/sleuthkit/autopsy/filesearch/filesearch-helpset.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4cf665f1394664260f0942824f31892e37b2f878
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/filesearch-helpset.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE helpsetref PUBLIC "-//NetBeans//DTD JavaHelp Help Set Reference 1.0//EN" "http://www.netbeans.org/dtds/helpsetref-1_0.dtd">
+<helpsetref url="nbdocs:/org/sleuthkit/autopsy/filesearch/docs/filesearch-hs.xml"/>
diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/layer.xml b/FileSearch/src/org/sleuthkit/autopsy/filesearch/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..36332b2899d32a068cf8b7c352337474a7b3424c
--- /dev/null
+++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/layer.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Window">
+            <file name="org-sleuthkit-autopsy-filesearch-FileSearchAction.instance">
+                <attr name="component" methodvalue="org.sleuthkit.autopsy.filesearch.FileSearchTopComponent.findInstance"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.filesearch.Bundle#CTL_FileSearchAction"/>
+                <attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window"/>
+    </folder>
+    <folder name="Services">
+        <folder name="JavaHelp">
+            <file name="filesearch-helpset.xml" url="filesearch-helpset.xml">
+                <attr name="position" intvalue="3662"/>
+            </file>
+        </folder>
+        <file name="org-sleuthkit-autopsy-filesearch-FileSearchTopComponent.instance">
+            <attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer"/>
+            <attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.filesearch.FileSearchTopComponent.getDefault"/>
+        </file>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="FileSearchTopComponent.settings" url="FileSearchTopComponentSettings.xml"/>
+        </folder>
+
+        <!-- Not letting NetBeans manage docking for us at all. It's all handled in CoreComponentInterfaces:CoreComponentControl
+        <folder name="Modes">
+            <folder name="explorer">
+                <file name="FileSearchTopComponent.wstcref" url="FileSearchTopComponentWstcref.xml"/>
+            </folder>
+        </folder-->
+    </folder>
+</filesystem>
diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7
--- /dev/null
+++ b/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Logging/build.xml b/Logging/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fbf2530e25429c5a4c05255be332f4658ec7781e
--- /dev/null
+++ b/Logging/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.logging" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.logging.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/Logging/manifest.mf b/Logging/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..7883520189b64b4b964c1b5f0f9c1d588d7da2ed
--- /dev/null
+++ b/Logging/manifest.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.logging/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Install: org/sleuthkit/autopsy/logging/Installer.class
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/logging/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/logging/Bundle.properties
+
diff --git a/Logging/nbproject/build-impl.xml b/Logging/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0b474da86198572f3d1f2e535cdd54a99610c25a
--- /dev/null
+++ b/Logging/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.logging-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/Logging/nbproject/genfiles.properties b/Logging/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d94cf243106a3abb7e558f30a5ed6cad86965a3d
--- /dev/null
+++ b/Logging/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=cacaba65
+build.xml.script.CRC32=5960e63f
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=cacaba65
+nbproject/build-impl.xml.script.CRC32=db164ed0
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/Logging/nbproject/platform.properties b/Logging/nbproject/platform.properties
new file mode 100644
index 0000000000000000000000000000000000000000..319807f1cdb475e3c29716dc6e9c32f71c07cfbe
--- /dev/null
+++ b/Logging/nbproject/platform.properties
@@ -0,0 +1,7 @@
+cluster.path=\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    org.netbeans.libs.jsr223,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+nbplatform.active=default
diff --git a/Logging/nbproject/private/platform-private.properties b/Logging/nbproject/private/platform-private.properties
new file mode 100644
index 0000000000000000000000000000000000000000..feb70af372bba13f8dddc96b62d5fb16d69687d2
--- /dev/null
+++ b/Logging/nbproject/private/platform-private.properties
@@ -0,0 +1 @@
+user.properties.file=C:\\Users\\pmartel\\.netbeans\\6.9\\build.properties
diff --git a/Logging/nbproject/private/private.xml b/Logging/nbproject/private/private.xml
new file mode 100644
index 0000000000000000000000000000000000000000..137618d8d27eb2181b980440dee5aafc7ffe0499
--- /dev/null
+++ b/Logging/nbproject/private/private.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+    <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1">
+        <file>
+            <url>src/org/sleuthkit/autopsy/logging/Installer.java</url>
+            <line>62</line>
+        </file>
+    </editor-bookmarks>
+</project-private>
diff --git a/Logging/nbproject/project.properties b/Logging/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c51692cafc19134f77f8ba341594b3e9ff4df820
--- /dev/null
+++ b/Logging/nbproject/project.properties
@@ -0,0 +1,3 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=0.0
diff --git a/Logging/nbproject/project.xml b/Logging/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0adbf513eec24f070f15f1fa4739e4027f6df530
--- /dev/null
+++ b/Logging/nbproject/project.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.netbeans.core</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>2</release-version>
+                        <implementation-version/>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.15.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.logging</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/Logging/nbproject/suite.properties b/Logging/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/Logging/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/AutopsyExceptionHandler.java b/Logging/src/org/sleuthkit/autopsy/logging/AutopsyExceptionHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..22b7779e00fb09148e4faf8569fb216981865eda
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/AutopsyExceptionHandler.java
@@ -0,0 +1,154 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.logging;
+
+import java.awt.Component;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.SimpleFormatter;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+import org.openide.util.lookup.ServiceProvider;
+import org.netbeans.core.NbErrorManager;
+
+/**
+ * Replaces default NetBeans exception handler. Displays messages in a dialog.
+ */
+@ServiceProvider(service = Handler.class, supersedes = "org.netbeans.core.NbErrorManager")
+public class AutopsyExceptionHandler extends Handler {
+
+    static final int INFO_VALUE = Level.INFO.intValue();
+    static final int WARNING_VALUE = Level.WARNING.intValue();
+    static final int SEVERE_VALUE = Level.SEVERE.intValue();
+    static final Handler nbErrorManager = new NbErrorManager(); // Default NetBeans handler
+
+    public AutopsyExceptionHandler() {
+        super();
+        // Only display messages for WARNING level and above, that come from an uncaught exception.
+        this.setLevel(Level.WARNING);
+        this.setFilter(new ExceptionFilter());
+        this.setFormatter(new SimpleFormatter());
+    }
+
+    @Override
+    public void publish(LogRecord record) {
+
+        if (isLoggable(record)) {
+
+            if (record.getMessage() != null) {
+                // Throwable was anticipated, caught and logged. Display log message and throwable message.
+
+                final int levelValue = record.getLevel().intValue();
+                
+                final Component parentComponent = null; // Use default window frame.
+                final String message = formatExplanation(record);
+                final String title = getTitleForLevelValue(levelValue);
+                final int messageType = getMessageTypeForLevelValue(levelValue);
+
+                // publish() was probably not called from the EDT, so run the message box there instead of here.
+                SwingUtilities.invokeLater(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        JOptionPane.showMessageDialog(
+                                parentComponent,
+                                message,
+                                title,
+                                messageType);
+                    }
+                });
+            } else {
+                // Throwable (unanticipated) error. Use built-in exception handler to offer details, stacktrace.
+                nbErrorManager.publish(record);
+            }
+        }
+    }
+
+
+    /**
+     * Filter only accepts records with exceptions attached.
+     */
+    private static class ExceptionFilter implements Filter {
+        @Override
+        public boolean isLoggable(LogRecord record) {
+            // True if there is an uncaught exception being thrown.
+            return record.getThrown() != null;
+        }
+    }
+
+    /**
+     *
+     * @param record A LogRecord with both a message and associated Throwable set.
+     * @return A String containing the log message and the cause of the Throwable (if there is one).
+     */
+    private String formatExplanation(LogRecord record) {
+        final String logMessage = getFormatter().formatMessage(record);
+        String explanation = record.getThrown().getMessage();
+        String causeMessage = (explanation != null) ? "\nCaused by: " + explanation : "";
+
+        return logMessage + causeMessage;
+    }
+
+//    It's harder to do this cleanly than I thought, because Exceptions
+//    initialized with no message copy and prepend the cause's message
+//
+//    private String recursiveExplanation(Throwable e) {
+//        String message = e.getMessage();
+//        String explanation = (message != null) ? "\nCaused by: " + message : "";
+//        Throwable cause = e.getCause();
+//        if (cause == null) {
+//            return explanation;
+//        } else {
+//            return explanation + recursiveExplanation(cause);
+//        }
+//    }
+
+    private static int getMessageTypeForLevelValue(int levelValue) {
+        if (levelValue >= SEVERE_VALUE) {
+            return JOptionPane.ERROR_MESSAGE;
+        } else if (levelValue >= WARNING_VALUE) {
+            return JOptionPane.WARNING_MESSAGE;
+        } else {
+            return JOptionPane.INFORMATION_MESSAGE;
+        }
+    }
+
+    private static String getTitleForLevelValue(int levelValue) {
+        if (levelValue >= SEVERE_VALUE) {
+            return "Error";
+        } else if (levelValue >= WARNING_VALUE) {
+            return "Warning";
+        } else {
+            return "Message";
+        }
+    }
+
+    @Override
+    public void flush() {
+        // no buffer to flush
+    }
+
+    @Override
+    public void close() throws SecurityException {
+        // no resources to close
+    }
+}
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/Bundle.properties b/Logging/src/org/sleuthkit/autopsy/logging/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7ff32e866b13246b2fc9d39b80a150294a214119
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/Bundle.properties
@@ -0,0 +1,2 @@
+CTL_TestLogger=Test log
+OpenIDE-Module-Name=Logging
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/Installer.java b/Logging/src/org/sleuthkit/autopsy/logging/Installer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8fa016254f23b38d0f972cfaf9d6ce76773c58a
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/Installer.java
@@ -0,0 +1,63 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.logging;
+
+import java.io.IOException;
+import java.util.logging.FileHandler;
+import org.openide.modules.ModuleInstall;
+import java.util.logging.Logger;
+import java.util.logging.Handler;
+import java.util.logging.SimpleFormatter;
+
+
+
+/**
+ * Manages a this module's lifecycle. Sets up logging to file.
+ */
+public class Installer extends ModuleInstall {
+
+    static final Logger autopsyLogger = Logger.getLogger("");
+    static final String LOG_FILENAME_PATTERN = System.getProperty("netbeans.user") + "/var/log/autopsy.log"; //%t is system temp dir, %g is log number
+    static final int LOG_SIZE = 0; // in bytes, zero is unlimited
+    static final int LOG_FILE_COUNT = 10;
+    static Handler logs;
+
+    @Override
+    public void restored() {
+        if (logs == null) {
+            try {
+                logs = new FileHandler(LOG_FILENAME_PATTERN, LOG_SIZE, LOG_FILE_COUNT);;
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+            logs.setFormatter(new SimpleFormatter());
+            autopsyLogger.addHandler(logs);
+        }
+    }
+    
+    @Override
+    public void uninstalled() {
+        autopsyLogger.removeHandler(logs);
+        logs.close();
+        logs = null;
+    }
+
+
+}
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/Log.java b/Logging/src/org/sleuthkit/autopsy/logging/Log.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8df07d91bda6bc856a7e41312eb3933b9eac83c
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/Log.java
@@ -0,0 +1,42 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.logging;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Helper class to slightly simplify getting the logger for a class, and other
+ * common log tasks.
+ */
+public class Log {
+    static public void noteAction(Class actionClass) {
+        get(actionClass).log(Level.INFO, "Action performed: {0}", actionClass.getName());
+    }
+
+
+    static public Logger get(Class clazz) {
+        return Logger.getLogger(clazz.getName());
+    }
+    
+    static public Logger get(String loggerName) {
+        return Logger.getLogger(loggerName);
+    }
+}
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/LogIcon.png b/Logging/src/org/sleuthkit/autopsy/logging/LogIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e2908c13a57e3f3d1bb6b1678f0a10094388093
Binary files /dev/null and b/Logging/src/org/sleuthkit/autopsy/logging/LogIcon.png differ
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/TestLogger.java b/Logging/src/org/sleuthkit/autopsy/logging/TestLogger.java
new file mode 100644
index 0000000000000000000000000000000000000000..54dd06b40a36d8d721e204a98390f9a630046b3e
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/TestLogger.java
@@ -0,0 +1,43 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.logging;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.logging.Formatter;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/*
+ * Toolbar button for testing logging. Not a normal part of application.
+ */
+public final class TestLogger implements ActionListener {
+
+    static final Logger logger = Logger.getLogger(TestLogger.class.getName());
+    Formatter fmt;
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        
+        logger.log(Level.WARNING, "Testing log!", new Exception(new Exception(new Exception(new Exception("original reason with asdfasdfasdfasdfasd fasdfasdfasdf sdfasdfasdfa asdfasdf asdfa sdfas ", new Exception("more original reason"))))));
+        //throw new RuntimeException("othe");
+
+        //logger.log(Level.WARNING, "Testing log!");
+    }
+}
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/TimestampingFormatter.java b/Logging/src/org/sleuthkit/autopsy/logging/TimestampingFormatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e52520e0ccde58dc4b00c9dcb0e925c39cfc9dd
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/TimestampingFormatter.java
@@ -0,0 +1,50 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.sleuthkit.autopsy.logging;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+/*
+ * Formatter to wrap another formatter and prepend a timestampe to each formatted string
+ * Not currently used.
+ */
+public class TimestampingFormatter extends Formatter {
+
+    Formatter original;
+    DateFormat timestampFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
+    String lineSeparator = System.getProperty("line.separator");
+
+    TimestampingFormatter(Formatter original) {
+        this.original = original;
+    }
+
+    @Override
+    public String format(LogRecord record) {
+        long millis = record.getMillis();
+        String timestamp = timestampFormat.format(new Date(millis));
+
+        return timestamp + lineSeparator + original.format(record);
+    }
+}
diff --git a/Logging/src/org/sleuthkit/autopsy/logging/layer.xml b/Logging/src/org/sleuthkit/autopsy/logging/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..25d015eaf52d7ba84d7d1fc28cf262a4a87ae9d1
--- /dev/null
+++ b/Logging/src/org/sleuthkit/autopsy/logging/layer.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Edit"/>
+    </folder>
+    <folder name="Toolbars">
+        <folder name="File"/>
+    </folder>
+</filesystem>
diff --git a/MenuActions/build.xml b/MenuActions/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7f26f62e4a33bceb714ef0e0104b1ddcb68460f4
--- /dev/null
+++ b/MenuActions/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="org.sleuthkit.autopsy.menuactions" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project org.sleuthkit.autopsy.menuactions.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
diff --git a/MenuActions/manifest.mf b/MenuActions/manifest.mf
new file mode 100644
index 0000000000000000000000000000000000000000..c92eae3577716f16e7eacddcb8c70ddf00ffc4d4
--- /dev/null
+++ b/MenuActions/manifest.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.sleuthkit.autopsy.menuactions/0
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Layer: org/sleuthkit/autopsy/menuactions/layer.xml
+OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/menuactions/Bundle.properties
+
diff --git a/MenuActions/nbproject/build-impl.xml b/MenuActions/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2502efc722f978087e7cd3d081fa84c301aa94a3
--- /dev/null
+++ b/MenuActions/nbproject/build-impl.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="org.sleuthkit.autopsy.menuactions-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
diff --git a/MenuActions/nbproject/genfiles.properties b/MenuActions/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4ab1b65f736572cc657d016a2e29df460d7423cc
--- /dev/null
+++ b/MenuActions/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=b49f5bc1
+build.xml.script.CRC32=46209f11
+build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=b49f5bc1
+nbproject/build-impl.xml.script.CRC32=cb422238
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.42.2
diff --git a/MenuActions/nbproject/project.properties b/MenuActions/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c51692cafc19134f77f8ba341594b3e9ff4df820
--- /dev/null
+++ b/MenuActions/nbproject/project.properties
@@ -0,0 +1,3 @@
+javac.source=1.6
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=0.0
diff --git a/MenuActions/nbproject/project.xml b/MenuActions/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..32ed35628a0744b0dd7697af835c69f2de716e1e
--- /dev/null
+++ b/MenuActions/nbproject/project.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>org.sleuthkit.autopsy.menuactions</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.28.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.modules</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.17.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.33.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.casemodule</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponentinterfaces</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.corecomponents</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.directorytree</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.filesearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.logging</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>0-1</release-version>
+                        <specification-version>0.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>org.sleuthkit.autopsy.menuactions</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
diff --git a/MenuActions/nbproject/suite.properties b/MenuActions/nbproject/suite.properties
new file mode 100644
index 0000000000000000000000000000000000000000..29d7cc9bd6fdd81453543cdf1bcf1dab301e3a92
--- /dev/null
+++ b/MenuActions/nbproject/suite.properties
@@ -0,0 +1 @@
+suite.dir=${basedir}/..
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/Bundle.properties b/MenuActions/src/org/sleuthkit/autopsy/menuactions/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..090b77bcefc99eb89c4d7077bde81e54fa9829d0
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/Bundle.properties
@@ -0,0 +1,2 @@
+CTL_FileBrowserAction=File Browser
+OpenIDE-Module-Name=MenuActions
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentDynamicMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentDynamicMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..661fca1f330c45c47cdebfe9c11663d2dc5b12ac
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentDynamicMenu.java
@@ -0,0 +1,85 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import java.util.List;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import org.openide.awt.DynamicMenuContent;
+import org.openide.util.Lookup;
+import org.openide.windows.TopComponent;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
+import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
+
+/**
+ *
+ * @author jantonius
+ */
+public class DataContentDynamicMenu extends JMenuItem implements DynamicMenuContent {
+
+    @Override
+    public JComponent[] getMenuPresenters() {
+        List<DataContentTopComponent> newWindowLists = DataContentTopComponent.getNewWindowList();
+
+        // Get DataContent provider to include in the menu
+        DataContent dataContent = Lookup.getDefault().lookup(DataContent.class);
+        int totalItems = newWindowLists.size() > 0 ? 2 : 1;
+        JComponent[] comps = new JComponent[totalItems];
+        int counter = 0;
+        
+        TopComponent contentWin = dataContent.getTopComponent();
+        JMenuItem defaultItem = new JMenuItem(contentWin.getName()); // set the main name
+
+        defaultItem.addActionListener(new OpenTopComponentAction(contentWin));
+
+        if (!Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0) {
+            defaultItem.setEnabled(false); // disable the menu items when no case is opened
+        } else {
+            defaultItem.setEnabled(true); // enable the menu items when there's a case opened / created
+        }
+
+        comps[counter++] = defaultItem;
+
+        // add the submenu
+        if (newWindowLists != null) {
+            if (newWindowLists.size() > 0) {
+
+                JMenu submenu = new JMenu("Data Content Windows");
+                for (int i = 0; i < newWindowLists.size(); i++) {
+                    DataContentTopComponent dctc = newWindowLists.get(i);
+                    JMenuItem item = new JMenuItem(dctc.getName());
+                    item.addActionListener(new OpenTopComponentAction(dctc));
+                    submenu.add(item);
+                }
+
+                comps[counter++] = submenu;
+            }
+        }
+
+        return comps;
+    }
+
+    @Override
+    public JComponent[] synchMenuPresenters(JComponent[] jcs) {
+        return getMenuPresenters();
+    }
+}
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..4468794852d01d4162cdb8805209308895cb1e45
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataContentMenu.java
@@ -0,0 +1,54 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import javax.swing.JMenuItem;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+
+/**
+ * Menu item that displays DataContentViewers
+ */
+public class DataContentMenu extends CallableSystemAction implements Presenter.Menu {
+
+    DataContentMenu(){}
+
+    @Override
+    public JMenuItem getMenuPresenter() {
+        return new DataContentDynamicMenu();
+    }
+
+    @Override
+    public void performAction() {
+
+    }
+
+    @Override
+    public String getName() {
+        return "DataContent Menu";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+}
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerDynamicMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerDynamicMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..9321e4a3d0b24e434868576c71f86f717efb981e
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerDynamicMenu.java
@@ -0,0 +1,71 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import java.util.Collection;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import org.openide.awt.DynamicMenuContent;
+import org.openide.util.Lookup;
+import org.openide.windows.TopComponent;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
+
+/**
+ * Populates the top-level menu with the list of DataExplorers.
+ * 
+ * @author jantonius
+ */
+public class DataExplorerDynamicMenu extends JMenuItem implements DynamicMenuContent{
+   DataExplorerDynamicMenu(){
+    }
+
+    @Override
+    public JComponent[] getMenuPresenters() {
+        Collection<? extends DataExplorer> dataExplorers = Lookup.getDefault().lookupAll(DataExplorer.class);
+
+        int totalItem = dataExplorers.size();
+        JComponent[] comps = new JComponent[totalItem];
+        
+        int i = 0;
+        for(DataExplorer dx : dataExplorers){
+            TopComponent explorerWin = dx.getTopComponent();
+            JMenuItem item = new JMenuItem(explorerWin.getName());
+            item.addActionListener(new OpenTopComponentAction(explorerWin));
+
+            if(!Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0){
+                item.setEnabled(false); // disable the menu when no case is opened
+            }
+            else{
+                item.setEnabled(true); // enable the menu if the case is opened or created
+            }
+
+            comps[i++] = item;
+        }
+
+        return comps;
+    }
+
+    @Override
+    public JComponent[] synchMenuPresenters(JComponent[] jcs) {
+        return getMenuPresenters();
+    }
+
+}
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..610669076806a7fbd4de895ccf225a39d3811099
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataExplorerMenu.java
@@ -0,0 +1,52 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import javax.swing.JMenuItem;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+
+/**
+ * Menu item that tracks available DataExplorers.
+ * @author jantonius
+ */
+public class DataExplorerMenu extends CallableSystemAction implements Presenter.Menu {
+
+    @Override
+    public JMenuItem getMenuPresenter() {
+        return new DataExplorerDynamicMenu();
+    }
+
+    @Override
+    public void performAction() {
+
+    }
+
+    @Override
+    public String getName() {
+        return "DataExplorer Tools";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+} 
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataResultMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataResultMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..06c67001df0555caf7dd9c8f91f7ea4a851e85f5
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/DataResultMenu.java
@@ -0,0 +1,83 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+import org.openide.util.actions.Presenter;
+import org.sleuthkit.autopsy.casemodule.Case;
+
+/**
+ * Menu item tracks the DataResult windows
+ */
+public class DataResultMenu extends CallableSystemAction implements Presenter.Menu, PropertyChangeListener {
+
+    JMenu menu = new JMenu("DataResult Windows");
+
+    DataResultMenu(){
+    }
+
+    @Override
+    public JMenuItem getMenuPresenter() {
+        return new SearchResultMenu();
+    }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        String changed = evt.getPropertyName();
+        Object oldValue = evt.getOldValue();
+        Object newValue = evt.getNewValue();
+
+        if (changed.equals(Case.CASE_CURRENT_CASE)) {
+            if (newValue != null) {
+                // enable all menus when a case is created / opened
+                int totalMenus = menu.getItemCount();
+                for (int i = 0; i < totalMenus; i++) {
+                    menu.getItem(i).setEnabled(true);
+                }
+            } else {
+                // disable all menus when the case is closed
+                int totalMenus = menu.getItemCount();
+                for (int i = 0; i < totalMenus; i++) {
+                    menu.getItem(i).setEnabled(false);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void performAction() {
+        
+    }
+
+    @Override
+    public String getName() {
+        return "DataResult Menu";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+}
\ No newline at end of file
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/OpenTopComponentAction.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/OpenTopComponentAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..42c9aac62c72a13eb227bec73362fb194e1140ab
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/OpenTopComponentAction.java
@@ -0,0 +1,45 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.windows.TopComponent;
+
+/**
+ * This action opens the TopComponent passed to the constructor
+ */
+public class OpenTopComponentAction extends AbstractAction{
+
+    TopComponent tc;
+
+    OpenTopComponentAction(TopComponent top){
+        this.tc = top;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if(!this.tc.isOpened()){
+            this.tc.open();
+        }
+        this.tc.requestActive();
+    }
+
+}
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/SearchResultMenu.java b/MenuActions/src/org/sleuthkit/autopsy/menuactions/SearchResultMenu.java
new file mode 100644
index 0000000000000000000000000000000000000000..60eafc3b58a0d8ae698d19dac9dfa37083792721
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/SearchResultMenu.java
@@ -0,0 +1,77 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.sleuthkit.autopsy.menuactions;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import org.openide.awt.DynamicMenuContent;
+import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
+import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
+import org.sleuthkit.autopsy.filesearch.FileSearchTopComponent;
+
+/**
+ * Menu item lists DataResult tabs.w
+ */
+public class SearchResultMenu extends JMenuItem implements DynamicMenuContent {
+
+    SearchResultMenu(){
+    }
+
+    @Override
+    public JComponent[] getMenuPresenters() {
+        List<DataResultTopComponent> searchResults = FileSearchTopComponent.getFileSearchResultList();
+        DirectoryTreeTopComponent directoryTree = DirectoryTreeTopComponent.findInstance();
+        DataResultTopComponent directoryListing = directoryTree.getDirectoryListing();
+
+
+
+        List<JComponent> menuItems = new ArrayList<JComponent>();
+        
+        // add the main "DirectoryListing"
+        JMenuItem dlItem = new JMenuItem(directoryListing.getName());
+        dlItem.addActionListener(new OpenTopComponentAction(directoryListing));
+        dlItem.setEnabled(directoryTree.isOpened());
+
+        menuItems.add(dlItem);
+
+
+        // add search results if there are any
+        if(searchResults.size() > 0){
+            JMenu submenu = new JMenu("File Search Results");
+            for(DataResultTopComponent resultTab : searchResults){
+                JMenuItem item = new JMenuItem(resultTab.getName());
+                item.addActionListener(new OpenTopComponentAction(resultTab));
+                submenu.add(item);
+            }
+
+            menuItems.add(submenu);
+        }
+
+        return menuItems.toArray(new JComponent[menuItems.size()]);
+    }
+
+    @Override
+    public JComponent[] synchMenuPresenters(JComponent[] jcs) {
+        return getMenuPresenters();
+    }
+}
diff --git a/MenuActions/src/org/sleuthkit/autopsy/menuactions/layer.xml b/MenuActions/src/org/sleuthkit/autopsy/menuactions/layer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9b009d6f12b7aaeae115d30bd8fc2ac992cb5574
--- /dev/null
+++ b/MenuActions/src/org/sleuthkit/autopsy/menuactions/layer.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Tools">
+            <file name="org-sleuthkit-autopsy-menuactions-FileBrowserAction.instance">
+                <attr name="delegate" newvalue="org.sleuthkit.autopsy.menuactions.FileBrowserAction"/>
+                <attr name="displayName" bundlevalue="org.sleuthkit.autopsy.menuactions.Bundle#CTL_FileBrowserAction"/>
+                <attr name="noIconInMenu" boolvalue="false"/>
+            </file>
+        </folder>
+        <folder name="Window">
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Tools">
+            <file name="org-sleuthkit-autopsy-menuactions-DataExplorerMenu.instance">
+                <attr name="position" intvalue="1225"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-DataExplorerMenu-separatoAfter.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="1250"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-FileBrowserAction-separatorAfter.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="1301"/>
+            </file>
+        </folder>
+        <folder name="Window">
+            <file name="org-netbeans-modules-favorites-View.shadow_hidden"/>
+            <file name="org-sleuthkit-autopsy-menuactions-DataResultMenu-separatoBefore.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="75"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-DataResultMenu.instance">
+                <attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-menuactions-DataResultMenu.instance"/>
+                <attr name="position" intvalue="100"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-DataResultMenu-separatoAfter.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="125"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-DataContentMenu.instance">
+                <attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-menuactions-DataContentMenu.instance"/>
+                <attr name="position" intvalue="150"/>
+            </file>
+            <file name="org-sleuthkit-autopsy-menuactions-DataContentMenu-separatorAfter.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="175"/>
+            </file>
+       </folder>
+    </folder>
+</filesystem>
diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..dbffcdcceef3135c8997d2c15a3f2287d103ad26
--- /dev/null
+++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
@@ -0,0 +1,8 @@
+currentVersion=Autopsy {0}
+LBL_splash_window_title=Starting Autopsy
+SPLASH_HEIGHT=288
+SPLASH_WIDTH=538
+SplashProgressBarBounds=3,236,533,6
+SplashRunningTextBounds=5,212,530,17
+SplashRunningTextColor=0x0
+SplashRunningTextFontSize=18
diff --git a/branding/core/core.jar/org/netbeans/core/startup/frame.gif b/branding/core/core.jar/org/netbeans/core/startup/frame.gif
new file mode 100644
index 0000000000000000000000000000000000000000..08dc748a0046d27fd09fc9c9d046e6971bcc241e
Binary files /dev/null and b/branding/core/core.jar/org/netbeans/core/startup/frame.gif differ
diff --git a/branding/core/core.jar/org/netbeans/core/startup/frame32.gif b/branding/core/core.jar/org/netbeans/core/startup/frame32.gif
new file mode 100644
index 0000000000000000000000000000000000000000..0cc097241a9227807e7d92aa191e00752cb23270
Binary files /dev/null and b/branding/core/core.jar/org/netbeans/core/startup/frame32.gif differ
diff --git a/branding/core/core.jar/org/netbeans/core/startup/frame48.gif b/branding/core/core.jar/org/netbeans/core/startup/frame48.gif
new file mode 100644
index 0000000000000000000000000000000000000000..3c6cdfd5870d5af946cdc2106774eb357753ccb6
Binary files /dev/null and b/branding/core/core.jar/org/netbeans/core/startup/frame48.gif differ
diff --git a/branding/core/core.jar/org/netbeans/core/startup/splash.gif b/branding/core/core.jar/org/netbeans/core/startup/splash.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a02e27f26bf3d2d842592562cadb46e775236905
Binary files /dev/null and b/branding/core/core.jar/org/netbeans/core/startup/splash.gif differ
diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..3400dcc9c95a417f4d1fd601383d7cb995558637
--- /dev/null
+++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
@@ -0,0 +1,2 @@
+CTL_MainWindow_Title=Autopsy {0}
+CTL_MainWindow_Title_No_Project=Autopsy {0}
diff --git a/build-unix.xml b/build-unix.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2cb9866ffb3986b6105fb791d7bee001ca7d6aa1
--- /dev/null
+++ b/build-unix.xml
@@ -0,0 +1,8 @@
+<project name="AutopsyTSKTargets">
+    <target name="copyTSKLibs">
+    <property environment="env"/>
+        <copy file="${env.TSK_HOME}/bindings/java/jni/.libs/libtsk_jni.dylib" tofile="${basedir}/DataModel/release/modules/lib/libtsk_jni.dylib"/>
+        <!-- <copy file="${env.TSK_HOME}/win32/libewf/msvscpp/Release/libewf.dll" tofile="${basedir}/DataModel/release/modules/lib/libewf.dll"/> 
+        <copy file="${env.TSK_HOME}/win32/libewf/msvscpp/zlib/zlib1.dll" tofile="${basedir}/DataModel/release/modules/lib/zlib1.dll"/> -->
+    </target>
+</project>
diff --git a/build-windows.xml b/build-windows.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aef70062310f76534c39499dd17711f7863480ee
--- /dev/null
+++ b/build-windows.xml
@@ -0,0 +1,14 @@
+<project name="AutopsyTSKTargets">
+    <target name="copyTSKLibs">
+        <property environment="env"/>
+        <condition property="ewfFound">
+            <isset property="env.LIBEWF_HOME"/>
+        </condition>
+        <fail unless="ewfFound" message="LIBEWF_HOME must be set as an environment variable."/>
+
+        <!-- Need a way to specify Debug versus release -->
+        <copy file="${env.TSK_HOME}/win32/release/libtsk_jni.dll" tofile="${basedir}/DataModel/release/modules/lib/libtsk_jni.dll"/>
+        <copy file="${env.LIBEWF_HOME}/msvscpp/Release/libewf.dll" tofile="${basedir}/DataModel/release/modules/lib/libewf.dll"/> 
+        <copy file="${env.LIBEWF_HOME}/msvscpp/zlib/zlib1.dll" tofile="${basedir}/DataModel/release/modules/lib/zlib1.dll"/>
+    </target>
+</project>
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..614f35e862796311453c417b793a4aa1ab90e3b7
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="Autopsy3" basedir=".">
+    <description>Builds the module suite Autopsy3.</description>
+    <import file="nbproject/build-impl.xml"/>
+
+    
+    <condition property="os.family" value="unix">  
+        <os family="unix"/>  
+    </condition>  
+    <condition property="os.family" value="windows">  
+        <os family="windows"/>  
+    </condition>  
+    <import file="build-${os.family}.xml"/>  
+
+    
+    <!-- This seems really bad to be hard coded, but I couldn't find a better solution -->
+    <path id="jni-path">
+        <pathelement location="./build/cluster/modules/org-sleuthkit-datamodel.jar"/>
+        <path refid="cluster.path.id" />
+    </path>
+
+    <!-- Verify that the TSK_HOME env variable is set -->
+    <target name="findTSK">
+        <property environment="env"/>
+        <condition property="tskFound">
+            <isset property="env.TSK_HOME"/>
+        </condition>
+        <fail unless="tskFound" message="TSK_HOME must be set as an environment variable."/>
+        <echo> TSK_HOME: ${env.TSK_HOME}</echo>
+        
+    </target>
+
+    <target name="getExternals" depends="findTSK,copyTSKLibs">
+        <property environment="env"/>
+        <copy file="${env.TSK_HOME}/bindings/java/dist/Tsk_DataModel.jar" tofile="${basedir}/DataModel/release/modules/ext/Tsk_DataModel.jar"/>
+        <copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.6.20.jar" tofile="${basedir}/DataModel/release/modules/ext/sqlite-jdbc-3.6.20.jar"/>
+        <!--<copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.6.20-javadoc.jar" tofile="${basedir}/DataModel/release/modules/ext/sqlite-jdbc-3.6.20-javadoc.jar"/>
+        <copy file="${env.TSK_HOME}/bindings/java/lib/sqlite-jdbc-3.6.20-sources.jar" tofile="${basedir}/DataModel/release/modules/ext/sqlite-jdbc-3.6.20-sources.jar"/> -->
+    </target>
+
+    <!-- This target will create a custom ZIP file for us.  It first uses the general
+      ZIP target and then opens it up and adds in any files that we want.  This is where we customize the
+      version number. -->
+    <target name="build-zip" depends="suite.build-zip">
+        <property name="nbdist.dir" value="dist"/>
+        <property name="release.dir" value="${nbdist.dir}/${app.name}"/>
+
+        <!-- step (2) unzip the result  -->
+        <property name="zip-tmp" value="${nbdist.dir}/tmp"/>
+        <delete dir="${zip-tmp}"/>
+        <mkdir dir="${zip-tmp}"/>
+        <unzip src="${nbdist.dir}/${app.name}.zip" dest="${zip-tmp}"/>
+
+        <!-- step (3) do your copying stuff here, check the ant doc for copy, move, etc file -->
+        <copy file="${basedir}/README.txt" tofile="${zip-tmp}/${app.name}/README.txt"/>
+        <copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/>
+        
+        <!-- step (4) zip again, but with the version numbers in the dir -->
+        <zip destfile="${nbdist.dir}/${app.name}-${app.version}.zip">
+            <zipfileset dir="${zip-tmp}/${app.name}" prefix="${app.name}-${app.version}"/>
+        </zip>
+
+        <delete dir="${zip-tmp}"/>
+        <delete file="${nbdist.dir}/${app.name}.zip"/>
+
+        <echo message=" "/>
+        <echo message="cleaning and finalizing release" />
+        <delete dir="${release.dir}"/>
+    </target>
+
+
+    <target name="-init" depends="-taskdefs,-convert-old-project,getExternals">
+        <convertclusterpath from="${cluster.path.evaluated}" to="cluster.path.final" id="cluster.path.id"/>
+        <property file="nbproject/private/private.properties"/>
+        <property file="nbproject/project.properties"/>
+        <sortsuitemodules unsortedmodules="${modules}" sortedmodulesproperty="modules.sorted"/>
+        <property name="cluster" location="build/cluster"/>
+        <echo level="verbose">Suite in ${basedir} with clusters ${cluster.path.final}, build cluster ${cluster}, and sorted modules ${modules.sorted}</echo>
+        <!-- synchronize with SuiteProject -->
+        <property name="disabled.modules" value=""/>
+        <property name="enabled.clusters" value=""/>
+        <property name="disabled.clusters" value=""/>
+        <property name="app.version" value="0.1"/>
+        <property name="branding.dir" location="branding"/>
+        <property name="dist.dir" location="dist"/>
+        <!-- MOVE THE .DLL FILES TO THE NETBEANS DIRECTORY -->
+
+        <condition property="run.branding"> <!-- #84689 -->
+            <and>
+                <available file="${branding.dir}" type="dir"/>
+                <isset property="branding.token"/>
+            </and>
+        </condition>
+    </target>
+
+    <target name="jni" depends="build,findTSK">
+        <javah verbose="yes" outputFile="${env.TSK_HOME}/bindings/java/tsk_jni/tsk_jni/dataModel_SleuthkitJNI.h">
+            <class name="org.sleuthkit.datamodel.SleuthkitJNI" />
+            <classpath  refid="jni-path"/>
+        </javah>
+    </target>
+    
+    <target name="javadoc" depends="-init,-hide-excluded-modules">
+        <subant target="javadoc" buildpath="${modules.sorted}" inheritrefs="false" inheritall="false" />
+    </target>
+</project>
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..253a284f004cc23292fa9e3bd64187762180d23d
--- /dev/null
+++ b/nbproject/build-impl.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="Autopsy3-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/platform-private.properties"/>
+    <property file="nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
+    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
+    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly.">
+        <condition>
+            <not>
+                <available type="dir" file="${harness.dir}"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/suite.xml"/>
+</project>
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..542aedb4ccf02a17a7c4800e3b6ae2642aafcf1b
--- /dev/null
+++ b/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=2e7964b0
+build.xml.script.CRC32=f6b177dc
+build.xml.stylesheet.CRC32=eaf9f76a@1.42.2
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=2e7964b0
+nbproject/build-impl.xml.script.CRC32=14b0b78d
+nbproject/build-impl.xml.stylesheet.CRC32=183e6ef3@1.42.2
diff --git a/nbproject/platform.properties b/nbproject/platform.properties
new file mode 100644
index 0000000000000000000000000000000000000000..38ecd5a92ebea2c14710d0595bdd2d6df0bafcf4
--- /dev/null
+++ b/nbproject/platform.properties
@@ -0,0 +1,99 @@
+cluster.path=\
+    ${nbplatform.active.dir}/java:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    org.apache.tools.ant.module,\
+    org.netbeans.api.debugger.jpda,\
+    org.netbeans.api.java,\
+    org.netbeans.libs.cglib,\
+    org.netbeans.libs.javacapi,\
+    org.netbeans.libs.javacimpl,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.springframework,\
+    org.netbeans.modules.ant.browsetask,\
+    org.netbeans.modules.ant.debugger,\
+    org.netbeans.modules.ant.freeform,\
+    org.netbeans.modules.ant.grammar,\
+    org.netbeans.modules.ant.kit,\
+    org.netbeans.modules.beans,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.dbschema,\
+    org.netbeans.modules.debugger.jpda,\
+    org.netbeans.modules.debugger.jpda.ant,\
+    org.netbeans.modules.debugger.jpda.projects,\
+    org.netbeans.modules.debugger.jpda.ui,\
+    org.netbeans.modules.form,\
+    org.netbeans.modules.form.j2ee,\
+    org.netbeans.modules.form.kit,\
+    org.netbeans.modules.hibernate,\
+    org.netbeans.modules.hibernatelib,\
+    org.netbeans.modules.hudson.ant,\
+    org.netbeans.modules.hudson.maven,\
+    org.netbeans.modules.i18n,\
+    org.netbeans.modules.i18n.form,\
+    org.netbeans.modules.j2ee.core.utilities,\
+    org.netbeans.modules.j2ee.eclipselink,\
+    org.netbeans.modules.j2ee.eclipselinkmodelgen,\
+    org.netbeans.modules.j2ee.jpa.refactoring,\
+    org.netbeans.modules.j2ee.jpa.verification,\
+    org.netbeans.modules.j2ee.metadata,\
+    org.netbeans.modules.j2ee.metadata.model.support,\
+    org.netbeans.modules.j2ee.persistence,\
+    org.netbeans.modules.j2ee.persistence.kit,\
+    org.netbeans.modules.j2ee.persistenceapi,\
+    org.netbeans.modules.j2ee.toplinklib,\
+    org.netbeans.modules.java.api.common,\
+    org.netbeans.modules.java.debug,\
+    org.netbeans.modules.java.editor,\
+    org.netbeans.modules.java.editor.lib,\
+    org.netbeans.modules.java.examples,\
+    org.netbeans.modules.java.freeform,\
+    org.netbeans.modules.java.guards,\
+    org.netbeans.modules.java.helpset,\
+    org.netbeans.modules.java.hints,\
+    org.netbeans.modules.java.hints.processor,\
+    org.netbeans.modules.java.j2seplatform,\
+    org.netbeans.modules.java.j2seproject,\
+    org.netbeans.modules.java.kit,\
+    org.netbeans.modules.java.lexer,\
+    org.netbeans.modules.java.navigation,\
+    org.netbeans.modules.java.platform,\
+    org.netbeans.modules.java.preprocessorbridge,\
+    org.netbeans.modules.java.project,\
+    org.netbeans.modules.java.source,\
+    org.netbeans.modules.java.source.ant,\
+    org.netbeans.modules.java.sourceui,\
+    org.netbeans.modules.javadoc,\
+    org.netbeans.modules.javawebstart,\
+    org.netbeans.modules.jellytools,\
+    org.netbeans.modules.jellytools.java,\
+    org.netbeans.modules.junit,\
+    org.netbeans.modules.maven,\
+    org.netbeans.modules.maven.coverage,\
+    org.netbeans.modules.maven.embedder,\
+    org.netbeans.modules.maven.grammar,\
+    org.netbeans.modules.maven.graph,\
+    org.netbeans.modules.maven.hints,\
+    org.netbeans.modules.maven.indexer,\
+    org.netbeans.modules.maven.junit,\
+    org.netbeans.modules.maven.kit,\
+    org.netbeans.modules.maven.model,\
+    org.netbeans.modules.maven.osgi,\
+    org.netbeans.modules.maven.persistence,\
+    org.netbeans.modules.maven.repository,\
+    org.netbeans.modules.maven.search,\
+    org.netbeans.modules.maven.spring,\
+    org.netbeans.modules.projectimport.eclipse.core,\
+    org.netbeans.modules.projectimport.eclipse.j2se,\
+    org.netbeans.modules.refactoring.java,\
+    org.netbeans.modules.spellchecker.bindings.java,\
+    org.netbeans.modules.spring.beans,\
+    org.netbeans.modules.swingapp,\
+    org.netbeans.modules.websvc.jaxws21,\
+    org.netbeans.modules.websvc.jaxws21api,\
+    org.netbeans.modules.websvc.saas.codegen.java,\
+    org.netbeans.modules.xml.jaxb,\
+    org.netbeans.modules.xml.tools.java,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+nbplatform.active=default
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..1cf62685478023649bd11c15dfd378e21898f43e
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,28 @@
+app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
+app.name=autopsy
+app.title=Autopsy
+app.version=3.0.0b1
+auxiliary.org-netbeans-modules-apisupport-installer.license-type=apache.v2
+auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
+auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=false
+auxiliary.org-netbeans-modules-apisupport-installer.os-solaris=false
+auxiliary.org-netbeans-modules-apisupport-installer.os-windows=true
+auxiliary.org-netbeans-modules-apisupport-installer.pack200-enabled=false
+branding.token=${app.name}
+modules=\
+    ${project.org.sleuthkit.autopsy.directorytree}:\
+    ${project.org.sleuthkit.autopsy.menuactions}:\
+    ${project.org.sleuthkit.autopsy.corecomponentinterfaces}:\
+    ${project.org.sleuthkit.autopsy.corecomponents}:\
+    ${project.org.sleuthkit.autopsy.filesearch}:\
+    ${project.org.sleuthkit.autopsy.datamodel}:\
+    ${project.org.sleuthkit.autopsy.logging}:\
+    ${project.org.sleuthkit.autopsy.casemodule}
+project.org.sleuthkit.autopsy.casemodule=Case
+project.org.sleuthkit.autopsy.corecomponentinterfaces=CoreComponentInterfaces
+project.org.sleuthkit.autopsy.corecomponents=CoreComponents
+project.org.sleuthkit.autopsy.directorytree=DirectoryTree
+project.org.sleuthkit.autopsy.filesearch=FileSearch
+project.org.sleuthkit.autopsy.logging=Logging
+project.org.sleuthkit.autopsy.menuactions=MenuActions
+project.org.sleuthkit.autopsy.datamodel=DataModel
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d93a72bfcc554ce0b9bc5ef4c02ff19ad415f206
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project.suite</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
+            <name>Autopsy3</name>
+        </data>
+    </configuration>
+</project>