diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index ddf56a5b72b4449b4079c1c63c8ebbb5f00f9d38..bdc60a5bc84f7cc3bc6e612de03c8727441c77ef 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -10,12 +10,26 @@ Added
 ^^^^^
 
 
+* New :func:`.cifti` module, providing classes and functions for working with
+  `CIFTI <https://www.nitrc.org/projects/cifti/>`_ data.
 * New :func:`.winpath` and :func:`wslpath` functions for working with paths
   when using FSL in a Windows Subsystem for Linux (WSL) environment.
 * New :func:`.wslcmd` function for generating a path to a FSL command installed
   in a WSL environment.
 * New :meth:`.Platform.fslwsl` attribute for detecting whether FSL is installed
   in a WSL environment.
+* New :meth:`.Image.niftiDataType` property.
+* The :class:`.FileTree` class has been updated to allow creation of
+  deep copies via the new :meth:`.FileTree.copy` method.
+
+
+Changed
+^^^^^^^
+
+
+* :func:`.Image` objects created from ``numpy`` arrays will be NIFTI1 or
+  NIFTI2, depending on the value of the ``$FSLOUTPUTTYPE`` environment
+  variable.
 
 
 Fixed
diff --git a/fsl/data/constants.py b/fsl/data/constants.py
index 5a870ccf03f5dd457fd39bd70137b9448891282f..00b60acb22f0e9fb71d4608f0a7d791d7d893dbd 100644
--- a/fsl/data/constants.py
+++ b/fsl/data/constants.py
@@ -98,6 +98,36 @@ NIFTI_UNITS_PPM     = 40
 NIFTI_UNITS_RADS    = 48
 
 
+# NIFTI datatype codes
+NIFTI_DT_NONE          = 0
+NIFTI_DT_UNKNOWN       = 0
+NIFTI_DT_BINARY        = 1
+NIFTI_DT_UNSIGNED_CHAR = 2
+NIFTI_DT_SIGNED_SHORT  = 4
+NIFTI_DT_SIGNED_INT    = 8
+NIFTI_DT_FLOAT         = 16
+NIFTI_DT_COMPLEX       = 32
+NIFTI_DT_DOUBLE        = 64
+NIFTI_DT_RGB           = 128
+NIFTI_DT_ALL           = 255
+NIFTI_DT_UINT8         = 2
+NIFTI_DT_INT16         = 4
+NIFTI_DT_INT32         = 8
+NIFTI_DT_FLOAT32       = 16
+NIFTI_DT_COMPLEX64     = 32
+NIFTI_DT_FLOAT64       = 64
+NIFTI_DT_RGB24         = 128
+NIFTI_DT_INT8          = 256
+NIFTI_DT_UINT16        = 512
+NIFTI_DT_UINT32        = 768
+NIFTI_DT_INT64         = 1024
+NIFTI_DT_UINT64        = 1280
+NIFTI_DT_FLOAT128      = 1536
+NIFTI_DT_COMPLEX128    = 1792
+NIFTI_DT_COMPLEX256    = 2048
+NIFTI_DT_RGBA32        = 2304
+
+
 # NIFTI file intent codes
 NIFTI_INTENT_NONE          = 0
 NIFTI_INTENT_CORREL        = 2
diff --git a/fsl/data/image.py b/fsl/data/image.py
index eb9c468cc50a9831833b50bbe3cd758576297e18..a12f39b12eec26064096a23dcc9365726588e3d2 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -39,7 +39,6 @@ import                      json
 import                      string
 import                      logging
 import                      tempfile
-import                      warnings
 
 import                      six
 import numpy             as np
@@ -560,6 +559,11 @@ class Nifti(notifier.Notifier, meta.Meta):
         """Returns the NIFTI intent code of this image. """
         return self.header.get('intent_code', constants.NIFTI_INTENT_NONE)
 
+    @property
+    def niftiDataType(self):
+        """Returns the NIFTI data type code of this image. """
+        return self.header.get('datatype', constants.NIFTI_DT_UNKNOWN)
+
 
     @intent.setter
     def intent(self, val):
@@ -1094,11 +1098,12 @@ class Image(Nifti):
                 if header is not None: xform = header.get_best_affine()
                 else:                  xform = np.identity(4)
 
-            # We default to NIFTI1 and not
-            # NIFTI2, because the rest of
-            # FSL is not yet NIFTI2 compatible.
+            # default to NIFTI1 if FSLOUTPUTTYPE
+            # is not set, just to be safe.
             if header is None:
-                ctr = nib.nifti1.Nifti1Image
+                outputType = os.environ.get('FSLOUTPUTTYPE', 'NIFTI_GZ')
+                if 'NIFTI2' in outputType: ctr = nib.Nifti2Image
+                else:                      ctr = nib.Nifti1Image
 
             # make sure that the data type is correct,
             # in case this header was passed in from
