diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index a55cb7e02cf936674893f81f40efe4d712333c77..9cdbb08f9e920ee90a6697d79dc70d04b85f519e 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -2,7 +2,8 @@ file.reference.jdom-2.0.5-contrib.jar=release/modules/ext/jdom-2.0.5-contrib.jar
 file.reference.jdom-2.0.5.jar=release/modules/ext/jdom-2.0.5.jar
 file.reference.jython-standalone-2.7.0.jar=release/modules/ext/jython-standalone-2.7.0.jar
 file.reference.jython.jar-1=release/modules/ext/jython.jar
-file.reference.metadata-extractor-2.6.2.jar=release/modules/ext/metadata-extractor-2.6.2.jar
+file.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1.jar
+file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar
 file.reference.Rejistry-1.0-SNAPSHOT.jar=release/modules/ext/Rejistry-1.0-SNAPSHOT.jar
 file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
 file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
@@ -10,12 +11,13 @@ file.reference.sqlite-jdbc-3.8.11.jar=release/modules/ext/sqlite-jdbc-3.8.11.jar
 file.reference.StixLib.jar=release/modules/ext/StixLib.jar
 file.reference.tika-core-1.2.jar=release/modules/ext/tika-core-1.2.jar
 file.reference.Tsk_DataModel.jar=release/modules/ext/Tsk_DataModel.jar
-file.reference.xmpcore.jar=release/modules/ext/xmpcore.jar
+file.reference.xmpcore-5.1.2.jar=release/modules/ext/xmpcore-5.1.2.jar
 javac.source=1.8
 javac.compilerargs=-Xlint -Xlint:-serial
 license.file=../LICENSE-2.0.txt
 nbm.homepage=http://www.sleuthkit.org/
 nbm.module.author=Brian Carrier
 nbm.needs.restart=true
+source.reference.metadata-extractor-2.8.1.jar=release/modules/ext/metadata-extractor-2.8.1-src.zip!/Source/
 spec.version.base=10.3
 
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index 440fdaa0bcaff716188fc2ad4334cd511e514b67..c8089bda6c2af8aac582c310fa5026a163c41667 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -204,49 +204,49 @@
                 <package>org.sleuthkit.datamodel</package>
             </public-packages>
             <class-path-extension>
-                <runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/jdom-2.0.5.jar</binary-origin>
-            </class-path-extension>
-            <class-path-extension>
-                <runtime-relative-path>ext/Rejistry-1.0-SNAPSHOT.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/Rejistry-1.0-SNAPSHOT.jar</binary-origin>
-            </class-path-extension>
-            <class-path-extension>
-                <runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
+                <runtime-relative-path>ext/xmpcore-5.1.2.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/xmpcore-5.1.2.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/jython-standalone-2.7.0.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/jython-standalone-2.7.0.jar</binary-origin>
+                <runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/jdom-2.0.5.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/StixLib.jar</runtime-relative-path>
                 <binary-origin>release/modules/ext/StixLib.jar</binary-origin>
             </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/sqlite-jdbc-3.8.11.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/sqlite-jdbc-3.8.11.jar</binary-origin>
+            </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/opencv-248.jar</runtime-relative-path>
                 <binary-origin>release/modules/ext/opencv-248.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/sqlite-jdbc-3.8.11.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/sqlite-jdbc-3.8.11.jar</binary-origin>
+                <runtime-relative-path>ext/Rejistry-1.0-SNAPSHOT.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/Rejistry-1.0-SNAPSHOT.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
+                <runtime-relative-path>ext/sevenzipjbinding.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/metadata-extractor-2.6.2.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/metadata-extractor-2.6.2.jar</binary-origin>
+                <runtime-relative-path>ext/jython-standalone-2.7.0.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/jython-standalone-2.7.0.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/xmpcore.jar</runtime-relative-path>
-                <binary-origin>release/modules/ext/xmpcore.jar</binary-origin>
+                <runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/sevenzipjbinding-AllPlatforms.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/tika-core-1.2.jar</runtime-relative-path>
                 <binary-origin>release/modules/ext/tika-core-1.2.jar</binary-origin>
             </class-path-extension>
+            <class-path-extension>
+                <runtime-relative-path>ext/metadata-extractor-2.8.1.jar</runtime-relative-path>
+                <binary-origin>release/modules/ext/metadata-extractor-2.8.1.jar</binary-origin>
+            </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/jdom-2.0.5-contrib.jar</runtime-relative-path>
                 <binary-origin>release/modules/ext/jdom-2.0.5-contrib.jar</binary-origin>
