diff --git a/test/test_imagewrapper.py b/test/test_imagewrapper.py
index d84c19eda4f33c0f4822dbdbdf60a44c1183d49f..c0bdb5e3fb9c0927ac804e0837e8aecc7bac8f3c 100644
--- a/test/test_imagewrapper.py
+++ b/test/test_imagewrapper.py
@@ -24,18 +24,19 @@ def teardown_module():
     pass
 
 
-def random_coverage(shape):
+def random_coverage(shape, vol_limit=None):
     
     ndims = len(shape) - 1
     nvols = shape[-1]
 
-    print '{}D (shape: {}, {} vectors/slices/volumes)'.format(ndims, shape, nvols)
+    print '{}D (shape: {}, {} vectors/slices/volumes)'.format(
+        ndims, shape, nvols)
 
     # Generate a random coverage. 
     # We use the same coverage for
     # each vector/slice/volume, so
     # are not fully testing the function.
-    coverage = np.zeros((2, ndims, nvols), dtype=np.uint32)
+    coverage = np.zeros((2, ndims, nvols), dtype=np.float32)
 
     for dim in range(ndims):
         dsize = shape[dim]
@@ -51,6 +52,9 @@ def random_coverage(shape):
 
         coverage[0, dim, :] = low
         coverage[1, dim, :] = high
+
+    if vol_limit is not None:
+        coverage[:, :, vol_limit:] = np.nan
  
     return coverage
 
@@ -139,6 +143,75 @@ def random_slices(coverage, shape, mode):
     return slices
 
 
+def rfloat(lo, hi):
+    return lo + np.random.random() * (hi - lo)
+
+def applyCoverage(wrapper, coverage):
+
+    ndims = coverage.shape[1]
+
+    wrapper.reset()
+    # 'Apply' that coverage to the image
+    # wrapper by accessing the data in it
+
+    sliceobjs = []
+    for dim in range(ndims):
+        sliceobjs.append(slice(coverage[0, dim, 0], coverage[1, dim, 0], 1))
+    sliceobjs.append(0)
+
+    wrapper[tuple(sliceobjs)]
+
+    # Check that the image wrapper
+    # has covered what we just told
+    # it to cover, for this volume
+    wcov = wrapper.coverage(0)
+
+    for dim in range(ndims):
+        assert coverage[0, dim, 0] == wcov[0, dim]
+        assert coverage[1, dim, 0] == wcov[1, dim]
+
+
+def coverageDataRange(data, coverage, slices):
+
+    # Assuming that adjustCoverage is working.
+    ndims = coverage.shape[1]
+    nvols = coverage.shape[2]
+
+    origcoverage = coverage
+
+    if slices is not None:
+        
+        coverage = np.copy(coverage)
+
+        lowVol, highVol = slices[-1]
+
+        for vol in range(lowVol, highVol):
+            coverage[..., vol] = imagewrap.adjustCoverage(
+                coverage[..., vol], slices[:ndims])
+
+    volmin = []
+    volmax = []
+
+    for vol in range(nvols):
+
+        cov = coverage[..., vol]
+
+        if np.any(np.isnan(cov)):
+            continue
+        
+        sliceobj = []
+
+        for d in range(ndims):
+            sliceobj.append(slice(cov[0, d], cov[1, d], 1))
+        sliceobj.append(vol)
+
+        voldata = data[tuple(sliceobj)]
+        volmin.append(voldata.min())
+        volmax.append(voldata.max())
+
+    return np.min(volmin), np.max(volmax)
+
+
 def test_sliceObjToSliceTuple():
 
     func  = imagewrap.sliceObjToSliceTuple
@@ -193,10 +266,10 @@ def test_adjustCoverage():
         assert np.all(imagewrap.adjustCoverage(coverage, expansion) == result)
 
 
-def test_sliceOverlap():
+def test_sliceOverlap(niters=150):
 
     # A bunch of random coverages
-    for i in range(150):
+    for i in range(niters):
 
         # 2D, 3D or 4D?
         # ndims is the number of dimensions
@@ -213,27 +286,27 @@ def test_sliceOverlap():
 
         # Generate some slices that should
         # be contained within the coverage
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'in')
             assert imagewrap.sliceOverlap(slices, coverage) == imagewrap.OVERLAP_ALL
 
         # Generate some slices that should
         # overlap with the coverage 
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'overlap')
             assert imagewrap.sliceOverlap(slices, coverage) == imagewrap.OVERLAP_SOME
 
         # Generate some slices that should
         # be outside of the coverage 
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'out')
             assert imagewrap.sliceOverlap(slices, coverage)  == imagewrap.OVERLAP_NONE
 
         