@@ -1643,9 +1648,14 @@ def defaultExt():
 
     # TODO: Add analyze support.
     options = {
-        'NIFTI'      : '.nii',
-        'NIFTI_PAIR' : '.img',
-        'NIFTI_GZ'   : '.nii.gz',
+        'NIFTI'          : '.nii',
+        'NIFTI2'         : '.nii',
+        'NIFTI_GZ'       : '.nii.gz',
+        'NIFTI2_GZ'      : '.nii.gz',
+        'NIFTI_PAIR'     : '.img',
+        'NIFTI2_PAIR'    : '.img',
+        'NIFTI_PAIR_GZ'  : '.img.gz',
+        'NIFTI2_PAIR_GZ' : '.img.gz',
     }
 
     outputType = os.environ.get('FSLOUTPUTTYPE', 'NIFTI_GZ')
diff --git a/tests/test_image.py b/tests/test_image.py
index 75ec686a9cdfba1d682d7b992fdd9820e1573512..b7de2def252e4f8bf4edcf672ebb773eafc38ee5 100644
--- a/tests/test_image.py
+++ b/tests/test_image.py
@@ -246,6 +246,11 @@ def _test_Image_atts(imgtype):
 
     allowedExts = fslimage.ALLOWED_EXTENSIONS
     fileGroups  = fslimage.FILE_GROUPS
+    typeMap     = {np.uint8   : constants.NIFTI_DT_UINT8,
+                   np.int16   : constants.NIFTI_DT_INT16,
+                   np.int32   : constants.NIFTI_DT_INT32,
+                   np.float32 : constants.NIFTI_DT_FLOAT32,
+                   np.float64 : constants.NIFTI_DT_FLOAT64}
 
     # (file, dims, pixdims, dtype)
     dtypes = [np.uint8, np.int16, np.int32, np.float32, np.double]
@@ -307,14 +312,15 @@ def _test_Image_atts(imgtype):
             assert tuple(i.nibImage.shape)              == tuple(dims)
             assert tuple(i.nibImage.header.get_zooms()) == tuple(pixdims)
 
-            assert i.nvals      == 1
-            assert i.ndim       == expndims
-            assert i.dtype      == dtype
-            assert i.name       == op.basename(path)
-            assert i.dataSource == fslpath.addExt(path,
-                                                  allowedExts=allowedExts,
-                                                  mustExist=True,
-                                                  fileGroups=fileGroups)
+            assert i.nvals         == 1
+            assert i.ndim          == expndims
+            assert i.dtype         == dtype
+            assert i.niftiDataType == typeMap[dtype]
+            assert i.name          == op.basename(path)
+            assert i.dataSource    == fslpath.addExt(path,
+                                                     allowedExts=allowedExts,
+                                                     mustExist=True,
+                                                     fileGroups=fileGroups)
             i = None
 
 
@@ -493,8 +499,9 @@ def test_splitExt():
 
 def test_defaultExt():
 
-    fslOutputTypes = ['NIFTI', 'NIFTI_PAIR', 'NIFTI_GZ']
-    exts           = ['.nii', '.img', '.nii.gz']
+    fslOutputTypes = ['NIFTI',  'NIFTI_PAIR',  'NIFTI_GZ',  'NIFTI_PAIR_GZ',
+                      'NIFTI2', 'NIFTI2_PAIR', 'NIFTI2_GZ', 'NIFTI2_PAIR_GZ']
+    exts           = ['.nii', '.img', '.nii.gz', '.img.gz'] * 2
 
     os.environ.pop('FSLOUTPUTTYPE', None)
     assert fslimage.defaultExt() == '.nii.gz'
@@ -506,6 +513,35 @@ def test_defaultExt():
         assert fslimage.defaultExt() == e
 
 
+def test_defaultImageType():
+
+    fslOutputTypes = [None,
+                      'NIFTI',  'NIFTI_PAIR',  'NIFTI_GZ',  'NIFTI_PAIR_GZ',
+                      'NIFTI2', 'NIFTI2_PAIR', 'NIFTI2_GZ', 'NIFTI2_PAIR_GZ']
+    exts           = ['.nii.gz'] + \
+                     ['.nii', '.img', '.nii.gz', '.img.gz'] * 2
+
+    with tempdir():
+        for o, e in zip(fslOutputTypes, exts):
+
+            if o is None:
+                os.environ.pop('FSLOUTPUTTYPE', None)
+            else:
+                os.environ['FSLOUTPUTTYPE'] = o
+
+            if o is None or 'NIFTI2' not in o:
+                exptype = nib.Nifti1Image
+            else:
+                exptype = nib.Nifti2Image
+
+            img = fslimage.Image(np.random.randint(1, 10, (30, 30, 30)))
+
+            assert type(img.nibImage) == exptype
+
+            img.save('image')
+            assert op.exists('image' + e)
+
+
 def test_fixExt():
     with tempdir():