diff --git a/Core/release/modules/ext/metadata-extractor-2.6.2.jar b/Core/release/modules/ext/metadata-extractor-2.6.2.jar
deleted file mode 100755
index 68426ac059d9cb48aa219b02e660581cb9c27c2b..0000000000000000000000000000000000000000
Binary files a/Core/release/modules/ext/metadata-extractor-2.6.2.jar and /dev/null differ
diff --git a/Core/release/modules/ext/metadata-extractor-2.8.1.jar b/Core/release/modules/ext/metadata-extractor-2.8.1.jar
new file mode 100755
index 0000000000000000000000000000000000000000..a5fe48640b6dc350e77ac550c1da92b68e56c4e8
Binary files /dev/null and b/Core/release/modules/ext/metadata-extractor-2.8.1.jar differ
diff --git a/Core/release/modules/ext/xmpcore-5.1.2.jar b/Core/release/modules/ext/xmpcore-5.1.2.jar
new file mode 100755
index 0000000000000000000000000000000000000000..ecd5db142e70fed769c5a3634b11b60f7767ef0e
Binary files /dev/null and b/Core/release/modules/ext/xmpcore-5.1.2.jar differ
diff --git a/Core/release/modules/ext/xmpcore.jar b/Core/release/modules/ext/xmpcore.jar
deleted file mode 100755
index 884c2dd57ff888b46097a6fe00aba08741d94a3f..0000000000000000000000000000000000000000
Binary files a/Core/release/modules/ext/xmpcore.jar and /dev/null differ
diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/ExifParserFileIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/exif/ExifParserFileIngestModule.java
index 7c186e93b4187524842da9ae60d131299643f854..deb55fa2abccec8500bc9f6ce72c2e7791eaef57 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/exif/ExifParserFileIngestModule.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/exif/ExifParserFileIngestModule.java
@@ -22,10 +22,21 @@
 import com.drew.imaging.ImageProcessingException;
 import com.drew.lang.GeoLocation;
 import com.drew.lang.Rational;
+import com.drew.metadata.Directory;
 import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.exif.makernotes.CanonMakernoteDirectory;
 import com.drew.metadata.exif.ExifIFD0Directory;
 import com.drew.metadata.exif.ExifSubIFDDirectory;
 import com.drew.metadata.exif.GpsDirectory;
+import com.drew.metadata.exif.makernotes.CasioType1MakernoteDirectory;
+import com.drew.metadata.exif.makernotes.FujifilmMakernoteDirectory;
+import com.drew.metadata.exif.makernotes.KodakMakernoteDirectory;
+import com.drew.metadata.exif.makernotes.NikonType2MakernoteDirectory;
+import com.drew.metadata.exif.makernotes.PanasonicMakernoteDirectory;
+import com.drew.metadata.exif.makernotes.PentaxMakernoteDirectory;
+import com.drew.metadata.exif.makernotes.SanyoMakernoteDirectory;
+import com.drew.metadata.exif.makernotes.SonyType1MakernoteDirectory;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -33,6 +44,8 @@
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
+import java.util.List;
+import java.util.TimeZone;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import org.openide.util.NbBundle;
@@ -47,6 +60,8 @@
 import org.sleuthkit.datamodel.BlackboardArtifact;
 import org.sleuthkit.datamodel.BlackboardAttribute;
 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
+import org.sleuthkit.datamodel.Content;
+import org.sleuthkit.datamodel.Image;
 import org.sleuthkit.datamodel.ReadContentInputStream;
 import org.sleuthkit.datamodel.TskCoreException;
 import org.sleuthkit.datamodel.TskData;
@@ -63,10 +78,13 @@ public final class ExifParserFileIngestModule implements FileIngestModule {
     private final IngestServices services = IngestServices.getInstance();
     private final AtomicInteger filesProcessed = new AtomicInteger(0);
     private volatile boolean filesToFire = false;
+    private volatile boolean facesDetected = false;
+    private final List<BlackboardArtifact> listOfFacesDetectedArtifacts = new ArrayList<>();
     private long jobId;
     private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
     private FileTypeDetector fileTypeDetector;
     private final HashSet<String> supportedMimeTypes = new HashSet<>();
+    private TimeZone timeZone = null;
 
     ExifParserFileIngestModule() {
         supportedMimeTypes.add("audio/x-wav");
@@ -103,9 +121,16 @@ public ProcessResult process(AbstractFile content) {
 
         // update the tree every 1000 files if we have EXIF data that is not being being displayed 
         final int filesProcessedValue = filesProcessed.incrementAndGet();
-        if ((filesToFire) && (filesProcessedValue % 1000 == 0)) {
-            services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF));
-            filesToFire = false;
+        if ((filesProcessedValue % 1000 == 0)) {
+            if (filesToFire) {
+                services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF));
+                filesToFire = false;
+            }
+            if (facesDetected) {
+                services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED, listOfFacesDetectedArtifacts));
+                listOfFacesDetectedArtifacts.clear();
+                facesDetected = false;
+            }
         }
 
         //skip unsupported