-def test_sliceCovered():
+def test_sliceCovered(niters=150):
 
     # A bunch of random coverages
-    for i in range(150):
+    for i in range(niters):
 
         # 2D, 3D or 4D?
         # ndims is the number of dimensions
@@ -250,19 +323,19 @@ def test_sliceCovered():
 
         # Generate some slices that should
         # be contained within the coverage
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'in')
             assert imagewrap.sliceCovered(slices, coverage)
 
         # Generate some slices that should
         # overlap with the coverage 
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'overlap')
             assert not imagewrap.sliceCovered(slices, coverage)
 
         # Generate some slices that should
         # be outside of the coverage 
-        for j in range(150):
+        for j in range(niters):
             slices = random_slices(coverage, shape, 'out')
             assert not imagewrap.sliceCovered(slices, coverage) 
 
@@ -304,7 +377,9 @@ def _test_expansion(coverage, slices, volumes, expansions):
     # Bin the expansions by volume
     expsByVol = collections.defaultdict(list)
     for vol, exp in zip(volumes, expansions):
-        print '  {:3d}:    "{}"'.format(vol, " ".join(["{:2d} {:2d}".format(l, h) for l, h in exp]))
+        print '  {:3d}:    "{}"'.format(
+            int(vol),
+            " ".join(["{:2d} {:2d}".format(int(l), int(h)) for l, h in exp]))
         expsByVol[vol].append(exp)
         
     for point in points:
@@ -343,9 +418,9 @@ def _test_expansion(coverage, slices, volumes, expansions):
             raise AssertionError(point)
 
             
-def test_calcExpansionNoCoverage():
+def test_calcExpansionNoCoverage(niters=150):
 
-    for i in range(150):
+    for i in range(niters):
         ndims       = random.choice((2, 3, 4)) - 1
         shape       = np.random.randint(5, 100, size=ndims + 1)
         shape[-1]   = np.random.randint(1, 8)
@@ -354,15 +429,15 @@ def test_calcExpansionNoCoverage():
 
         print
         print '-- Out --' 
-        for j in range(150):
+        for j in range(niters):
             slices     = random_slices(coverage, shape, 'out')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
                 
-def test_calcExpansion():
+def test_calcExpansion(niters=150):
 
-    for i in range(150):
+    for i in range(niters):
 
         ndims     = random.choice((2, 3, 4)) - 1
         shape     = np.random.randint(5, 60, size=ndims + 1)
@@ -376,7 +451,7 @@ def test_calcExpansion():
 
         print
         print '-- In --'
-        for j in range(150):
+        for j in range(niters):
             slices     = random_slices(coverage, shape, 'in')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
 
@@ -386,23 +461,22 @@ def test_calcExpansion():
             
         print
         print '-- Overlap --' 
-        for j in range(150):
+        for j in range(niters):
             slices     = random_slices(coverage, shape, 'overlap')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
         print
         print '-- Out --' 
-        for j in range(150):
+        for j in range(niters):
             slices     = random_slices(coverage, shape, 'out')
             vols, exps = imagewrap.calcExpansion(slices, coverage)
             _test_expansion(coverage, slices, vols, exps)
 
 
-def test_ImageWrapper_read():
-
+def test_ImageWrapper_read(niters=150):
 
-    for i in range(150):
+    for i in range(niters):
 
         # Generate an image with a number of volumes
         ndims     = random.choice((2, 3, 4)) - 1
@@ -430,7 +504,7 @@ def test_ImageWrapper_read():
         # through the image wrapper with a
         # bunch of random volume orderings.
 
-        for i in range(150):
+        for i in range(niters):
 
             ordering = list(range(nvols))
             random.shuffle(ordering)
@@ -456,3 +530,267 @@ def test_ImageWrapper_read():
 
                 if j < nvols - 1: assert not wrapper.covered
                 else:             assert     wrapper.covered
