Autopsy  4.7.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
org.sleuthkit.autopsy.casemodule.services.FileManager Class Reference

Inherits Closeable.

Classes

interface  FileAddProgressUpdater
 

Public Member Functions

 FileManager (SleuthkitCase caseDb)
 
synchronized LayoutFile addCarvedFile (String fileName, long fileSize, long parentObjId, List< TskFileRange > layout) throws TskCoreException
 
synchronized List< LayoutFile > addCarvedFiles (CarvingResult carvingResult) throws TskCoreException
 
synchronized List< LayoutFile > addCarvedFiles (List< org.sleuthkit.datamodel.CarvedFileContainer > filesToAdd) throws TskCoreException
 
synchronized DerivedFile addDerivedFile (String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, Content parentObj, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType) throws TskCoreException
 
synchronized DerivedFile addDerivedFile (String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, AbstractFile parentFile, String rederiveDetails, String toolName, String toolVersion, String otherDetails) throws TskCoreException
 
synchronized LocalFilesDataSource addLocalFilesDataSource (String deviceId, String rootVirtualDirectoryName, String timeZone, List< String > localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException, TskDataException
 
synchronized VirtualDirectory addLocalFilesDirs (List< String > localFilePaths, FileAddProgressUpdater progressUpdater) throws TskCoreException
 
synchronized void close () throws IOException
 
synchronized List< AbstractFile > findFiles (String fileName) throws TskCoreException
 
synchronized List< AbstractFile > findFiles (String fileName, String parentSubString) throws TskCoreException
 
synchronized List< AbstractFile > findFiles (String fileName, AbstractFile parent) throws TskCoreException
 
synchronized List< AbstractFile > findFiles (Content dataSource, String fileName) throws TskCoreException
 
synchronized List< AbstractFile > findFiles (Content dataSource, String fileName, String parentSubString) throws TskCoreException
 
synchronized List< AbstractFile > findFiles (Content dataSource, String fileName, AbstractFile parent) throws TskCoreException
 
synchronized List< AbstractFile > findFilesByMimeType (Collection< String > mimeTypes) throws TskCoreException
 
synchronized List< AbstractFile > findFilesByMimeType (Content dataSource, Collection< String > mimeTypes) throws TskCoreException
 
synchronized List< AbstractFile > findFilesByParentPath (long dataSourceObjectID, String parentPath) throws TskCoreException
 
synchronized List< AbstractFile > openFiles (Content dataSource, String filePath) throws TskCoreException
 
synchronized DerivedFile updateDerivedFile (DerivedFile derivedFile, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, String mimeType, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType) throws TskCoreException
 

Private Member Functions

AbstractFile addLocalFile (CaseDbTransaction trans, SpecialDirectory parentDirectory, java.io.File localFile, TskData.EncodingType encodingType, FileAddProgressUpdater progressUpdater) throws TskCoreException
 
AbstractFile addLocalFile (CaseDbTransaction trans, SpecialDirectory parentDirectory, java.io.File localFile, FileAddProgressUpdater progressUpdater) throws TskCoreException
 
List< java.io.File > getFilesAndDirectories (List< String > localFilePaths) throws TskDataException
 

Static Private Member Functions

static String createFileTypeInCondition (Collection< String > mimeTypes)
 
static String createParentPathCondition (long dataSourceObjectID, String parentPath)
 
static synchronized String generateFilesDataSourceName (SleuthkitCase caseDb) throws TskCoreException
 

Private Attributes

SleuthkitCase caseDb
 

Static Private Attributes

static final Logger LOGGER = Logger.getLogger(FileManager.class.getName())
 

Detailed Description

A manager that provides methods for retrieving files from the current case and for adding local files, carved files, and derived files to the current case.

Definition at line 58 of file FileManager.java.

Constructor & Destructor Documentation

org.sleuthkit.autopsy.casemodule.services.FileManager.FileManager ( SleuthkitCase  caseDb)

Constructs a manager that provides methods for retrieving files from the current case and for adding local files, carved files, and derived files to the current case.

Parameters
caseDbThe case database.

Definition at line 70 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.caseDb.

Member Function Documentation

synchronized LayoutFile org.sleuthkit.autopsy.casemodule.services.FileManager.addCarvedFile ( String  fileName,
long  fileSize,
long  parentObjId,
List< TskFileRange >  layout 
) throws TskCoreException

Adds a carved file to the '$CarvedFiles' virtual directory of a data source, volume or file system.

Parameters
fileNameThe name of the file.
fileSizeThe size of the file.
parentObjIdThe object id of the parent data source, volume or file system.
layoutA list of the offsets and sizes that gives the layout of the file within its parent.
Returns
A LayoutFile object representing the carved file.
Exceptions
TskCoreExceptionif there is a problem adding the file to the case database.
Deprecated:
Use List<LayoutFile> addCarvedFiles(CarvingResult carvingResult instead.

Definition at line 672 of file FileManager.java.

synchronized List<LayoutFile> org.sleuthkit.autopsy.casemodule.services.FileManager.addCarvedFiles ( CarvingResult  carvingResult) throws TskCoreException

Adds a carving result to the case database.

Parameters
carvingResultThe carving result (a set of carved files and their parent) to be added.
Returns
A list of LayoutFile representations of the carved files.
Exceptions
TskCoreExceptionIf there is a problem completing a case database operation.

Definition at line 418 of file FileManager.java.

synchronized List<LayoutFile> org.sleuthkit.autopsy.casemodule.services.FileManager.addCarvedFiles ( List< org.sleuthkit.datamodel.CarvedFileContainer >  filesToAdd) throws TskCoreException

Adds a collection of carved files to the '$CarvedFiles' virtual directory of a data source, volume or file system.

Parameters
filesToAddA collection of CarvedFileContainer objects, one per carved file, all of which must have the same parent object id.
Returns
A collection of LayoutFile object representing the carved files.
Exceptions
TskCoreExceptionif there is a problem adding the files to the case database.
Deprecated:
Use List<LayoutFile> addCarvedFiles(CarvingResult carvingResult instead.

Definition at line 699 of file FileManager.java.

synchronized DerivedFile org.sleuthkit.autopsy.casemodule.services.FileManager.addDerivedFile ( String  fileName,
String  localPath,
long  size,
long  ctime,
long  crtime,
long  atime,
long  mtime,
boolean  isFile,
Content  parentObj,
String  rederiveDetails,
String  toolName,
String  toolVersion,
String  otherDetails,
TskData.EncodingType  encodingType 
) throws TskCoreException

Adds a derived file to the case.

Parameters
fileNameThe name of the file.
localPathThe local path of the file, relative to the case folder and including the file name.
sizeThe size of the file in bytes.
ctimeThe change time of the file.
crtimeThe create time of the file
atimeThe accessed time of the file.
mtimeThe modified time of the file.
isFileTrue if a file, false if a directory.
parentObjThe parent object from which the file was derived.
rederiveDetailsThe details needed to re-derive file (will be specific to the derivation method), currently unused.
toolNameThe name of the derivation method or tool, currently unused.
toolVersionThe version of the derivation method or tool, currently unused.
otherDetailsOther details of the derivation method or tool, currently unused.
encodingTypeType of encoding used on the file
Returns
A DerivedFile object representing the derived file.
Exceptions
TskCoreExceptionif there is a problem adding the file to the case database.

Definition at line 348 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.addDerivedFile(), org.sleuthkit.autopsy.thunderbirdparser.ThunderbirdMboxFileIngestModule.handleAttachments(), and org.sleuthkit.autopsy.modules.embeddedfileextractor.SevenZipExtractor.UnpackedTree.updateOrAddFileToCaseRec().

synchronized DerivedFile org.sleuthkit.autopsy.casemodule.services.FileManager.addDerivedFile ( String  fileName,
String  localPath,
long  size,
long  ctime,
long  crtime,
long  atime,
long  mtime,
boolean  isFile,
AbstractFile  parentFile,
String  rederiveDetails,
String  toolName,
String  toolVersion,
String  otherDetails 
) throws TskCoreException

Adds a derived file to the case.

Parameters
fileNameThe name of the file.
localPathThe local path of the file, relative to the case folder and including the file name.
sizeThe size of the file in bytes.
ctimeThe change time of the file.
crtimeThe create time of the file
atimeThe accessed time of the file.
mtimeThe modified time of the file.
isFileTrue if a file, false if a directory.
parentFileThe parent file from which the file was derived.
rederiveDetailsThe details needed to re-derive file (will be specific to the derivation method), currently unused.
toolNameThe name of the derivation method or tool, currently unused.
toolVersionThe version of the derivation method or tool, currently unused.
otherDetailsOther details of the derivation method or tool, currently unused.
Returns
A DerivedFile object representing the derived file.
Exceptions
TskCoreExceptionif there is a problem adding the file to the case database.
Deprecated:
Use the version with explicit EncodingType instead

Definition at line 737 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.addDerivedFile().

AbstractFile org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFile ( CaseDbTransaction  trans,
SpecialDirectory  parentDirectory,
java.io.File  localFile,
TskData.EncodingType  encodingType,
FileAddProgressUpdater  progressUpdater 
) throws TskCoreException
private

Adds a file or directory of logical/local files data source to the case database, recursively adding the contents of directories.

Parameters
transA case database transaction.
parentDirectoryThe root virtual directory of the data source or the parent local directory.
localFileThe local/logical file or directory.
encodingTypeType of encoding used when storing the file
progressUpdaterCalled after each file/directory is added to the case database.
Returns
An AbstractFile representation of the local/logical file.
Exceptions
TskCoreExceptionIf there is a problem completing a database operation.

Definition at line 586 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFile(), and org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDataSource().

AbstractFile org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFile ( CaseDbTransaction  trans,
SpecialDirectory  parentDirectory,
java.io.File  localFile,
FileAddProgressUpdater  progressUpdater 
) throws TskCoreException
private

Adds a file or directory of logical/local files data source to the case database, recursively adding the contents of directories.

Parameters
transA case database transaction.
parentDirectoryThe root virtual directory of the data source or the parent local directory.
localFileThe local/logical file or directory.
progressUpdaternotifier to receive progress notifications on folders added, or null if not used
progressUpdaterCalled after each file/directory is added to the case database.
Returns
An AbstractFile representation of the local/logical file.
Exceptions
TskCoreExceptionIf there is a problem completing a database operation.
Deprecated:
Use the version with explicit EncodingType instead

Definition at line 769 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFile().

synchronized LocalFilesDataSource org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDataSource ( String  deviceId,
String  rootVirtualDirectoryName,
String  timeZone,
List< String >  localFilePaths,
FileAddProgressUpdater  progressUpdater 
) throws TskCoreException, TskDataException

Adds a set of local/logical files and/or directories to the case database as data source.

Parameters
deviceIdAn ASCII-printable identifier for the device associated with the data source that is intended to be unique across multiple cases (e.g., a UUID).
rootVirtualDirectoryNameThe name to give to the virtual directory that will serve as the root for the local/logical files and/or directories that compose the data source. Pass the empty string to get a default name of the form: LogicalFileSet[N]
timeZoneThe time zone used to process the data source, may be the empty string.
localFilePathsA list of local/logical file and/or directory localFilePaths.
progressUpdaterCalled after each file/directory is added to the case database.
Returns
A local files data source object.
Exceptions
TskCoreExceptionIf there is a problem completing a database operation.
TskDataExceptionif any of the local file paths is for a file or directory that does not exist or cannot be read.

Definition at line 467 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFile(), org.sleuthkit.autopsy.ingest.IngestServices.fireModuleContentEvent(), org.sleuthkit.autopsy.casemodule.services.FileManager.generateFilesDataSourceName(), org.sleuthkit.autopsy.casemodule.services.FileManager.getFilesAndDirectories(), and org.sleuthkit.autopsy.ingest.IngestServices.getInstance().

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDirs().

synchronized VirtualDirectory org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDirs ( List< String >  localFilePaths,
FileAddProgressUpdater  progressUpdater 
) throws TskCoreException

Adds a set of local/logical files and/or directories to the case database as data source.

Parameters
localFilePathsA list of local/logical file and/or directory localFilePaths.
progressUpdaterCalled after each file/directory is added to the case database.
Returns
The root virtual directory for the local/logical files data source.
Exceptions
TskCoreExceptionIf any of the local file paths is for a file or directory that does not exist or cannot be read, or there is a problem completing a database operation.
Deprecated:
Use addLocalFilesDataSource instead.

Definition at line 642 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDataSource().

synchronized void org.sleuthkit.autopsy.casemodule.services.FileManager.close ( ) throws IOException

Closes the file manager.

Exceptions
IOExceptionIf there is a problem closing the file manager.

Definition at line 619 of file FileManager.java.

static String org.sleuthkit.autopsy.casemodule.services.FileManager.createFileTypeInCondition ( Collection< String >  mimeTypes)
staticprivate

Converts a list of MIME types into an SQL "mime_type IN" condition.

Parameters
mimeTypesThe MIIME types.
Returns
The condition string.

Definition at line 135 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.findFilesByMimeType().

static String org.sleuthkit.autopsy.casemodule.services.FileManager.createParentPathCondition ( long  dataSourceObjectID,
String  parentPath 
)
staticprivate

Converts a data source object id and a parent path into SQL data_source_obj_id = ? AND parent_path LIKE ?%

Parameters
dataSourceObjectID
parentPath
Returns

Definition at line 148 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.findFilesByParentPath().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( String  fileName) throws TskCoreException

Finds all files and directories with a given file name. The name search is for full or partial matches and is case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
fileNameThe full name or a pattern to match on part of the name
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 165 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( String  fileName,
String  parentSubString 
) throws TskCoreException

Finds all files and directories with a given file name and parent file or directory name. The name searches are for full or partial matches and are case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
fileNameThe full name or a pattern to match on part of the name
parentSubStringSubstring that must exist in parent path. Will be surrounded by % in LIKE query.
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 191 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( String  fileName,
AbstractFile  parent 
) throws TskCoreException

Finds all files and directories with a given file name and parent file or directory. The name search is for full or partial matches and is case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
fileNameThe full name or a pattern to match on part of the name
parentThe parent file or directory.
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 217 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( Content  dataSource,
String  fileName 
) throws TskCoreException

Finds all files and directories with a given file name in a given data source (image, local/logical files set, etc.). The name search is for full or partial matches and is case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
dataSourceThe data source.
fileNameThe full name or a pattern to match on part of the name
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 243 of file FileManager.java.

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( Content  dataSource,
String  fileName,
String  parentSubString 
) throws TskCoreException

Finds all files and directories with a given file name and parent file or directory name in a given data source (image, local/logical files set, etc.). The name searches are for full or partial matches and are case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
dataSourceThe data source.
fileNameThe full name or a pattern to match on part of the name
parentSubStringSubstring that must exist in parent path. Will be surrounded by % in LIKE query.
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 266 of file FileManager.java.

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles ( Content  dataSource,
String  fileName,
AbstractFile  parent 
) throws TskCoreException

Finds all files and directories with a given file name and given parent file or directory in a given data source (image, local/logical files set, etc.). The name search is for full or partial matches and is case insensitive (a case insensitive SQL LIKE clause is used to query the case database).

Parameters
dataSourceThe data source.
fileNameThe full name or a pattern to match on part of the name
parentThe parent file or directory.
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 289 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.findFiles().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFilesByMimeType ( Collection< String >  mimeTypes) throws TskCoreException

Finds all files with types that match one of a collection of MIME types.

Parameters
mimeTypesThe MIME types.
Returns
The files.
Exceptions
TskCoreExceptionIf there is a problem querying the case database.

Definition at line 84 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.createFileTypeInCondition().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFilesByMimeType ( Content  dataSource,
Collection< String >  mimeTypes 
) throws TskCoreException

Finds all files in a given data source (image, local/logical files set, etc.) with types that match one of a collection of MIME types.

Parameters
dataSourceThe data source.
mimeTypesThe MIME types.
Returns
The files.
Exceptions
TskCoreExceptionIf there is a problem querying the case database.

Definition at line 121 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.createFileTypeInCondition().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.findFilesByParentPath ( long  dataSourceObjectID,
String  parentPath 
) throws TskCoreException

Finds all parent_paths that match the specified parentPath and are in the specified data source.

Parameters
dataSourceObjectID- the id of the data source to get files from
parentPath- the parent path that all files should be like
Returns
The list of files
Exceptions
TskCoreExceptionIf there is a problem querying the case database.

Definition at line 102 of file FileManager.java.

References org.sleuthkit.autopsy.casemodule.services.FileManager.createParentPathCondition().

static synchronized String org.sleuthkit.autopsy.casemodule.services.FileManager.generateFilesDataSourceName ( SleuthkitCase  caseDb) throws TskCoreException
staticprivate

Generates a name for the root virtual directory for the data source.

NOTE: Although this method is guarded by the file manager's monitor, there is currently a minimal chance of default name duplication for multi-user cases with multiple FileManagers running on different nodes.

Returns
A default name for a local/logical files data source of the form: LogicalFileSet[N].
Exceptions
TskCoreExceptionIf there is a problem querying the case database.

Definition at line 530 of file FileManager.java.

References org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode.LOGICAL_FILE_SET_PREFIX.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDataSource().

List<java.io.File> org.sleuthkit.autopsy.casemodule.services.FileManager.getFilesAndDirectories ( List< String >  localFilePaths) throws TskDataException
private

Converts a list of local/logical file and/or directory paths to a list of file objects.

Parameters
localFilePathsA list of local/logical file and/or directory paths.
Returns
A list of file objects.
Exceptions
TskDataExceptionif any of the paths is for a file or directory that does not exist or cannot be read.

Definition at line 557 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.casemodule.services.FileManager.addLocalFilesDataSource().

synchronized List<AbstractFile> org.sleuthkit.autopsy.casemodule.services.FileManager.openFiles ( Content  dataSource,
String  filePath 
) throws TskCoreException

Finds all files and directories with a given file name and path in a given data source (image, local/logical files set, etc.). The name search is for full or partial matches and is case insensitive (a case insensitive SQL LIKE clause is used to query the case database). Any path components at the volume level and above are removed for the search.

Parameters
dataSourceThe data source.
filePathThe file path (path components volume at the volume level or above will be removed).
Returns
The matching files and directories.
Exceptions
TskCoreExceptionif there is a problem querying the case database.

Definition at line 312 of file FileManager.java.

synchronized DerivedFile org.sleuthkit.autopsy.casemodule.services.FileManager.updateDerivedFile ( DerivedFile  derivedFile,
String  localPath,
long  size,
long  ctime,
long  crtime,
long  atime,
long  mtime,
boolean  isFile,
String  mimeType,
String  rederiveDetails,
String  toolName,
String  toolVersion,
String  otherDetails,
TskData.EncodingType  encodingType 
) throws TskCoreException

Update a derived file which already exists in the the case.

Parameters
derivedFileThe derived file you wish to update
localPathThe local path of the file, relative to the case folder and including the file name.
sizeThe size of the file in bytes.
ctimeThe change time of the file.
crtimeThe create time of the file
atimeThe accessed time of the file.
mimeTypeThe MIME type the updated file should have, null to unset it
mtimeThe modified time of the file.
isFileTrue if a file, false if a directory.
rederiveDetailsThe details needed to re-derive file (will be specific to the derivation method), currently unused.
toolNameThe name of the derivation method or tool, currently unused.
toolVersionThe version of the derivation method or tool, currently unused.
otherDetailsOther details of the derivation method or tool, currently unused.
encodingTypeType of encoding used on the file
Returns
A DerivedFile object representing the derived file.
Exceptions
TskCoreExceptionif there is a problem adding the file to the case database.

Definition at line 393 of file FileManager.java.

Referenced by org.sleuthkit.autopsy.modules.embeddedfileextractor.SevenZipExtractor.UnpackedTree.updateOrAddFileToCaseRec().

Member Data Documentation

SleuthkitCase org.sleuthkit.autopsy.casemodule.services.FileManager.caseDb
private
final Logger org.sleuthkit.autopsy.casemodule.services.FileManager.LOGGER = Logger.getLogger(FileManager.class.getName())
staticprivate

Definition at line 60 of file FileManager.java.


The documentation for this class was generated from the following file:

Copyright © 2012-2016 Basis Technology. Generated on: Mon Jun 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.