@@ -125,19 +150,32 @@ ProcessResult processFile(AbstractFile f) {
             bin = new BufferedInputStream(in);
 
             Collection<BlackboardAttribute> attributes = new ArrayList<>();
-            Metadata metadata = ImageMetadataReader.readMetadata(bin, true);
+            Metadata metadata = ImageMetadataReader.readMetadata(bin);
 
             // Date
-            ExifSubIFDDirectory exifDir = metadata.getDirectory(ExifSubIFDDirectory.class);
+            ExifSubIFDDirectory exifDir = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
             if (exifDir != null) {
-                Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
+
+                // set the timeZone for the current datasource.
+                if (timeZone == null) {
+                    try {
+                        Content dataSource = f.getDataSource();
+                        if ((dataSource != null) && (dataSource instanceof Image)) {
+                            Image image = (Image) dataSource;
+                            timeZone = TimeZone.getTimeZone(image.getTimeZone());
+                        }
+                    } catch (TskCoreException ex) {
+                        logger.log(Level.INFO, "Error getting time zones", ex); //NON-NLS
+                    }
+                }
+                Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL, timeZone);
                 if (date != null) {
                     attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(), ExifParserModuleFactory.getModuleName(), date.getTime() / 1000));
                 }
             }
 
             // GPS Stuff
-            GpsDirectory gpsDir = metadata.getDirectory(GpsDirectory.class);
+            GpsDirectory gpsDir = metadata.getFirstDirectoryOfType(GpsDirectory.class);
             if (gpsDir != null) {
                 GeoLocation loc = gpsDir.getGeoLocation();
                 if (loc != null) {
@@ -147,14 +185,14 @@ ProcessResult processFile(AbstractFile f) {
                     attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), longitude));
                 }
 
-                Rational altitude = gpsDir.getRational(GpsDirectory.TAG_GPS_ALTITUDE);
+                Rational altitude = gpsDir.getRational(GpsDirectory.TAG_ALTITUDE);
                 if (altitude != null) {
                     attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), altitude.doubleValue()));
                 }
             }
 
             // Device info
-            ExifIFD0Directory devDir = metadata.getDirectory(ExifIFD0Directory.class);
+            ExifIFD0Directory devDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
             if (devDir != null) {
                 String model = devDir.getString(ExifIFD0Directory.TAG_MODEL);
                 if (model != null && !model.isEmpty()) {
@@ -167,6 +205,11 @@ ProcessResult processFile(AbstractFile f) {
                 }
             }
 
+            if (containsFace(metadata)) {
+                listOfFacesDetectedArtifacts.add(f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED));
+                facesDetected = true;
+            }
+
             // Add the attributes, if there are any, to a new artifact
             if (!attributes.isEmpty()) {
                 BlackboardArtifact bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
@@ -199,6 +242,121 @@ ProcessResult processFile(AbstractFile f) {
         }
     }
 