+
+                
+def test_ImageWrapper_write_out(niters=150):
+    # This is HORRIBLE
+
+    # Generate an image with just two volumes. We're only
+    # testing within-volume modifications here.
+    ndims     = random.choice((2, 3, 4)) - 1
+    shape     = np.random.randint(5, 60, size=ndims + 1)
+    shape[-1] = np.random.randint(2, 3)
+    nvols     = shape[-1]
+
+    data = np.zeros(shape)
+
+    # The data range of each volume
+    # increases sequentially
+    data[..., 0] = np.random.randint(-5, 6, shape[:-1])
+    for i in range(1, nvols):
+        data[..., i] = data[..., 0] * (i + 1)
+ 
+    # Generate a bunch of random coverages
+    for i in range(niters):
+
+        # Generate a random coverage
+        cov = random_coverage(shape, vol_limit=1)
+
+        print 'This is the coverage: {}'.format(cov)
+
+        img     = nib.Nifti1Image(data, np.eye(4))
+        wrapper = imagewrap.ImageWrapper(img)
+        applyCoverage(wrapper, cov)
+        clo, chi = wrapper.dataRange
+
+        # Now, we'll simulate some writes
+        # outside of the coverage area.
+        for i in range(niters):
+
+            # Generate some slices outside
+            # of the coverage area, making
+            # sure that the slice covers
+            # at least two elements
+            while True:
+                slices     = random_slices(cov, shape, 'out')
+                slices[-1] = [0, 1]
+                sliceshape = [hi - lo for lo, hi in slices]
+
+                if np.prod(sliceshape) == 1:
+                    continue
+
+                sliceobjs = imagewrap.sliceTupleToSliceObj(slices)
+                sliceobjs  = tuple(list(sliceobjs[:-1]) + [0])
+                sliceshape = sliceshape[:-1]
+                break
+
+            print '---------------'
+            print 'Slice {}'.format(slices)
+
+            # Expected wrapper coverage after the write
+            expCov = imagewrap.adjustCoverage(cov[..., 0], slices)
+
+            # Figure out the data range of the
+            # expanded coverage (the original
+            # coverage expanded to include this
+            # slice).
+            elo, ehi = coverageDataRange(data, cov, slices)
+
+            # Test all data range possibilities:
+            #  - inside the existing range       (clo < rlo < rhi < chi)
+            #  - encompassing the existing range (rlo < clo < chi < rhi)
+            #  - Overlapping the existing range  (rlo < clo < rhi < chi)
+            #                                    (clo < rlo < chi < rhi)
+            #  - Outside of the existing range   (clo < chi < rlo < rhi)
+            #                                    (rlo < rhi < clo < chi)
+            loRanges = [rfloat(clo,         chi), 
+                        rfloat(elo - 100,   elo), 
+                        rfloat(elo - 100,   elo), 
+                        rfloat(clo,         chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(elo - 100,   elo)] 
+
+            hiRanges = [rfloat(loRanges[0], chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(clo,         chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(loRanges[4], ehi + 100), 
+                        rfloat(loRanges[5], elo)]
+            
+            for rlo, rhi in zip(loRanges, hiRanges):
+
+                img     = nib.Nifti1Image(np.copy(data), np.eye(4))
+                wrapper = imagewrap.ImageWrapper(img)
+                applyCoverage(wrapper, cov)
+
+                print 'ndims', ndims
+                print 'sliceshape', sliceshape
+                print 'sliceobjs', sliceobjs
+
+                newData = np.linspace(rlo, rhi, np.prod(sliceshape))
+                newData = newData.reshape(sliceshape)
+
+                # Make sure that the expected low/high values
+                # are present in the data being written
+
+                print 'Writing data (shape: {})'.format(newData.shape)
+
+                oldCov = wrapper.coverage(0)
+
+                wrapper[tuple(sliceobjs)] = newData
+
+                expLo, expHi = coverageDataRange(img.get_data(), cov, slices)
+                newLo, newHi = wrapper.dataRange
+
+                print 'Old    range: {} - {}'.format(clo,   chi)
+                print 'Sim    range: {} - {}'.format(rlo,   rhi)
+                print 'Exp    range: {} - {}'.format(expLo, expHi)
+                print 'NewDat range: {} - {}'.format(newData.min(), newData.max())
+                print 'Data   range: {} - {}'.format(data.min(),   data.max())
+                print 'Expand range: {} - {}'.format(elo, ehi)
+                print 'New    range: {} - {}'.format(newLo, newHi)
+
+                newCov = wrapper.coverage(0)
+                print 'Old coverage:      {}'.format(oldCov)
+                print 'New coverage:      {}'.format(newCov)
+                print 'Expected coverage: {}'.format(expCov)
+                print
+                print
+
+                assert np.all(newCov == expCov)
+
+                assert np.isclose(newLo, expLo)
+                assert np.isclose(newHi, expHi)
+            print '--------------'
+
+
+                
+def best_ImageWrapper_write_in_overlap():
+
+    # Generate an image with only two volumes. We're only
+    # testing within-volume modifications here.
+    ndims     = random.choice((2, 3, 4)) - 1
+    shape     = np.random.randint(5, 60, size=ndims + 1)
+    shape[-1] = np.random.randint(2, 3)
+    nvols     = shape[-1]
+
+    data = np.zeros(shape)
+
+    # The data range of each volume
+    # increases sequentially
+    data[..., 0] = np.random.randint(-5, 6, shape[:-1])
+    for i in range(1, nvols):
+        data[..., i] = data[..., 0] * (i + 1)
+ 
+    # Generate a bunch of random coverages
+    for i in range(1):
+
+        # Generate a random coverage
+        cov = random_coverage(shape, vol_limit=1)
+
+        print 'This is the coverage: {}'.format(cov)
+
+        img     = nib.Nifti1Image(data, np.eye(4))
+        wrapper = imagewrap.ImageWrapper(img)
+        applyCoverage(wrapper, cov)
+        clo, chi = wrapper.dataRange
+
+        # Now, we'll simulate some writes
+        # outside of the coverage area.
+        for i in range(5):
+
+            # Generate some slices inside/overlapping
+            # with the coverage area, making sure that
+            # the slice covers at least two elements
+            while True:
+                slices     = random_slices(cov, shape, np.random.choice(('in', 'overlap')))
+                slices[-1] = [0, 1]
+                sliceshape = [hi - lo for lo, hi in slices]
+
+                if np.prod(sliceshape) == 1:
+                    continue
+
+                sliceobjs = imagewrap.sliceTupleToSliceObj(slices)
+                sliceobjs  = tuple(list(sliceobjs[:-1]) + [0])
+                sliceshape = sliceshape[:-1]
+                break
+
+            print '---------------'
+            print 'Slice {}'.format(slices)
+
+            # Expected wrapper coverage after the write
+            expCov = imagewrap.adjustCoverage(cov[..., 0], slices)
+
+            # Figure out the data range of the
+            # expanded coverage (the original
+            # coverage expanded to include this
+            # slice).
+            elo, ehi = coverageDataRange(data, cov, slices)
+
+            # Test all data range possibilities:
+            #  - inside the existing range       (clo < rlo < rhi < chi)
+            #  - encompassing the existing range (rlo < clo < chi < rhi)
+            #  - Overlapping the existing range  (rlo < clo < rhi < chi)
+            #                                    (clo < rlo < chi < rhi)
+            #  - Outside of the existing range   (clo < chi < rlo < rhi)
+            #                                    (rlo < rhi < clo < chi)
+            loRanges = [rfloat(clo,         chi), 
+                        rfloat(elo - 100,   elo), 
+                        rfloat(elo - 100,   elo), 
+                        rfloat(clo,         chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(elo - 100,   elo)] 
+
+            hiRanges = [rfloat(loRanges[0], chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(clo,         chi), 
+                        rfloat(ehi,         ehi + 100), 
+                        rfloat(loRanges[4], ehi + 100), 
+                        rfloat(loRanges[5], elo)]
+            
+            for rlo, rhi in zip(loRanges, hiRanges):
+
+                img     = nib.Nifti1Image(np.copy(data), np.eye(4))
+                wrapper = imagewrap.ImageWrapper(img)
+                applyCoverage(wrapper, cov)
+
+                print 'ndims', ndims
+                print 'sliceshape', sliceshape
+                print 'sliceobjs', sliceobjs
+
+                newData = np.linspace(rlo, rhi, np.prod(sliceshape))
+                newData = newData.reshape(sliceshape)
+
+                # Make sure that the expected low/high values
+                # are present in the data being written
+
+                print 'Writing data (shape: {})'.format(newData.shape)
+
+                oldCov = wrapper.coverage(0)
+
+                wrapper[tuple(sliceobjs)] = newData
+
+                expLo, expHi = coverageDataRange(img.get_data(), cov, slices)
+                newLo, newHi = wrapper.dataRange
+
+                print 'Old    range: {} - {}'.format(clo,   chi)
+                print 'Sim    range: {} - {}'.format(rlo,   rhi)
+                print 'Exp    range: {} - {}'.format(expLo, expHi)
+                print 'NewDat range: {} - {}'.format(newData.min(), newData.max())
+                print 'Data   range: {} - {}'.format(data.min(),   data.max())
+                print 'Expand range: {} - {}'.format(elo, ehi)
+                print 'New    range: {} - {}'.format(newLo, newHi)
+
+                newCov = wrapper.coverage(0)
+                print 'Old coverage:      {}'.format(oldCov)
+                print 'New coverage:      {}'.format(newCov)
+                print 'Expected coverage: {}'.format(expCov)
+                print
+                print
+
+                assert np.all(newCov == expCov)
+
+                assert np.isclose(newLo, expLo)
+                assert np.isclose(newHi, expHi)
+
+            print '--------------'