+    /**
+     * Checks if this metadata contains any tags related to facial information.
+     * NOTE: Cases with this metadata containing tags like enabled red-eye
+     * reduction settings, portrait settings, etc are also assumed to contain
+     * facial information. The method returns true. The return value of this
+     * method does NOT guarantee actual presence of face.
+     *
+     * @param metadata the metadata which needs to be parsed for possible facial
+     *                 information.
+     *
+     * @return returns true if the metadata contains any tags related to facial
+     *         information.
+     */
+    private boolean containsFace(Metadata metadata) {
+        Directory d = metadata.getFirstDirectoryOfType(CanonMakernoteDirectory.class);
+        if (d != null) {
+            if (d.containsTag(CanonMakernoteDirectory.TAG_FACE_DETECT_ARRAY_1)
+                    && d.getString(CanonMakernoteDirectory.TAG_FACE_DETECT_ARRAY_1) != null) {
+                return true;
+            }
+            if (d.containsTag(CanonMakernoteDirectory.TAG_FACE_DETECT_ARRAY_2)
+                    && d.getString(CanonMakernoteDirectory.TAG_FACE_DETECT_ARRAY_2) != null) {
+                return true;
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(CasioType1MakernoteDirectory.class);
+        if (d != null) {
+            try {
+                if (d.containsTag(CasioType1MakernoteDirectory.TAG_FLASH_MODE)
+                        && d.getInt(CasioType1MakernoteDirectory.TAG_FLASH_MODE) == 0x04) { //0x04 = "Red eye reduction"
+                    return true;
+                }
+            } catch (MetadataException ex) {
+                // move on and check next directory
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(FujifilmMakernoteDirectory.class);
+        if (d != null) {
+            if (d.containsTag(FujifilmMakernoteDirectory.TAG_FACES_DETECTED)
+                    && d.getString(FujifilmMakernoteDirectory.TAG_FACES_DETECTED) != null) {
+                return true;
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(KodakMakernoteDirectory.class);
+        if (d != null) {
+            try {
+                if (d.containsTag(KodakMakernoteDirectory.TAG_FLASH_MODE)
+                        && d.getInt(KodakMakernoteDirectory.TAG_FLASH_MODE) == 0x03) { //0x03 = "Red Eye"
+                    return true;
+                }
+            } catch (MetadataException ex) {
+                /// move on and check next directory
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(NikonType2MakernoteDirectory.class);
+        if (d != null) {
+            if (d.containsTag(NikonType2MakernoteDirectory.TAG_SCENE_MODE)
+                    && d.getString(NikonType2MakernoteDirectory.TAG_SCENE_MODE) != null
+                    && (d.getString(NikonType2MakernoteDirectory.TAG_SCENE_MODE).equals("BEST FACE") // NON-NLS
+                    || (d.getString(NikonType2MakernoteDirectory.TAG_SCENE_MODE).equals("SMILE")))) { // NON-NLS
+                return true;
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(PanasonicMakernoteDirectory.class);
+        if (d != null) {
+            if (d.containsTag(PanasonicMakernoteDirectory.TAG_FACES_DETECTED)
+                    && d.getString(PanasonicMakernoteDirectory.TAG_FACES_DETECTED) != null) {
+                return true;
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(PentaxMakernoteDirectory.class);
+        if (d != null) {
+            try {
+                if (d.containsTag(PentaxMakernoteDirectory.TAG_FLASH_MODE)
+                        && d.getInt(PentaxMakernoteDirectory.TAG_FLASH_MODE) == 6) { // 6 = Red-eye Reduction
+                    return true;
+                }
+            } catch (MetadataException ex) {
+                // move on and check next directory
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(SanyoMakernoteDirectory.class);
+        if (d != null) {
+            if (d.containsTag(SanyoMakernoteDirectory.TAG_MANUAL_FOCUS_DISTANCE_OR_FACE_INFO)
+                    && d.getString(SanyoMakernoteDirectory.TAG_MANUAL_FOCUS_DISTANCE_OR_FACE_INFO) != null) {
+                return true;
+            }
+        }
+
+        d = metadata.getFirstDirectoryOfType(SonyType1MakernoteDirectory.class);
+        if (d != null) {
+            try {
+                if (d.containsTag(SonyType1MakernoteDirectory.TAG_AF_MODE)
+                        && d.getInt(SonyType1MakernoteDirectory.TAG_AF_MODE) == 15) { //15 = "Face Detected"
+                    return true;
+                }
+                if (d.containsTag(SonyType1MakernoteDirectory.TAG_EXPOSURE_MODE)
+                        && d.getInt(SonyType1MakernoteDirectory.TAG_EXPOSURE_MODE) == 14) { //14 = "Smile shutter"
+                    return true;
+                }
+            } catch (MetadataException ex) {
+                // move on and check next directory
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Checks if should try to attempt to extract exif. Currently checks if JPEG
      * image (by signature)
@@ -225,10 +383,15 @@ private boolean parsableFormat(AbstractFile f) {
     public void shutDown() {
         // We only need to check for this final event on the last module per job
         if (refCounter.decrementAndGet(jobId) == 0) {
+            timeZone = null;
             if (filesToFire) {
                 //send the final new data event
                 services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF));
             }
+            if (facesDetected) {
+                //send the final new data event
+                services.fireModuleDataEvent(new ModuleDataEvent(ExifParserModuleFactory.getModuleName(), BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED, listOfFacesDetectedArtifacts));
+            }
         }
     }
 }