From 0ce4534e7d4bf3f2474de543a36d7af692a4220c Mon Sep 17 00:00:00 2001
From: "Timothy M. Shead" <tshead@sandia.gov>
Date: Wed, 24 Mar 2010 10:55:28 -0400
Subject: [PATCH] ENH: Update the vtkArrayAPI to support distributed arrays /
 arrays with non-zero-based coordinate indices.

---
 Common/CMakeLists.txt                         |  11 +-
 Common/Testing/CMakeLists.txt                 |   3 +-
 Common/Testing/Cxx/ArrayAPIDense.cxx          |  23 ++--
 Common/Testing/Cxx/ArrayAPISparse.cxx         |  18 +--
 .../Cxx/{ArraySlice.cxx => ArrayExtents.cxx}  |  30 ++---
 .../Testing/Cxx/ArrayInterpolationDense.cxx   |   8 +-
 Common/Testing/Cxx/CMakeLists.txt             |   2 +-
 Common/vtkArray.cxx                           |  34 +++--
 Common/vtkArray.h                             |  18 +--
 Common/vtkArrayCoordinateIterator.h           |  93 --------------
 Common/vtkArrayExtents.cxx                    | 116 ++++++++++++++---
 Common/vtkArrayExtents.h                      |  99 ++++++++++++---
 ...rraySlices.cxx => vtkArrayExtentsList.cxx} |  24 ++--
 ...vtkArraySlices.h => vtkArrayExtentsList.h} |  34 ++---
 Common/vtkArrayInterpolate.h                  |   4 +-
 Common/vtkArrayInterpolate.txx                |  26 ++--
 Common/vtkArrayPrint.txx                      |  14 +-
 Common/vtkArrayRange.cxx                      |  13 +-
 Common/vtkArrayRange.h                        |  12 +-
 Common/vtkArraySlice.cxx                      | 118 -----------------
 Common/vtkArraySlice.h                        | 120 ------------------
 Common/vtkDenseArray.h                        |   7 +-
 Common/vtkDenseArray.txx                      |  22 ++--
 Common/vtkSparseArray.h                       |   2 +-
 Common/vtkSparseArray.txx                     |  27 ++--
 IO/Testing/Cxx/TestArraySerialization.cxx     |  13 +-
 IO/vtkArrayReader.cxx                         |  39 +++---
 IO/vtkArrayWriter.cxx                         |  12 +-
 Infovis/Testing/Cxx/ArrayMatricizeArray.cxx   |   6 +-
 Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx  |   4 +-
 Infovis/vtkAdjacencyMatrixToEdgeTable.cxx     |   8 +-
 Infovis/vtkArrayNorm.cxx                      |  10 +-
 Infovis/vtkArrayToTable.cxx                   |  22 ++--
 Infovis/vtkBoostRandomSparseArraySource.cxx   |  10 +-
 Infovis/vtkDotProductSimilarity.cxx           |  46 ++++---
 Infovis/vtkMatricizeArray.cxx                 |   8 +-
 Infovis/vtkNormalizeMatrixVectors.cxx         |  12 +-
 Infovis/vtkTransposeMatrix.cxx                |   6 +-
 .../Testing/Cxx/TestExtractSelectedSlices.cxx |   4 +-
 .../Testing/Cxx/TestMatrixWeighting.cxx       |   8 +-
 TextAnalysis/vtkConcatenateArray.cxx          |  11 +-
 TextAnalysis/vtkEntropyMatrixWeighting.cxx    |  18 +--
 TextAnalysis/vtkExtractSelectedSlices.cxx     |  22 ++--
 .../vtkPointwiseMutualInformation.cxx         |   4 +-
 TextAnalysis/vtkScaleDimension.cxx            |   9 +-
 TextAnalysis/vtkSelectArraySlices.cxx         |  16 +--
 TextAnalysis/vtkUnityMatrixWeighting.cxx      |   6 +-
 47 files changed, 502 insertions(+), 670 deletions(-)
 rename Common/Testing/Cxx/{ArraySlice.cxx => ArrayExtents.cxx} (73%)
 delete mode 100644 Common/vtkArrayCoordinateIterator.h
 rename Common/{vtkArraySlices.cxx => vtkArrayExtentsList.cxx} (61%)
 rename Common/{vtkArraySlices.h => vtkArrayExtentsList.h} (68%)
 delete mode 100644 Common/vtkArraySlice.cxx
 delete mode 100644 Common/vtkArraySlice.h

diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt
index 223dbb83627..2dc35e60137 100644
--- a/Common/CMakeLists.txt
+++ b/Common/CMakeLists.txt
@@ -410,12 +410,10 @@ IF(VTK_USE_N_WAY_ARRAYS)
   SET(Kit_SRCS
     ${Kit_SRCS}
     vtkArray.cxx
-    vtkArrayExtents.cxx
     vtkArrayCoordinates.cxx
-    vtkArrayCoordinateIterator.cxx
+    vtkArrayExtents.cxx
+    vtkArrayExtentsList.cxx
     vtkArrayRange.cxx
-    vtkArraySlice.cxx
-    vtkArraySlices.cxx
     vtkArraySort.cxx
     vtkArrayWeights.cxx
     )
@@ -426,11 +424,10 @@ IF(VTK_USE_N_WAY_ARRAYS)
     )
 
   SET_SOURCE_FILES_PROPERTIES(
-    vtkArrayExtents.cxx
     vtkArrayCoordinates.cxx
+    vtkArrayExtents.cxx
+    vtkArrayExtentsList.cxx
     vtkArrayRange.cxx
-    vtkArraySlice.cxx
-    vtkArraySlices.cxx
     vtkArraySort.cxx
     vtkArrayWeights.cxx
     WRAP_EXCLUDE
diff --git a/Common/Testing/CMakeLists.txt b/Common/Testing/CMakeLists.txt
index ba4e5df1a84..33fc34c4ee1 100644
--- a/Common/Testing/CMakeLists.txt
+++ b/Common/Testing/CMakeLists.txt
@@ -21,6 +21,7 @@ IF(PYTHON_EXECUTABLE)
     vtkArrayCoordinateIterator.h
     vtkArrayCoordinates.h
     vtkArrayExtents.h
+    vtkArrayExtentsList.h
     vtkArrayInterpolate.h
     vtkArrayIteratorIncludes.h
     vtkArrayIteratorTemplate.h
@@ -28,8 +29,6 @@ IF(PYTHON_EXECUTABLE)
     vtkArrayMapIterator.h
     vtkArrayPrint.h
     vtkArrayRange.h
-    vtkArraySlice.h
-    vtkArraySlices.h
     vtkArraySort.h
     vtkArrayWeights.h
     vtkAssemblyPaths.h
diff --git a/Common/Testing/Cxx/ArrayAPIDense.cxx b/Common/Testing/Cxx/ArrayAPIDense.cxx
index 878ee8bda41..1761e349300 100644
--- a/Common/Testing/Cxx/ArrayAPIDense.cxx
+++ b/Common/Testing/Cxx/ArrayAPIDense.cxx
@@ -60,6 +60,7 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
 
     // Resize the array and verify that everything adds-up ...
     array->Resize(vtkArrayExtents(1, 2, 3));
+    array->Print(std::cout);
     test_expression(array->GetDimensions() == 3);
     test_expression(array->GetSize() == 6);
     test_expression(array->GetNonNullSize() == 6);
@@ -69,11 +70,11 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     {
     array->Fill(0.0);
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(vtkIdType i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(vtkIdType j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(vtkIdType k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           test_expression(array->GetValue(vtkArrayCoordinates(i, j, k)) == 0.0);
           }
@@ -85,11 +86,11 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     {
     double value = 0;
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(vtkIdType i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(vtkIdType j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(vtkIdType k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           array->SetValue(vtkArrayCoordinates(i, j, k), value++);
           }
@@ -101,11 +102,11 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     double value = 0;
     vtkIdType index = 0;
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(vtkIdType i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(vtkIdType j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(vtkIdType k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           test_expression(array->GetValue(vtkArrayCoordinates(i, j, k)) == value);
 
@@ -123,7 +124,7 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     array->Fill(19700827);
 
     // Test unordered access ...
-    for(int n = 0; n != array->GetNonNullSize(); ++n)
+    for(vtkIdType n = 0; n != array->GetNonNullSize(); ++n)
       test_expression(array->GetValueN(n) == 19700827);
    
     // Verify that deep-copy works correctly ...
@@ -133,7 +134,7 @@ int ArrayAPIDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     test_expression(deep_copy->GetSize() == array->GetSize());
     test_expression(deep_copy->GetNonNullSize() == array->GetNonNullSize());
     test_expression(deep_copy->GetExtents() == array->GetExtents());
-    for(int n = 0; n != deep_copy->GetNonNullSize(); ++n)
+    for(vtkIdType n = 0; n != deep_copy->GetNonNullSize(); ++n)
       test_expression(deep_copy->GetValueN(n) == 19700827);
 
     // Verify that data is organized in fortran-order ...
diff --git a/Common/Testing/Cxx/ArrayAPISparse.cxx b/Common/Testing/Cxx/ArrayAPISparse.cxx
index 152278b4be7..6e815a98a13 100644
--- a/Common/Testing/Cxx/ArrayAPISparse.cxx
+++ b/Common/Testing/Cxx/ArrayAPISparse.cxx
@@ -63,11 +63,11 @@ int ArrayAPISparse(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     // Verify that the array contains all zeros ...
     {
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(int i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(int j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(int k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           test_expression(array->GetValue(vtkArrayCoordinates(i, j, k)) == 0);
           }
@@ -79,11 +79,11 @@ int ArrayAPISparse(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     {
     double value = 0;
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(int i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(int j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(int k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           array->AddValue(vtkArrayCoordinates(i, j, k), value++);
           }
@@ -95,11 +95,11 @@ int ArrayAPISparse(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     double value = 0;
     vtkIdType index = 0;
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(int i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(int j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(int k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           test_expression(array->GetValue(vtkArrayCoordinates(i, j, k)) == value);
           test_expression(array->GetValueN(index) == value);
diff --git a/Common/Testing/Cxx/ArraySlice.cxx b/Common/Testing/Cxx/ArrayExtents.cxx
similarity index 73%
rename from Common/Testing/Cxx/ArraySlice.cxx
rename to Common/Testing/Cxx/ArrayExtents.cxx
index 47045e56338..7cf0f5b80a4 100644
--- a/Common/Testing/Cxx/ArraySlice.cxx
+++ b/Common/Testing/Cxx/ArrayExtents.cxx
@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Program:   Visualization Toolkit
-  Module:    ArraySlice.cxx
+  Module:    ArrayExtents.cxx
   
 -------------------------------------------------------------------------
   Copyright 2008 Sandia Corporation.
@@ -20,7 +20,7 @@
 =========================================================================*/
 
 #include <vtkArrayCoordinates.h>
-#include <vtkArraySlice.h>
+#include <vtkArrayExtents.h>
 
 #include <vtksys/ios/iostream>
 #include <vtksys/ios/sstream>
@@ -37,35 +37,35 @@
     } \
 }
 
-int ArraySlice(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
+int ArrayExtents(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
 {
   try
     {
-    vtkArraySlice slice(vtkArrayRange(2, 4), vtkArrayRange(6, 9));
+    vtkArrayExtents slice(vtkArrayRange(2, 4), vtkArrayRange(6, 9));
 
     test_expression(slice.GetDimensions() == 2);
-    test_expression(slice.GetExtents()[0] == 2);
-    test_expression(slice.GetExtents()[1] == 3);
-    test_expression(slice.GetExtents().GetSize() == 6);
+    test_expression(slice[0].GetSize() == 2);
+    test_expression(slice[1].GetSize() == 3);
+    test_expression(slice.GetSize() == 6);
 
     vtkArrayCoordinates coordinates;
-    for(vtkIdType n = 0; n != slice.GetExtents().GetSize(); ++n)
+    for(vtkIdType n = 0; n != slice.GetSize(); ++n)
       {
-      slice.GetCoordinatesN(n, coordinates);
+      slice.GetLeftToRightCoordinatesN(n, coordinates);
       cerr << coordinates << endl;
       }
 
-    slice.GetCoordinatesN(0, coordinates);
+    slice.GetLeftToRightCoordinatesN(0, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(2, 6));
-    slice.GetCoordinatesN(1, coordinates);
+    slice.GetLeftToRightCoordinatesN(1, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(3, 6));
-    slice.GetCoordinatesN(2, coordinates);
+    slice.GetLeftToRightCoordinatesN(2, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(2, 7));
-    slice.GetCoordinatesN(3, coordinates);
+    slice.GetLeftToRightCoordinatesN(3, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(3, 7));
-    slice.GetCoordinatesN(4, coordinates);
+    slice.GetLeftToRightCoordinatesN(4, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(2, 8));
-    slice.GetCoordinatesN(5, coordinates);
+    slice.GetLeftToRightCoordinatesN(5, coordinates);
     test_expression(coordinates == vtkArrayCoordinates(3, 8));
 
     test_expression(slice.Contains(vtkArrayCoordinates(3, 7)));
diff --git a/Common/Testing/Cxx/ArrayInterpolationDense.cxx b/Common/Testing/Cxx/ArrayInterpolationDense.cxx
index e086f5b4cf2..2eed262a9f1 100644
--- a/Common/Testing/Cxx/ArrayInterpolationDense.cxx
+++ b/Common/Testing/Cxx/ArrayInterpolationDense.cxx
@@ -46,8 +46,8 @@ int ArrayInterpolationDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     vtkSmartPointer<vtkDenseArray<double> > b = vtkSmartPointer<vtkDenseArray<double> >::New();
     b->Resize(vtkArrayExtents(2));
 
-    vtkInterpolate(a.GetPointer(), vtkArraySlices(vtkArraySlice(vtkArrayRange(0)), vtkArraySlice(vtkArrayRange(1))), vtkArrayWeights(0.5, 0.5), vtkArraySlice(vtkArrayRange(0)), b.GetPointer());
-    vtkInterpolate(a.GetPointer(), vtkArraySlices(vtkArraySlice(vtkArrayRange(2)), vtkArraySlice(vtkArrayRange(3))), vtkArrayWeights(0.5, 0.5), vtkArraySlice(vtkArrayRange(1)), b.GetPointer());
+    vtkInterpolate(a.GetPointer(), vtkArrayExtentsList(vtkArrayExtents(vtkArrayRange(0, 1)), vtkArrayExtents(vtkArrayRange(1, 2))), vtkArrayWeights(0.5, 0.5), vtkArrayExtents(vtkArrayRange(0, 1)), b.GetPointer());
+    vtkInterpolate(a.GetPointer(), vtkArrayExtentsList(vtkArrayExtents(vtkArrayRange(2, 3)), vtkArrayExtents(vtkArrayRange(3, 4))), vtkArrayWeights(0.5, 0.5), vtkArrayExtents(vtkArrayRange(1, 2)), b.GetPointer());
 
     test_expression(b->GetValue(0) == 0.5, "expected 0.5");
     test_expression(b->GetValue(1) == 2.5, "expected 2.5");
@@ -66,8 +66,8 @@ int ArrayInterpolationDense(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     vtkSmartPointer<vtkDenseArray<double> > d = vtkSmartPointer<vtkDenseArray<double> >::New();
     d->Resize(vtkArrayExtents(2, 2));
 
-    vtkInterpolate(c.GetPointer(), vtkArraySlices(vtkArraySlice(vtkArrayRange(0), vtkArrayRange(0, 2)), vtkArraySlice(vtkArrayRange(1), vtkArrayRange(0, 2))), vtkArrayWeights(0.5, 0.5), vtkArraySlice(vtkArrayRange(0), vtkArrayRange(0, 2)), d.GetPointer());
-    vtkInterpolate(c.GetPointer(), vtkArraySlices(vtkArraySlice(vtkArrayRange(2), vtkArrayRange(0, 2)), vtkArraySlice(vtkArrayRange(3), vtkArrayRange(0, 2))), vtkArrayWeights(0.5, 0.5), vtkArraySlice(vtkArrayRange(1), vtkArrayRange(0, 2)), d.GetPointer());
+    vtkInterpolate(c.GetPointer(), vtkArrayExtentsList(vtkArrayExtents(vtkArrayRange(0, 1), vtkArrayRange(0, 2)), vtkArrayExtents(vtkArrayRange(1, 2), vtkArrayRange(0, 2))), vtkArrayWeights(0.5, 0.5), vtkArrayExtents(vtkArrayRange(0, 1), vtkArrayRange(0, 2)), d.GetPointer());
+    vtkInterpolate(c.GetPointer(), vtkArrayExtentsList(vtkArrayExtents(vtkArrayRange(2, 3), vtkArrayRange(0, 2)), vtkArrayExtents(vtkArrayRange(3, 4), vtkArrayRange(0, 2))), vtkArrayWeights(0.5, 0.5), vtkArrayExtents(vtkArrayRange(1, 2), vtkArrayRange(0, 2)), d.GetPointer());
 
     test_expression(d->GetValue(0, 0) == 1, "expected 1");
     test_expression(d->GetValue(0, 1) == 2, "expected 2");
diff --git a/Common/Testing/Cxx/CMakeLists.txt b/Common/Testing/Cxx/CMakeLists.txt
index 1c5308ed20d..2402f93f4ab 100644
--- a/Common/Testing/Cxx/CMakeLists.txt
+++ b/Common/Testing/Cxx/CMakeLists.txt
@@ -81,7 +81,7 @@ IF(VTK_USE_N_WAY_ARRAYS)
     ArrayBool.cxx
     ArrayInterpolationDense.cxx
     ArrayNullValues.cxx
-    ArraySlice.cxx
+    ArrayExtents.cxx
     ArrayUserTypes.cxx
     ArrayVariants.cxx
     SparseArrayValidation.cxx
diff --git a/Common/vtkArray.cxx b/Common/vtkArray.cxx
index b0fc33fe5eb..7b1eca00255 100644
--- a/Common/vtkArray.cxx
+++ b/Common/vtkArray.cxx
@@ -30,7 +30,7 @@
 // Standard functions
 //
 
-vtkCxxRevisionMacro(vtkArray, "1.5");
+vtkCxxRevisionMacro(vtkArray, "1.6");
 
 //----------------------------------------------------------------------------
 
@@ -138,36 +138,42 @@ vtkArray* vtkArray::CreateArray(int StorageType, int ValueType)
     return 0;
 }
 
-void vtkArray::Resize(vtkIdType i)
+void vtkArray::Resize(const vtkIdType i)
+{
+  this->Resize(vtkArrayExtents(vtkArrayRange(0, i)));
+}
+
+void vtkArray::Resize(const vtkArrayRange& i)
 {
   this->Resize(vtkArrayExtents(i));
 }
 
-void vtkArray::Resize(vtkIdType i, vtkIdType j)
+void vtkArray::Resize(const vtkIdType i, const vtkIdType j)
+{
+  this->Resize(vtkArrayExtents(vtkArrayRange(0, i), vtkArrayRange(0, j)));
+}
+
+void vtkArray::Resize(const vtkArrayRange& i, const vtkArrayRange& j)
 {
   this->Resize(vtkArrayExtents(i, j));
 }
 
-void vtkArray::Resize(vtkIdType i, vtkIdType j, vtkIdType k)
+void vtkArray::Resize(const vtkIdType i, const vtkIdType j, const vtkIdType k)
+{
+  this->Resize(vtkArrayExtents(vtkArrayRange(0, i), vtkArrayRange(0, j), vtkArrayRange(0, k)));
+}
+
+void vtkArray::Resize(const vtkArrayRange& i, const vtkArrayRange& j, const vtkArrayRange& k)
 {
   this->Resize(vtkArrayExtents(i, j, k));
 }
 
 void vtkArray::Resize(const vtkArrayExtents& extents)
 {    
-  for(vtkIdType i = 0; i != extents.GetDimensions(); ++i)
-    {
-    if(extents[i] < 0)
-      {
-      vtkErrorMacro(<< "cannot create dimension with extents < 0");
-      return;
-      }
-    }
-
   this->InternalResize(extents);
 }
 
-vtkIdType vtkArray::GetExtent(vtkIdType dimension)
+const vtkArrayRange vtkArray::GetExtent(vtkIdType dimension)
 {
   return this->GetExtents()[dimension];
 }
diff --git a/Common/vtkArray.h b/Common/vtkArray.h
index ecc6f06c19b..29d076da452 100644
--- a/Common/vtkArray.h
+++ b/Common/vtkArray.h
@@ -91,21 +91,23 @@ public:
   // initialize its contents accordingly.  In particular, dimension-labels will be
   // undefined, dense array values will be undefined, and sparse arrays will be
   // empty.
-  void Resize(vtkIdType i);
-  void Resize(vtkIdType i, vtkIdType j);
-  void Resize(vtkIdType i, vtkIdType j, vtkIdType k);
+  void Resize(const vtkIdType i);
+  void Resize(const vtkIdType i, const vtkIdType j);
+  void Resize(const vtkIdType i, const vtkIdType j, const vtkIdType k);
 //BTX
+  void Resize(const vtkArrayRange& i);
+  void Resize(const vtkArrayRange& i, const vtkArrayRange& j);
+  void Resize(const vtkArrayRange& i, const vtkArrayRange& j, const vtkArrayRange& k);
   void Resize(const vtkArrayExtents& extents);
 //ETX
 
+//BTX
   // Description:
-  // Returns the extent (array size) along the given dimension.
-  vtkIdType GetExtent(vtkIdType dimension);
-
+  // Returns the extent (valid coordinate range) along the given dimension.
+  const vtkArrayRange GetExtent(vtkIdType dimension);
   // Description:
   // Returns the extents (the number of dimensions and size along each dimension) of the array.
-//BTX
-  virtual vtkArrayExtents GetExtents() = 0;
+  virtual const vtkArrayExtents& GetExtents() = 0;
 //ETX
 
   // Description:
diff --git a/Common/vtkArrayCoordinateIterator.h b/Common/vtkArrayCoordinateIterator.h
deleted file mode 100644
index c98d5f96b03..00000000000
--- a/Common/vtkArrayCoordinateIterator.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*=========================================================================
-
-  Program:   Visualization Toolkit
-  Module:    vtkArrayCoordinateIterator.h
-
--------------------------------------------------------------------------
-  Copyright 2008 Sandia Corporation.
-  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
-  the U.S. Government retains certain rights in this software.
--------------------------------------------------------------------------
-
-  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
-  All rights reserved.
-  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notice for more information.
-
-=========================================================================*/
-
-// .NAME vtkArrayCoordinateIterator - Iterates over array coordinates.
-//
-// .SECTION Description
-// vtkArrayCoordinateIterator iterates over every unique set of coordinates
-// that are defined by a set of vtkArrayExtents.  The order in which
-// coordinates are visited is undefined.
-//
-// Note that vtkArrayCoordinateIterator visits every permutation of
-// coordinates defined by a set of array extents, *not* the array itself - if
-// you are working with a sparse array, any of the coordinates that are visited
-// by the iterator could be NULL within the array.
-//
-// vtkArrayCoordinateIterator is mainly useful if you are writing a source that
-// generates arbitrary-dimension arrays from scratch.  Algorithms that process
-// existing arrays can almost always be written more efficiently using
-// vtkArray::GetCoordinatesN() and vtkTypedArray::GetValueN(), which only visit
-// non-NULL values within an array.
-//
-// .SECTION See Also
-// vtkArray, vtkArrayExtents, vtkArrayCoordinates
-//
-// .SECTION Thanks
-// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
-
-#ifndef __vtkArrayCoordinateIterator_h
-#define __vtkArrayCoordinateIterator_h
-
-#include "vtkArrayExtents.h"
-#include "vtkArrayCoordinates.h"
-#include "vtkObject.h"
-
-class VTK_COMMON_EXPORT vtkArrayCoordinateIterator : public vtkObject
-{
-public:
-  static vtkArrayCoordinateIterator* New();
-  vtkTypeRevisionMacro(vtkArrayCoordinateIterator, vtkObject);
-  void PrintSelf(ostream &os, vtkIndent indent);
-
-//BTX
-  // Description:
-  // Sets the array extents to iterate over, and resets the iterator to
-  // the beginning of the range of unique coordinates.
-  void SetExtents(const vtkArrayExtents&);
-//ETX
-
-  // Description:
-  // Returns true iff the iterator has not reached the end
-  // of the range of unique coordinates.
-  bool HasNext();
-
-  // Description:
-  // Returns the next set of coordinates and advances the iterator.
-//BTX
-  vtkArrayCoordinates Next();
-//ETX
-
-protected:
-  vtkArrayCoordinateIterator();
-  ~vtkArrayCoordinateIterator();
-
-private:
-  vtkArrayCoordinateIterator(const vtkArrayCoordinateIterator&); // Not implemented
-  void operator=(const vtkArrayCoordinateIterator&); // Not implemented
-
-  vtkArrayExtents Extents;
-  vtkArrayCoordinates Coordinates;
-  vtkIdType Current;
-  vtkIdType End;
-};
-
-#endif
-
diff --git a/Common/vtkArrayExtents.cxx b/Common/vtkArrayExtents.cxx
index 800ff4d6a3d..3912d5fcca0 100644
--- a/Common/vtkArrayExtents.cxx
+++ b/Common/vtkArrayExtents.cxx
@@ -29,20 +29,41 @@ vtkArrayExtents::vtkArrayExtents()
 {
 }
 
-vtkArrayExtents::vtkArrayExtents(vtkIdType i) :
+vtkArrayExtents::vtkArrayExtents(const vtkIdType i) :
+  Storage(1)
+{
+  this->Storage[0] = vtkArrayRange(0, i);
+}
+
+vtkArrayExtents::vtkArrayExtents(const vtkArrayRange& i) :
   Storage(1)
 {
   this->Storage[0] = i;
 }
 
-vtkArrayExtents::vtkArrayExtents(vtkIdType i, vtkIdType j) :
+vtkArrayExtents::vtkArrayExtents(const vtkIdType i, const vtkIdType j) :
+  Storage(2)
+{
+  this->Storage[0] = vtkArrayRange(0, i);
+  this->Storage[1] = vtkArrayRange(0, j);
+}
+
+vtkArrayExtents::vtkArrayExtents(const vtkArrayRange& i, const vtkArrayRange& j) :
   Storage(2)
 {
   this->Storage[0] = i;
   this->Storage[1] = j;
 }
 
-vtkArrayExtents::vtkArrayExtents(vtkIdType i, vtkIdType j, vtkIdType k) :
+vtkArrayExtents::vtkArrayExtents(const vtkIdType i, const vtkIdType j, const vtkIdType k) :
+  Storage(3)
+{
+  this->Storage[0] = vtkArrayRange(0, i);
+  this->Storage[1] = vtkArrayRange(0, j);
+  this->Storage[2] = vtkArrayRange(0, k);
+}
+
+vtkArrayExtents::vtkArrayExtents(const vtkArrayRange& i, const vtkArrayRange& j, const vtkArrayRange& k) :
   Storage(3)
 {
   this->Storage[0] = i;
@@ -58,15 +79,15 @@ const vtkArrayExtents vtkArrayExtents::Uniform(vtkIdType n, vtkIdType m)
   // arguement constructor and initialize the values manually.
   // result.Storage = vtksys_stl::vector<vtkIdType>(n, m);
 
-  result.Storage = vtksys_stl::vector<vtkIdType>(n);
-  for(int i = 0; i < n; i++)
+  result.Storage = vtksys_stl::vector<vtkArrayRange>(n);
+  for(vtkIdType i = 0; i < n; i++)
     {
-    result.Storage[i] = m;
+    result.Storage[i] = vtkArrayRange(0, m);
     }
   return result;
 }
 
-void vtkArrayExtents::Append(vtkIdType extent)
+void vtkArrayExtents::Append(const vtkArrayRange& extent)
 {
   this->Storage.push_back(extent);
 }
@@ -81,20 +102,24 @@ vtkIdType vtkArrayExtents::GetSize() const
   if(this->Storage.empty())
     return 0;
 
-  return vtkstd::accumulate(this->Storage.begin(), this->Storage.end(), 1, vtkstd::multiplies<vtkIdType>());
+  vtkIdType size = 1;
+  for(vtkIdType i = 0; i != this->Storage.size(); ++i)
+    size *= this->Storage[i].GetSize();
+
+  return size;
 }
 
 void vtkArrayExtents::SetDimensions(vtkIdType dimensions)
 {
-  this->Storage.assign(dimensions, 0);
+  this->Storage.assign(dimensions, vtkArrayRange());
 }
 
-vtkIdType& vtkArrayExtents::operator[](vtkIdType i)
+vtkArrayRange& vtkArrayExtents::operator[](vtkIdType i)
 {
   return this->Storage[i];
 }
 
-const vtkIdType& vtkArrayExtents::operator[](vtkIdType i) const
+const vtkArrayRange& vtkArrayExtents::operator[](vtkIdType i) const
 {
   return this->Storage[i];
 }
@@ -109,6 +134,69 @@ bool vtkArrayExtents::operator!=(const vtkArrayExtents& rhs) const
   return !(*this == rhs);
 }
 
+bool vtkArrayExtents::ZeroBased() const
+{
+  for(vtkIdType i = 0; i != this->GetDimensions(); ++i)
+    {
+    if(this->Storage[i].GetBegin() != 0)
+      return false;
+    }
+
+  return true;
+}
+
+bool vtkArrayExtents::SameShape(const vtkArrayExtents& rhs) const
+{
+  if(this->GetDimensions() != rhs.GetDimensions())
+    return false;
+
+  for(vtkIdType i = 0; i != this->GetDimensions(); ++i)
+    {
+    if(this->Storage[i].GetSize() != rhs.Storage[i].GetSize())
+      return false;
+    }
+
+  return true;
+}
+
+void vtkArrayExtents::GetLeftToRightCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const
+{
+  coordinates.SetDimensions(this->GetDimensions());
+
+  vtkIdType divisor = 1;
+  for(vtkIdType i = 0; i < this->GetDimensions(); ++i)
+    {
+    coordinates[i] = ((n / divisor) % this->Storage[i].GetSize()) + this->Storage[i].GetBegin();
+    divisor *= this->Storage[i].GetSize();
+    }
+}
+
+void vtkArrayExtents::GetRightToLeftCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const
+{
+  coordinates.SetDimensions(this->GetDimensions());
+
+  vtkIdType divisor = 1;
+  for(vtkIdType i = this->GetDimensions() - 1; i >= 0; --i)
+    {
+    coordinates[i] = ((n / divisor) % this->Storage[i].GetSize()) + this->Storage[i].GetBegin();
+    divisor *= this->Storage[i].GetSize();
+    }
+}
+
+bool vtkArrayExtents::Contains(const vtkArrayExtents& other) const
+{
+  if(this->GetDimensions() != other.GetDimensions())
+    return false;
+
+  for(vtkIdType i = 0; i != this->GetDimensions(); ++i)
+    {
+    if(!this->Storage[i].Contains(other[i]))
+      return false;
+    }
+
+  return true;
+}
+
 bool vtkArrayExtents::Contains(const vtkArrayCoordinates& coordinates) const
 {
   if(coordinates.GetDimensions() != this->GetDimensions())
@@ -116,9 +204,7 @@ bool vtkArrayExtents::Contains(const vtkArrayCoordinates& coordinates) const
 
   for(vtkIdType i = 0; i != this->GetDimensions(); ++i)
     {
-    if(coordinates[i] < 0)
-      return false;
-    if(coordinates[i] >= this->Storage[i])
+    if(!this->Storage[i].Contains(coordinates[i]))
       return false;
     }
 
@@ -131,7 +217,7 @@ ostream& operator<<(ostream& stream, const vtkArrayExtents& rhs)
     {
     if(i)
       stream << "x";
-    stream << rhs.Storage[i];
+    stream << "[" << rhs.Storage[i].GetBegin() << "," << rhs.Storage[i].GetEnd() << ")";
     }
 
   return stream;
diff --git a/Common/vtkArrayExtents.h b/Common/vtkArrayExtents.h
index 7811ded41c5..a965ce6cbc0 100644
--- a/Common/vtkArrayExtents.h
+++ b/Common/vtkArrayExtents.h
@@ -19,13 +19,21 @@
 
 =========================================================================*/
 
-// .NAME vtkArrayExtents - Stores the number of dimensions and size of an
-// N-way array.
+// .NAME vtkArrayExtents - Stores the number of dimensions and valid coordinate
+// ranges along each dimension for vtkArray.
 //
 // .SECTION Description
-// vtkArrayExtents describes the number of dimensions and size along each
-// dimension of an N-way collection of values.  It is used to retrieve and
-// update the extents of a vtkArray object.
+// vtkArrayExtents describes the number of dimensions and coordinate ranges
+//  along each dimension of an N-way collection of values.  It is used to
+// retrieve and update the extents of a vtkArray object.
+//
+// Conceptually, vtkArrayExtents is a collection of vtkArrayRange objects,
+// one per dimension, that store the half-open range of valid coordinates
+// (the "extent") for that dimension.  Because each extent is stored as a
+// range rather than a size, you can: create arrays that use one-based
+// coordinates for consistency with mathematics and tools such as MATLAB;
+// easily represent arbitrary subsets of an array; and easily store and
+// manipulate distributed arrays using "global" coordinates.
 //
 // Convenience constructors are provided for creating extents along one, two,
 // and three dimensions.  For higher dimensions, you can:
@@ -40,7 +48,7 @@
 // size along each dimension.
 //
 // .SECTION See Also
-// vtkArray, vtkArrayCoordinates
+// vtkArray, vtkArrayRange, vtkArrayCoordinates
 //
 // .SECTION Thanks
 // Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
@@ -49,6 +57,7 @@
 #define __vtkArrayExtents_h
 
 #include "vtkSystemIncludes.h"
+#include "vtkArrayRange.h"
 #include <vtksys/stl/vector> // STL Header
 
 class vtkArrayCoordinates;
@@ -60,26 +69,39 @@ public:
   // Create zero-dimensional extents.
   vtkArrayExtents();
   
+  // Description:
+  // Create one-dimensional extents.  This constructor is shorthand for
+  // vtkArrayExtents(vtkArrayRange(0, i)).
+  explicit vtkArrayExtents(const vtkIdType i);
   // Description:
   // Create one-dimensional extents. 
-  explicit vtkArrayExtents(vtkIdType i);
+  explicit vtkArrayExtents(const vtkArrayRange& i);
   
+  // Description:
+  // Create two-dimensional extents.  This constructor is shorthand for
+  // vtkArrayExtents(vtkArrayRange(0, i), vtkArrayRange(0, j)).
+  vtkArrayExtents(const vtkIdType i, const vtkIdType j);
   // Description:
   // Create two-dimensional extents.
-  vtkArrayExtents(vtkIdType i, vtkIdType j);
+  vtkArrayExtents(const vtkArrayRange& i, const vtkArrayRange& j);
   
   // Description:
-  // Create three-dimensional extents.
-  vtkArrayExtents(vtkIdType i, vtkIdType j, vtkIdType k);
+  // Create three-dimensional extents.  This constructor is shorthand for
+  // vtkArrayExtents(vtkArrayRange(0, i), vtkArrayRange(0, j), vtkArrayRange(0, k)).
+  vtkArrayExtents(const vtkIdType i, const vtkIdType j, const vtkIdType k);
+  // Description:
+  // Create two-dimensional extents.
+  vtkArrayExtents(const vtkArrayRange& i, const vtkArrayRange& j, const vtkArrayRange& k);
   
   // Description:
-  // Create n-dimensional extents with size m along each dimension.
+  // Create n-dimensional extents with extent [0, m) along each dimension.  This
+  // is useful for creating e.g: a square matrix.
   static const vtkArrayExtents Uniform(vtkIdType n, vtkIdType m);
 
   // Description:
   // Grow the number of dimensions by one, specifying the extent
   // of the new dimension.
-  void Append(vtkIdType extent);
+  void Append(const vtkArrayRange& extent);
 
   // Description:
   // Return the current number of dimensions.
@@ -87,24 +109,24 @@ public:
   
   // Description:
   // Return the number of values that *could* be stored using the
-  // current extents.  This is equal to the product of the extents
-  // along each dimension.
+  // current extents.  This is equal to the product of the size of the
+  // extent along each dimension.
   vtkIdType GetSize() const;
 
   // Description:
   // Set the current number of dimensions.  Note that this method
-  // resets the extent along each dimension to zero, so you must assign
-  // each dimension's extent explicitly using operator[] after calling
-  // SetDimensions().
+  // resets the extent along each dimension to an empty range, so you
+  // must assign each dimension's extent explicitly using operator[]
+  // after calling SetDimensions().
   void SetDimensions(vtkIdType dimensions);
   
   // Description:
   // Accesses the extent of the i-th dimension.
-  vtkIdType& operator[](vtkIdType i);
+  vtkArrayRange& operator[](vtkIdType i);
   
   // Description:
   // Accesses the extent of the i-th dimension.
-  const vtkIdType& operator[](vtkIdType i) const;
+  const vtkArrayRange& operator[](vtkIdType i) const;
   
   // Description:
   // Equality comparison
@@ -114,9 +136,44 @@ public:
   // Inequality comparison
   bool operator!=(const vtkArrayExtents& rhs) const;
 
+  // Description:
+  // Returns true iff every range in the current extents is zero-based.
+  // This is useful as a precondition test for legacy filters / operations
+  // that predate the switch to range-based extents and assume that all extents
+  // are zero-based.  In general, new code should be written to work with
+  // arbitrary range extents, so won't need to perform this check.
+  bool ZeroBased() const;
+
+  // Description:
+  // Returns true iff the given extents have the same number of dimensions
+  // and size along each dimension.  Note that the ranges along each dimension
+  // may have different values, so long as their sizes match.
+  bool SameShape(const vtkArrayExtents& rhs) const;
+
+  // Description:
+  // Returns coordinates that reference the n-th value in the extents, where
+  // n is in the range [0, GetSize()).  The returned coordinates will be ordered
+  // so that the left-most indices vary fastest.  The is equivalent to column-major
+  // ordering for matrices, and corresponds to the order in which consecutive array
+  // values would be stored in languages such as Fortran, MATLAB, Octave, and R.
+  void GetLeftToRightCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const;
+  // Description:
+  // Returns coordinates that reference the n-th value in the extents, where
+  // n is in the range [0, GetSize()).  The returned coordinates will be ordered
+  // so that the right-most indices vary fastest.  The is equivalent to row-major
+  // ordering for matrices, and corresponds to the order in which consecutive array
+  // values would be stored in languages including C and C++.
+  void GetRightToLeftCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const;
+
+  // Description:
+  // Returns true if the given extents are a non-overlapping subset of the
+  // current extents.  Returns false if any of the given extents fall outside
+  // the current extents, or there is a mismatch in the number of dimensions.
+  bool Contains(const vtkArrayExtents& extents) const;
+
   // Description:
   // Returns true if the given array coordinates are completely contained
-  // by the current extents (i.e. that 0 <= coordinate and coordinate < extent
+  // by the current extents (i.e. extent begin <= coordinate and coordinate < extent end
   // along every dimension).  Returns false if the array coordinates are outside
   // the current extents, or contain a different number of dimensions.
   bool Contains(const vtkArrayCoordinates& coordinates) const;
@@ -125,7 +182,7 @@ public:
     ostream& stream, const vtkArrayExtents& rhs);
   
 private:
-  vtksys_stl::vector<vtkIdType> Storage;
+  vtksys_stl::vector<vtkArrayRange> Storage;
 };
 
 #endif
diff --git a/Common/vtkArraySlices.cxx b/Common/vtkArrayExtentsList.cxx
similarity index 61%
rename from Common/vtkArraySlices.cxx
rename to Common/vtkArrayExtentsList.cxx
index 315cc0560fa..a8ebe0ed195 100644
--- a/Common/vtkArraySlices.cxx
+++ b/Common/vtkArrayExtentsList.cxx
@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Program:   Visualization Toolkit
-  Module:    vtkArraySlices.cxx
+  Module:    vtkArrayExtentsList.cxx
   
 -------------------------------------------------------------------------
   Copyright 2008 Sandia Corporation.
@@ -19,26 +19,26 @@
 
 =========================================================================*/
 
-#include "vtkArraySlices.h"
+#include "vtkArrayExtentsList.h"
 
-vtkArraySlices::vtkArraySlices()
+vtkArrayExtentsList::vtkArrayExtentsList()
 {
 }
 
-vtkArraySlices::vtkArraySlices(const vtkArraySlice& i) :
+vtkArrayExtentsList::vtkArrayExtentsList(const vtkArrayExtents& i) :
   Storage(1)
 {
   this->Storage[0] = i;
 }
   
-vtkArraySlices::vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j) :
+vtkArrayExtentsList::vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j) :
   Storage(2)
 {
   this->Storage[0] = i;
   this->Storage[1] = j;
 }
   
-vtkArraySlices::vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, const vtkArraySlice& k) :
+vtkArrayExtentsList::vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j, const vtkArrayExtents& k) :
   Storage(3)
 {
   this->Storage[0] = i;
@@ -46,7 +46,7 @@ vtkArraySlices::vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, c
   this->Storage[2] = k;
 }
 
-vtkArraySlices::vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, const vtkArraySlice& k, const vtkArraySlice& l) :
+vtkArrayExtentsList::vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j, const vtkArrayExtents& k, const vtkArrayExtents& l) :
   Storage(4)
 {
   this->Storage[0] = i;
@@ -55,22 +55,22 @@ vtkArraySlices::vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, c
   this->Storage[3] = l;
 }
 
-vtkIdType vtkArraySlices::GetCount() const
+vtkIdType vtkArrayExtentsList::GetCount() const
 {
   return this->Storage.size();
 }
 
-void vtkArraySlices::SetCount(vtkIdType count)
+void vtkArrayExtentsList::SetCount(vtkIdType count)
 {
-  this->Storage.assign(count, vtkArraySlice());
+  this->Storage.assign(count, vtkArrayExtents());
 }
 
-vtkArraySlice& vtkArraySlices::operator[](vtkIdType i)
+vtkArrayExtents& vtkArrayExtentsList::operator[](vtkIdType i)
 {
   return this->Storage[i];
 }
 
-const vtkArraySlice& vtkArraySlices::operator[](vtkIdType i) const
+const vtkArrayExtents& vtkArrayExtentsList::operator[](vtkIdType i) const
 {
   return this->Storage[i];
 }
diff --git a/Common/vtkArraySlices.h b/Common/vtkArrayExtentsList.h
similarity index 68%
rename from Common/vtkArraySlices.h
rename to Common/vtkArrayExtentsList.h
index be2da3ff9d0..dfd6b656fe7 100644
--- a/Common/vtkArraySlices.h
+++ b/Common/vtkArrayExtentsList.h
@@ -1,7 +1,7 @@
 /*=========================================================================
 
   Program:   Visualization Toolkit
-  Module:    vtkArraySlices.h
+  Module:    vtkArrayExtentsList.h
   
 -------------------------------------------------------------------------
   Copyright 2008 Sandia Corporation.
@@ -19,15 +19,15 @@
 
 =========================================================================*/
 
-// .NAME vtkArraySlices - Stores a collection of vtkArraySlice objects.
+// .NAME vtkArrayExtentsList - Stores a collection of vtkArraySlice objects.
 //
 // .SECTION Description
-// vtkArraySlices provides storage for a collection of vtkArraySlice instances.
+// vtkArrayExtentsList provides storage for a collection of vtkArraySlice instances.
 // Constructors are provided for creating collections containing one, two, three,
 // or four slices.  To work with larger numbers of slices, use the default
 // constructor, the SetCount() method, and operator[].
 //
-// vtkArraySlices is most commonly used with the vtkInterpolate() function, which
+// vtkArrayExtentsList is most commonly used with the vtkInterpolate() function, which
 // is used to computed weighted sums of vtkArray slices.
 //
 // .SECTION See Also
@@ -36,34 +36,34 @@
 // .SECTION Thanks
 // Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
 
-#ifndef __vtkArraySlices_h
-#define __vtkArraySlices_h
+#ifndef __vtkArrayExtentsList_h
+#define __vtkArrayExtentsList_h
 
-#include "vtkArraySlice.h"
-#include <vtksys/stl/vector>
+#include "vtkArrayExtents.h"
+#include <vtksys/stl/vector> // STL Header
 
-class VTK_COMMON_EXPORT vtkArraySlices
+class VTK_COMMON_EXPORT vtkArrayExtentsList
 {
 public:
   // Description:
   // Creates an empty collection of slices.
-  vtkArraySlices();
+  vtkArrayExtentsList();
   
   // Description:
   // Creates a collection containing one slice.
-  vtkArraySlices(const vtkArraySlice& i);
+  vtkArrayExtentsList(const vtkArrayExtents& i);
   
   // Description:
   // Creates a collection containing two slices.
-  vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j);
+  vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j);
   
   // Description:
   // Creates a collection containing three slices.
-  vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, const vtkArraySlice& k);
+  vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j, const vtkArrayExtents& k);
   
   // Description:
   // Creates a collection containing four slices.
-  vtkArraySlices(const vtkArraySlice& i, const vtkArraySlice& j, const vtkArraySlice& k, const vtkArraySlice& l);
+  vtkArrayExtentsList(const vtkArrayExtents& i, const vtkArrayExtents& j, const vtkArrayExtents& k, const vtkArrayExtents& l);
 
   // Description:
   // Returns the number of slices stored in this collection.
@@ -77,14 +77,14 @@ public:
 
   // Description:
   // Accesses the i-th slice.
-  vtkArraySlice& operator[](vtkIdType i);
+  vtkArrayExtents& operator[](vtkIdType i);
   
   // Description:
   // Accesses the i-th slice.
-  const vtkArraySlice& operator[](vtkIdType i) const;
+  const vtkArrayExtents& operator[](vtkIdType i) const;
 
 private:
-  vtkstd::vector<vtkArraySlice> Storage;
+  vtkstd::vector<vtkArrayExtents> Storage;
 };
 
 #endif
diff --git a/Common/vtkArrayInterpolate.h b/Common/vtkArrayInterpolate.h
index 095d7ee3a44..8e5eea1b7d2 100644
--- a/Common/vtkArrayInterpolate.h
+++ b/Common/vtkArrayInterpolate.h
@@ -24,7 +24,7 @@
 
 #include "vtkTypedArray.h"
 
-class vtkArraySlice;
+class vtkArrayExtents;
 class vtkArraySlices;
 class vtkArrayWeights;
 
@@ -51,7 +51,7 @@ void vtkInterpolate(
   vtkTypedArray<T>* source_array,
   const vtkArraySlices& source_slices,
   const vtkArrayWeights& source_weights,
-  const vtkArraySlice& target_slice,
+  const vtkArrayExtents& target_slice,
   vtkTypedArray<T>* target_array);
 
 #include "vtkArrayInterpolate.txx"
diff --git a/Common/vtkArrayInterpolate.txx b/Common/vtkArrayInterpolate.txx
index e80c21c9a76..a2e2b716c7b 100644
--- a/Common/vtkArrayInterpolate.txx
+++ b/Common/vtkArrayInterpolate.txx
@@ -22,47 +22,45 @@
 #ifndef __vtkArrayInterpolate_txx
 #define __vtkArrayInterpolate_txx
 
-#include "vtkArraySlices.h"
+#include "vtkArrayExtentsList.h"
 #include "vtkArrayWeights.h"
 
 template<typename T>
 void vtkInterpolate(
   vtkTypedArray<T>* source_array,
-  const vtkArraySlices& source_slices,
+  const vtkArrayExtentsList& source_slices,
   const vtkArrayWeights& source_weights,
-  const vtkArraySlice& target_slice,
+  const vtkArrayExtents& target_slice,
   vtkTypedArray<T>* target_array)
 {
-  const vtkArrayExtents target_extents = target_slice.GetExtents();
-  
-  if(target_extents.GetDimensions() != target_array->GetDimensions())
+  if(!target_array->GetExtents().Contains(target_slice))
     {
-    vtkGenericWarningMacro(<< "target slice must match target array dimensions");
+    vtkGenericWarningMacro(<< "Target array does not contain target slice.");
     return;
     }
   
   if(source_slices.GetCount() != source_weights.GetCount())
     {
-    vtkGenericWarningMacro(<< "source slice and weight counts must match");
+    vtkGenericWarningMacro(<< "Source slice and weight counts must match.");
     return;
     }
 
   for(int i = 0; i != source_slices.GetCount(); ++i)
     {
-    if(source_slices[i].GetExtents() != target_extents)
+    if(!target_slice.SameShape(source_slices[i]))
       {
-      vtkGenericWarningMacro(<< "source and target slice extents must match");
+      vtkGenericWarningMacro(<< "Source and target slice shapes must match: " << source_slices[i] << " versus " << target_slice);
       return;
       }
     }
     
   // Zero-out the target storage ...
   const vtkIdType n_begin = 0;
-  const vtkIdType n_end = target_extents.GetSize();
+  const vtkIdType n_end = target_slice.GetSize();
   vtkArrayCoordinates target_coordinates;
   for(vtkIdType n = n_begin; n != n_end; ++n)
     {
-    target_slice.GetCoordinatesN(n, target_coordinates);
+    target_slice.GetLeftToRightCoordinatesN(n, target_coordinates);
     target_array->SetValue(target_coordinates, 0);
     }
 
@@ -70,10 +68,10 @@ void vtkInterpolate(
   vtkArrayCoordinates source_coordinates;
   for(vtkIdType n = n_begin; n != n_end; ++n)
     {
-    target_slice.GetCoordinatesN(n, target_coordinates);
+    target_slice.GetLeftToRightCoordinatesN(n, target_coordinates);
     for(int source = 0; source != source_slices.GetCount(); ++source)
       {
-      source_slices[source].GetCoordinatesN(n, source_coordinates);
+      source_slices[source].GetLeftToRightCoordinatesN(n, source_coordinates);
       target_array->SetValue(target_coordinates, target_array->GetValue(target_coordinates) + (source_array->GetValue(source_coordinates) * source_weights[source]));
       }
     }
diff --git a/Common/vtkArrayPrint.txx b/Common/vtkArrayPrint.txx
index 7b93bb0d0fb..4e37f62ec45 100644
--- a/Common/vtkArrayPrint.txx
+++ b/Common/vtkArrayPrint.txx
@@ -68,13 +68,12 @@ void vtkPrintMatrixFormat(ostream& stream, vtkTypedArray<T>* matrix)
     return;
     }
     
-  const vtkArrayExtents extents = matrix->GetExtents();
-  const vtkIdType row_count = extents[0];
-  const vtkIdType column_count = extents[1];
+  const vtkArrayRange rows = matrix->GetExtent(0);
+  const vtkArrayRange columns = matrix->GetExtent(1);
 
-  for(vtkIdType row = 0; row != row_count; ++row)
+  for(vtkIdType row = rows.GetBegin(); row != rows.GetEnd(); ++row)
     {
-    for(vtkIdType column = 0; column != column_count; ++column)
+    for(vtkIdType column = columns.GetBegin(); column != columns.GetEnd(); ++column)
       {
       stream << matrix->GetValue(vtkArrayCoordinates(row, column)) << " ";
       }
@@ -97,10 +96,9 @@ void vtkPrintVectorFormat(ostream& stream, vtkTypedArray<T>* vector)
     return;
     }
     
-  const vtkArrayExtents extents = vector->GetExtents();
-  const vtkIdType row_count = extents[0];
+  const vtkArrayRange rows = vector->GetExtent(0);
 
-  for(vtkIdType row = 0; row != row_count; ++row)
+  for(vtkIdType row = rows.GetBegin(); row != rows.GetEnd(); ++row)
     {
     stream << vector->GetValue(vtkArrayCoordinates(row)) << "\n";
     }
diff --git a/Common/vtkArrayRange.cxx b/Common/vtkArrayRange.cxx
index 0887ac992c4..343ec2dd033 100644
--- a/Common/vtkArrayRange.cxx
+++ b/Common/vtkArrayRange.cxx
@@ -29,12 +29,6 @@ vtkArrayRange::vtkArrayRange() :
 {
 }
 
-vtkArrayRange::vtkArrayRange(vtkIdType index) :
-  Begin(index),
-  End(index + 1)
-{
-}
-
 vtkArrayRange::vtkArrayRange(vtkIdType begin, vtkIdType end) :
   Begin(begin),
   End(vtkstd::max(begin, end))
@@ -51,11 +45,16 @@ vtkIdType vtkArrayRange::GetEnd() const
   return this->End;
 }
 
-vtkIdType vtkArrayRange::GetExtent() const
+vtkIdType vtkArrayRange::GetSize() const
 {
   return this->End - this->Begin;
 }
 
+bool vtkArrayRange::Contains(const vtkArrayRange& range) const
+{
+  return this->Begin <= range.Begin && range.End <= this->End;
+}
+
 bool vtkArrayRange::Contains(const vtkIdType coordinate) const
 {
   return this->Begin <= coordinate && coordinate < this->End;
diff --git a/Common/vtkArrayRange.h b/Common/vtkArrayRange.h
index 0a5e663d0db..9aefdcfbcdf 100644
--- a/Common/vtkArrayRange.h
+++ b/Common/vtkArrayRange.h
@@ -43,10 +43,6 @@ public:
   // Creates an empty range.
   vtkArrayRange();
   
-  // Description:
-  // Creates a range containing a single value.
-  vtkArrayRange(vtkIdType index);
-  
   // Description:
   // Creates a half-open range [begin, end).  Note that begin must be <= end,
   // if not, creates the empty range [begin, begin).
@@ -61,8 +57,12 @@ public:
   vtkIdType GetEnd() const;
 
   // Description:
-  // Returns the extent of the range (the distance End - Begin).
-  vtkIdType GetExtent() const;
+  // Returns the size of the range (the distance End - Begin).
+  vtkIdType GetSize() const;
+
+  // Description:
+  // Returns true iff the given range is a non-overlapping subset of this range.
+  bool Contains(const vtkArrayRange& range) const;
 
   // Description:
   // Returns true iff the given coordinate falls within this range.
diff --git a/Common/vtkArraySlice.cxx b/Common/vtkArraySlice.cxx
deleted file mode 100644
index 0010b353905..00000000000
--- a/Common/vtkArraySlice.cxx
+++ /dev/null
@@ -1,118 +0,0 @@
-/*=========================================================================
-
-  Program:   Visualization Toolkit
-  Module:    vtkArraySlice.cxx
-  
--------------------------------------------------------------------------
-  Copyright 2008 Sandia Corporation.
-  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
-  the U.S. Government retains certain rights in this software.
--------------------------------------------------------------------------
-
-  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
-  All rights reserved.
-  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notice for more information.
-
-=========================================================================*/
-
-#include "vtkArrayCoordinates.h"
-#include "vtkArraySlice.h"
-
-vtkArraySlice::vtkArraySlice()
-{
-}
-
-vtkArraySlice::vtkArraySlice(const vtkArrayRange& i) :
-  Storage(1)
-{
-  this->Storage[0] = i;
-}
-
-vtkArraySlice::vtkArraySlice(const vtkArrayRange& i, const vtkArrayRange& j) :
-  Storage(2)
-{
-  this->Storage[0] = i;
-  this->Storage[1] = j;
-}
-
-vtkArraySlice::vtkArraySlice(const vtkArrayRange& i, const vtkArrayRange& j, const vtkArrayRange& k) :
-  Storage(3)
-{
-  this->Storage[0] = i;
-  this->Storage[1] = j;
-  this->Storage[2] = k;
-}
-
-vtkIdType vtkArraySlice::GetDimensions() const
-{
-  return this->Storage.size();
-}
-
-const vtkArrayExtents vtkArraySlice::GetExtents() const
-{
-  vtkArrayExtents result;
-  result.SetDimensions(this->GetDimensions());
-
-  for(int i = 0; i != this->GetDimensions(); ++i)
-    result[i] = this->Storage[i].GetExtent();
-
-  return result;
-}
-
-void vtkArraySlice::GetCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const
-{
-  coordinates.SetDimensions(this->GetDimensions());
-
-  vtkIdType divisor = 1;
-  for(vtkIdType i = 0; i < this->GetDimensions(); ++i)
-    {
-    coordinates[i] = ((n / divisor) % this->Storage[i].GetExtent()) + this->Storage[i].GetBegin();
-    divisor *= this->Storage[i].GetExtent();
-    }
-}
-
-bool vtkArraySlice::Contains(const vtkArrayCoordinates& coordinates) const
-{
-  if(coordinates.GetDimensions() != this->GetDimensions())
-    return false;
-
-  for(vtkIdType i = 0; i < this->GetDimensions(); ++i)
-    {
-    if(!this->Storage[i].Contains(coordinates[i]))
-      return false;
-    }
-
-  return true;
-}
-
-void vtkArraySlice::SetDimensions(vtkIdType dimensions)
-{
-  this->Storage.assign(dimensions, vtkArrayRange());
-}
-
-vtkArrayRange& vtkArraySlice::operator[](vtkIdType i)
-{
-  return this->Storage[i];
-}
-
-const vtkArrayRange& vtkArraySlice::operator[](vtkIdType i) const
-{
-  return this->Storage[i];
-}
-
-ostream& operator<<(ostream& stream, const vtkArraySlice& rhs)
-{
-  for(vtkIdType i = 0; i != static_cast<vtkIdType>(rhs.Storage.size()); ++i)
-    {
-    if(i)
-      stream << " ";
-    stream << rhs[i];
-    }
-    
-  return stream;
-}
-
diff --git a/Common/vtkArraySlice.h b/Common/vtkArraySlice.h
deleted file mode 100644
index 9d518f111da..00000000000
--- a/Common/vtkArraySlice.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*=========================================================================
-
-  Program:   Visualization Toolkit
-  Module:    vtkArraySlice.h
-  
--------------------------------------------------------------------------
-  Copyright 2008 Sandia Corporation.
-  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
-  the U.S. Government retains certain rights in this software.
--------------------------------------------------------------------------
-
-  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
-  All rights reserved.
-  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notice for more information.
-
-=========================================================================*/
-
-// .NAME vtkArraySlice - Describes a subset of an N-way array.
-//
-// .SECTION Description
-// vtkArraySlice describes a subset of a vtkArray as a set of half-open
-// ranges along each dimension.
-//
-// Convenience constructors are provided for specifying one, two, and three
-// dimension slices.  For higher dimensions, use the default constructor, the
-// SetDimensions() method and operator[] to assign a range along each dimension
-// of a slice.
-//
-// vtkArraySlice is most commonly used with the vtkInterpolate() function, which
-// is used to compute weighted sums of vtkArray slices.
-//
-// .SECTION See Also
-// vtkArray, vtkRange
-//
-// .SECTION Thanks
-// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
-
-#ifndef __vtkArraySlice_h
-#define __vtkArraySlice_h
-
-#include "vtkArrayExtents.h"
-#include "vtkArrayRange.h"
-
-#include <vtkstd/vector> // STL Header: duh
-
-class vtkArrayCoordinates;
-
-class VTK_COMMON_EXPORT vtkArraySlice
-{
-public:
-  // Description:
-  // Create a zero-dimensional slice.
-  vtkArraySlice();
-  
-  // Description:
-  // Create a one-dimensional slice.
-  vtkArraySlice(
-    const vtkArrayRange& i);
-  
-  // Description:
-  // Create a two-dimensional slice.
-  vtkArraySlice(
-    const vtkArrayRange& i,
-    const vtkArrayRange& j);
-  
-  // Description:
-  // Create a three-dimensional slice.
-  vtkArraySlice(
-    const vtkArrayRange& i,
-    const vtkArrayRange& j,
-    const vtkArrayRange& k);
-
-  // Description:
-  // Returns the number of dimensions in this slice.
-  vtkIdType GetDimensions() const;
-  
-  // Description:
-  // Returns the extents of this slice - i.e: the size of the range
-  // along each dimension.
-  const vtkArrayExtents GetExtents() const;
-  
-  // Description:
-  // Returns coordinates that reference the n-th value in the slice, where
-  // n is in the range [0, GetExtents().GetSize()).  Note that the order
-  // in which coordinates are visited is undefined.
-  void GetCoordinatesN(vtkIdType n, vtkArrayCoordinates& coordinates) const;
-
-  // Description:
-  // Returns true iff the given array coordinates have the same number of
-  // dimensions as this slice, and can be contained within all its ranges.
-  // Returns false if the array coordinates fall outside the slice, or
-  // have a different number of dimensions.
-  bool Contains(const vtkArrayCoordinates& coordinates) const;
-
-  // Description:
-  // Sets the number of slice dimensions.  Use operator[] to set the range
-  // along each dimension.  Note that the range along each slice dimension will
-  // be empty after calling SetDimensions(), so you must explicitly set them all.
-  void SetDimensions(vtkIdType dimensions);
-  
-  // Description:
-  // Accesses the range of the i-th dimension.
-  vtkArrayRange& operator[](vtkIdType i);
-  
-  // Description:
-  // Accesses the rnage of the i-th dimension.
-  const vtkArrayRange& operator[](vtkIdType i) const;
-  
-  friend ostream& operator<<(ostream& stream, const vtkArraySlice& rhs);
-
-private:
-  vtkstd::vector<vtkArrayRange> Storage;
-};
-
-#endif
-
diff --git a/Common/vtkDenseArray.h b/Common/vtkDenseArray.h
index 81c781a31c8..b2e322e7e40 100644
--- a/Common/vtkDenseArray.h
+++ b/Common/vtkDenseArray.h
@@ -58,7 +58,7 @@ public:
   
   // vtkArray API
   bool IsDense();
-  vtkArrayExtents GetExtents();
+  const vtkArrayExtents& GetExtents();
   vtkIdType GetNonNullSize();
   void GetCoordinatesN(const vtkIdType n, vtkArrayCoordinates& coordinates);
   vtkArray* DeepCopy();
@@ -193,7 +193,10 @@ private:
   T* End;
 
   // Description:
-  // Stores the strides along each array dimension (used for fast lookups).
+  // Stores the offset along each array dimension (used for fast lookups).
+  vtkstd::vector<vtkIdType> Offsets;
+  // Description:
+  // Stores the stride along each array dimension (used for fast lookups).
   vtkstd::vector<vtkIdType> Strides;
 };
 
diff --git a/Common/vtkDenseArray.txx b/Common/vtkDenseArray.txx
index 75d056fb392..feba4f2b955 100644
--- a/Common/vtkDenseArray.txx
+++ b/Common/vtkDenseArray.txx
@@ -93,7 +93,7 @@ bool vtkDenseArray<T>::IsDense()
 }
 
 template<typename T>
-vtkArrayExtents vtkDenseArray<T>::GetExtents()
+const vtkArrayExtents& vtkDenseArray<T>::GetExtents()
 {
   return this->Extents;
 }
@@ -112,8 +112,8 @@ void vtkDenseArray<T>::GetCoordinatesN(const vtkIdType n, vtkArrayCoordinates& c
   vtkIdType divisor = 1;
   for(vtkIdType i = 0; i < this->GetDimensions(); ++i)
     {
-    coordinates[i] = ((n / divisor) % this->Extents[i]);
-    divisor *= this->Extents[i];
+    coordinates[i] = ((n / divisor) % this->Extents[i].GetSize()) + this->Extents[i].GetBegin();
+    divisor *= this->Extents[i].GetSize();
     }
 }
 
@@ -318,19 +318,19 @@ vtkStdString vtkDenseArray<T>::InternalGetDimensionLabel(vtkIdType i)
 template<typename T>
 vtkIdType vtkDenseArray<T>::MapCoordinates(vtkIdType i)
 {
-  return (i * this->Strides[0]);
+  return ((i + this->Offsets[0]) * this->Strides[0]);
 }
 
 template<typename T>
 vtkIdType vtkDenseArray<T>::MapCoordinates(vtkIdType i, vtkIdType j)
 {
-  return (i * this->Strides[0]) + (j * this->Strides[1]);
+  return ((i + this->Offsets[0]) * this->Strides[0]) + ((j + this->Offsets[1]) * this->Strides[1]);
 }
 
 template<typename T>
 vtkIdType vtkDenseArray<T>::MapCoordinates(vtkIdType i, vtkIdType j, vtkIdType k)
 {
-  return (i * this->Strides[0]) + (j * this->Strides[1]) + (k * this->Strides[2]);
+  return ((i + this->Offsets[0]) * this->Strides[0]) + ((j + this->Offsets[1]) * this->Strides[1]) + ((k + this->Offsets[2]) * this->Strides[2]);
 }
 
 template<typename T>
@@ -338,7 +338,7 @@ vtkIdType vtkDenseArray<T>::MapCoordinates(const vtkArrayCoordinates& coordinate
 {
   vtkIdType index = 0;
   for(vtkIdType i = 0; i != static_cast<vtkIdType>(this->Strides.size()); ++i)
-    index += (coordinates[i] * this->Strides[i]);
+    index += ((coordinates[i] + this->Offsets[i]) * this->Strides[i]);
 
   return index;
 }
@@ -354,13 +354,19 @@ void vtkDenseArray<T>::Reconfigure(const vtkArrayExtents& extents, MemoryBlock*
   this->Begin = storage->GetAddress();
   this->End = this->Begin + extents.GetSize(); 
 
+  this->Offsets.resize(extents.GetDimensions());
+  for(vtkIdType i = 0; i != extents.GetDimensions(); ++i)
+    {
+    this->Offsets[i] = -extents[i].GetBegin();
+    }
+
   this->Strides.resize(extents.GetDimensions());
   for(vtkIdType i = 0; i != extents.GetDimensions(); ++i)
     {
     if(i == 0)
       this->Strides[i] = 1;
     else
-      this->Strides[i] = this->Strides[i-1] * extents[i-1];
+      this->Strides[i] = this->Strides[i-1] * extents[i-1].GetSize();
     }
 }
 
diff --git a/Common/vtkSparseArray.h b/Common/vtkSparseArray.h
index 49b92df1f8f..731370247c6 100644
--- a/Common/vtkSparseArray.h
+++ b/Common/vtkSparseArray.h
@@ -79,7 +79,7 @@ public:
 
   // vtkArray API 
   bool IsDense();
-  vtkArrayExtents GetExtents();
+  const vtkArrayExtents& GetExtents();
   vtkIdType GetNonNullSize();
   void GetCoordinatesN(const vtkIdType n, vtkArrayCoordinates& coordinates);
   vtkArray* DeepCopy();
diff --git a/Common/vtkSparseArray.txx b/Common/vtkSparseArray.txx
index 746c69e4908..b119f388269 100644
--- a/Common/vtkSparseArray.txx
+++ b/Common/vtkSparseArray.txx
@@ -48,7 +48,7 @@ bool vtkSparseArray<T>::IsDense()
 }
 
 template<typename T>
-vtkArrayExtents vtkSparseArray<T>::GetExtents()
+const vtkArrayExtents& vtkSparseArray<T>::GetExtents()
 {
   return this->Extents;
 }
@@ -451,16 +451,21 @@ void vtkSparseArray<T>::ReserveStorage(const vtkIdType value_count)
 template<typename T>
 void vtkSparseArray<T>::SetExtentsFromContents()
 {
-  vtkArrayExtents new_extents = vtkArrayExtents::Uniform(this->GetDimensions(), 0);
+  vtkArrayExtents new_extents;
 
-  vtkIdType row_begin = 0;
-  vtkIdType row_end = row_begin + this->Values.size();
-  for(vtkIdType row = row_begin; row != row_end; ++row)
+  const vtkIdType row_begin = 0;
+  const vtkIdType row_end = row_begin + this->Values.size();
+  const vtkIdType dimension_count = this->GetDimensions();
+  for(vtkIdType dimension = 0; dimension != dimension_count; ++dimension)
     {
-    for(vtkIdType column = 0; column != this->GetDimensions(); ++column)
+    vtkIdType range_begin = std::numeric_limits<vtkIdType>::max();
+    vtkIdType range_end = -std::numeric_limits<vtkIdType>::max();
+    for(vtkIdType row = row_begin; row != row_end; ++row)
       {
-      new_extents[column] = vtkstd::max(new_extents[column], this->Coordinates[column][row] + 1);
+        range_begin = vtkstd::min(range_begin, this->Coordinates[dimension][row]);
+        range_end = vtkstd::max(range_end, this->Coordinates[dimension][row] + 1);
       }
+    new_extents.Append(vtkArrayRange(range_begin, range_end));
     }
 
   this->Extents = new_extents;
@@ -552,13 +557,7 @@ bool vtkSparseArray<T>::Validate()
     {
     for(vtkIdType j = 0; j != dimensions; ++j)
       {
-      if(this->Coordinates[j][i] < 0)
-        {
-        ++out_of_bound_count;
-        break;
-        }
-
-      if(this->Coordinates[j][i] >= this->Extents[j])
+      if(this->Coordinates[j][i] < this->Extents[j].GetBegin() || this->Coordinates[j][i] >= this->Extents[j].GetEnd())
         {
         ++out_of_bound_count;
         break;
diff --git a/IO/Testing/Cxx/TestArraySerialization.cxx b/IO/Testing/Cxx/TestArraySerialization.cxx
index d20c6513070..2ecd0d0583a 100644
--- a/IO/Testing/Cxx/TestArraySerialization.cxx
+++ b/IO/Testing/Cxx/TestArraySerialization.cxx
@@ -56,6 +56,7 @@ int TestArraySerialization(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
 
     vtkstd::stringstream a_buffer;
     vtkArrayWriter::Write(a1, a_buffer);
+
     vtkSmartPointer<vtkArray> a2;
     a2.TakeReference(vtkArrayReader::Read(a_buffer));
 
@@ -72,28 +73,28 @@ int TestArraySerialization(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
     test_expression(a2->GetVariantValue(1, 1).ToDouble() == 2.5);
 
     // Test sparse-array coordinates out-of-bounds ...
-    vtkstd::istringstream b_buffer("vtk-sparse-array double\nascii\nb1\n2 2 1\nrows\ncolumns\n0\n2 2 3.5\n");
+    vtkstd::istringstream b_buffer("vtk-sparse-array double\nascii\nb1\n0 2 0 2 1\nrows\ncolumns\n0\n2 2 3.5\n");
     vtkSmartPointer<vtkArray> b1;
     b1.TakeReference(vtkArrayReader::Read(b_buffer));
 
     test_expression(!b1);
 
     // Test sparse-array too many values ...
-    vtkstd::istringstream c_buffer("vtk-sparse-array double\nascii\nc1\n2 2 1\nrows\ncolumns\n0\n0 0 1.1\n0 1 2.2\n");
+    vtkstd::istringstream c_buffer("vtk-sparse-array double\nascii\nc1\n0 2 0 2 1\nrows\ncolumns\n0\n0 0 1.1\n0 1 2.2\n");
     vtkSmartPointer<vtkArray> c1;
     c1.TakeReference(vtkArrayReader::Read(c_buffer));
 
     test_expression(!c1);
 
     // Test sparse-array not enough values ...
-    vtkstd::istringstream d_buffer("vtk-sparse-array double\nascii\nd1\n2 2 1\nrows\ncolumns\n0\n");
+    vtkstd::istringstream d_buffer("vtk-sparse-array double\nascii\nd1\n0 2 0 2 1\nrows\ncolumns\n0\n");
     vtkSmartPointer<vtkArray> d1;
     d1.TakeReference(vtkArrayReader::Read(d_buffer));
 
     test_expression(!d1);
 
     // Test dense string arrays containing whitespace ...
-    vtkstd::istringstream e_buffer("vtk-dense-array string\nascii\ne1\n3 3\nvalues\nThe\nquick brown\nfox\n");
+    vtkstd::istringstream e_buffer("vtk-dense-array string\nascii\ne1\n0 3 3\nvalues\nThe\nquick brown\nfox\n");
     vtkSmartPointer<vtkArray> e1;
     e1.TakeReference(vtkArrayReader::Read(e_buffer));
 
@@ -105,7 +106,7 @@ int TestArraySerialization(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
     test_expression(e1->GetVariantValue(2).ToString() == "fox");
 
     // Test sparse string arrays containing whitespace ...
-    vtkstd::istringstream f_buffer("vtk-sparse-array string\nascii\nf1\n3 3\nvalues\nempty value\n0 The\n1 quick brown\n2 fox\n");
+    vtkstd::istringstream f_buffer("vtk-sparse-array string\nascii\nf1\n0 3 3\nvalues\nempty value\n0 The\n1 quick brown\n2 fox\n");
     vtkSmartPointer<vtkArray> f1;
     f1.TakeReference(vtkArrayReader::Read(f_buffer));
 
@@ -158,7 +159,7 @@ int TestArraySerialization(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
     test_expression(h2->GetVariantValue(2).ToUnicodeString() == vtkUnicodeString::from_utf8("fox"));
 
     // Test sparse arrays with DOS line endings ...
-    vtkstd::istringstream i_buffer("vtk-sparse-array double\r\nascii\r\ni1\r\n2 2 1\r\nrows\r\ncolumns\r\n0\r\n0 0 5\r\n");
+    vtkstd::istringstream i_buffer("vtk-sparse-array double\r\nascii\r\ni1\r\n0 2 0 2 1\r\nrows\r\ncolumns\r\n0\r\n0 0 5\r\n");
     vtkSmartPointer<vtkArray> i1;
     i1.TakeReference(vtkArrayReader::Read(i_buffer));
 
diff --git a/IO/vtkArrayReader.cxx b/IO/vtkArrayReader.cxx
index c5d038bcb96..1caf9a63f85 100644
--- a/IO/vtkArrayReader.cxx
+++ b/IO/vtkArrayReader.cxx
@@ -20,7 +20,6 @@
 
 #include "vtkArrayReader.h"
 
-#include <vtkArrayCoordinateIterator.h>
 #include <vtkCommand.h>
 #include <vtkDenseArray.h>
 #include <vtkObjectFactory.h>
@@ -32,7 +31,7 @@
 #include <vtkstd/stdexcept>
 #include <vtkstd/string>
 
-vtkCxxRevisionMacro(vtkArrayReader, "1.3");
+vtkCxxRevisionMacro(vtkArrayReader, "1.4");
 vtkStandardNewMacro(vtkArrayReader);
 
 namespace {
@@ -85,12 +84,21 @@ void ReadHeader(istream& stream, vtkArrayExtents& extents, vtkIdType& non_null_s
   for(extents_buffer >> extent; extents_buffer; extents_buffer >> extent)
     temp_extents.push_back(extent);
 
-  if(temp_extents.size() < 2)
-    throw vtkstd::runtime_error("Missing array extents.");
-
   extents.SetDimensions(0);
-  for(vtkstd::vector<vtkIdType>::size_type i = 0; i + 1 < temp_extents.size(); ++i)
-    extents.Append(temp_extents[i]);
+  while(temp_extents.size() > 1)
+    {
+    const vtkIdType begin = temp_extents.front();
+    temp_extents.erase(temp_extents.begin());
+    const vtkIdType end = temp_extents.front();
+    temp_extents.erase(temp_extents.begin());
+    extents.Append(vtkArrayRange(begin, end));
+    }
+
+  if(extents.GetDimensions() < 1)
+    throw vtkstd::runtime_error("Array cannot have fewer than one dimension.");
+
+  if(temp_extents.empty())
+    throw vtkstd::runtime_error("Missing non null size.");
 
   non_null_size = temp_extents.back();
 
@@ -406,7 +414,7 @@ vtkSparseArray<ValueT>* ReadSparseArrayAscii(istream& stream)
     for(vtkIdType j = 0; j != array->GetDimensions(); ++j)
       {
       line_stream >> *(coordinates[j] + value_count);
-      if(*(coordinates[j] + value_count) >= extents[j])
+      if(!extents[j].Contains(*(coordinates[j] + value_count)))
         throw vtkstd::runtime_error("Coordinate out-of-bounds.");
       if(!line_stream)
         throw vtkstd::runtime_error("Missing coordinate.");
@@ -440,20 +448,19 @@ vtkDenseArray<ValueT>* ReadDenseArrayAscii(istream& stream)
     throw vtkstd::runtime_error("Incorrect number of values for a dense array.");
 
   // Read the file contents ...
-  vtkSmartPointer<vtkArrayCoordinateIterator> iterator = vtkSmartPointer<vtkArrayCoordinateIterator>::New();
-  iterator->SetExtents(extents);
-
   ValueT value;
-  vtkIdType value_count = 0;
-  for(ExtractValue(stream, value); stream; ExtractValue(stream, value), ++value_count)
+  vtkIdType n = 0;
+  vtkArrayCoordinates coordinates;
+  for(ExtractValue(stream, value); stream; ExtractValue(stream, value), ++n)
     {
-    if(value_count + 1 > non_null_size)
+    if(n + 1 > non_null_size)
       throw vtkstd::runtime_error("Stream contains too many values.");
 
-    array->SetValue(iterator->Next(), value);
+    extents.GetRightToLeftCoordinatesN(n, coordinates);
+    array->SetValue(coordinates, value);
     }
 
-  if(value_count != non_null_size)
+  if(n != non_null_size)
     throw vtkstd::runtime_error("Stream doesn't contain enough values.");
 
   array->Register(0); 
diff --git a/IO/vtkArrayWriter.cxx b/IO/vtkArrayWriter.cxx
index 72d1fe855d6..aeaa57fe3dd 100644
--- a/IO/vtkArrayWriter.cxx
+++ b/IO/vtkArrayWriter.cxx
@@ -15,7 +15,6 @@
 
 #include "vtkArrayWriter.h"
 
-#include <vtkArrayCoordinateIterator.h>
 #include <vtkArrayPrint.h>
 #include <vtkDenseArray.h>
 #include <vtkExecutive.h>
@@ -56,7 +55,7 @@ void WriteHeader(const vtkStdString& array_type,
 
   // Serialize the array extents and number of non-NULL values ...
   for(vtkIdType i = 0; i != dimensions; ++i)
-    stream << extents[i] << " ";
+    stream << extents[i].GetBegin() << " " << extents[i].GetEnd() << " ";
   stream << array->GetNonNullSize() << "\n";
 
   // Serialize the dimension-label for each dimension ...
@@ -300,11 +299,10 @@ bool WriteDenseArrayAscii(const vtkStdString& type_name, vtkArray* array, ostrea
   if(vtkstd::numeric_limits<ValueT>::is_specialized)
     stream.precision(vtkstd::numeric_limits<ValueT>::digits10 + 1);
 
-  vtkSmartPointer<vtkArrayCoordinateIterator> iterator = vtkSmartPointer<vtkArrayCoordinateIterator>::New();
-  iterator->SetExtents(extents);
-  while(iterator->HasNext())
+  vtkArrayCoordinates coordinates;
+  for(vtkIdType n = 0; n != extents.GetSize(); ++n)
     {
-    vtkArrayCoordinates coordinates = iterator->Next();
+    extents.GetRightToLeftCoordinatesN(n, coordinates);
     stream << concrete_array->GetValue(coordinates) << "\n";
     }
   
@@ -313,7 +311,7 @@ bool WriteDenseArrayAscii(const vtkStdString& type_name, vtkArray* array, ostrea
 
 } // End anonymous namespace
 
-vtkCxxRevisionMacro(vtkArrayWriter, "1.3");
+vtkCxxRevisionMacro(vtkArrayWriter, "1.4");
 vtkStandardNewMacro(vtkArrayWriter);
 
 vtkArrayWriter::vtkArrayWriter()
diff --git a/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx b/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
index 98033baad63..a54719fc4df 100644
--- a/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
+++ b/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
@@ -44,11 +44,11 @@ int ArrayMatricizeArray(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
 
     double value = 0;
     const vtkArrayExtents extents = array->GetExtents();
-    for(int i = 0; i != extents[0]; ++i)
+    for(int i = extents[0].GetBegin(); i != extents[0].GetEnd(); ++i)
       {
-      for(int j = 0; j != extents[1]; ++j)
+      for(int j = extents[1].GetBegin(); j != extents[1].GetEnd(); ++j)
         {
-        for(int k = 0; k != extents[2]; ++k)
+        for(int k = extents[2].GetBegin(); k != extents[2].GetEnd(); ++k)
           {
           array->AddValue(vtkArrayCoordinates(i, j, k), value++);
           }
diff --git a/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx b/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
index b25466d1abd..5c8af1a4422 100644
--- a/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
+++ b/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
@@ -62,8 +62,8 @@ int ArrayTransposeMatrix(int vtkNotUsed(argc), char *vtkNotUsed(argv)[])
     vtkPrintMatrixFormat(cout, output);
 
     test_expression(output);
-    test_expression(output->GetExtents()[0] == 2);
-    test_expression(output->GetExtents()[1] == 3);
+    test_expression(output->GetExtent(0).GetSize() == 2);
+    test_expression(output->GetExtent(1).GetSize() == 3);
 
     test_expression(output->GetValue(vtkArrayCoordinates(0, 0)) == 0);
     test_expression(output->GetValue(vtkArrayCoordinates(0, 1)) == 2);
diff --git a/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx b/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
index e2af1bcf60c..cfbf4178acd 100644
--- a/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
+++ b/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
@@ -35,7 +35,7 @@
 
 // ----------------------------------------------------------------------
 
-vtkCxxRevisionMacro(vtkAdjacencyMatrixToEdgeTable, "1.5");
+vtkCxxRevisionMacro(vtkAdjacencyMatrixToEdgeTable, "1.6");
 vtkStandardNewMacro(vtkAdjacencyMatrixToEdgeTable);
 
 // ----------------------------------------------------------------------
@@ -127,14 +127,14 @@ int vtkAdjacencyMatrixToEdgeTable::RequestData(
 
   // For each source in the matrix ...
   vtkArrayCoordinates coordinates(0, 0);
-  for(vtkIdType i = 0; i != input_extents[source_dimension]; ++i)
+  for(vtkIdType i = input_extents[source_dimension].GetBegin(); i != input_extents[source_dimension].GetEnd(); ++i)
     {
     coordinates[source_dimension] = i;
 
     // Create a sorted list of source values ...
     typedef vtkstd::multimap<double, vtkIdType, vtkstd::greater<double> > sorted_values_t;
     sorted_values_t sorted_values;
-    for(vtkIdType j = 0; j != input_extents[target_dimension]; ++j)
+    for(vtkIdType j = input_extents[target_dimension].GetBegin(); j != input_extents[target_dimension].GetEnd(); ++j)
       {
       coordinates[target_dimension] = j;
 
@@ -159,7 +159,7 @@ int vtkAdjacencyMatrixToEdgeTable::RequestData(
         }
       }
 
-    double progress = static_cast<double>(i) / static_cast<double>(input_extents[source_dimension]);
+    double progress = static_cast<double>(i - input_extents[source_dimension].GetBegin()) / static_cast<double>(input_extents[source_dimension].GetSize());
     this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
     }
 
diff --git a/Infovis/vtkArrayNorm.cxx b/Infovis/vtkArrayNorm.cxx
index c7fdb18ccdb..19b58842a0c 100644
--- a/Infovis/vtkArrayNorm.cxx
+++ b/Infovis/vtkArrayNorm.cxx
@@ -34,7 +34,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkArrayNorm
 
-vtkCxxRevisionMacro(vtkArrayNorm, "1.6");
+vtkCxxRevisionMacro(vtkArrayNorm, "1.7");
 vtkStandardNewMacro(vtkArrayNorm);
 
 vtkArrayNorm::vtkArrayNorm() :
@@ -112,15 +112,13 @@ int vtkArrayNorm::RequestData(
       throw vtkstd::runtime_error("Dimension must be zero or one.");
     const vtkIdType element_dimension = 1 - vector_dimension;
 
-    const vtkIdType vector_count = input_array->GetExtent(vector_dimension);
-
     // Setup our output ...
     vtkstd::ostringstream array_name;
     array_name << "L" << this->L << "_norm";
     
     vtkDenseArray<double>* const output_array = vtkDenseArray<double>::New();
     output_array->SetName(array_name.str());
-    output_array->Resize(vector_count);
+    output_array->Resize(input_array->GetExtent(vector_dimension));
     output_array->Fill(0.0);
 
     vtkArrayData* const output = vtkArrayData::GetData(outputVector);
@@ -139,7 +137,7 @@ int vtkArrayNorm::RequestData(
       output_array->SetValue(coordinates[vector_dimension], output_array->GetValue(coordinates[vector_dimension]) + pow(input_array->GetValueN(n), this->L));
       }
 
-    for(vtkIdType n = 0; n != vector_count; ++n)
+    for(vtkIdType n = 0; n != output_array->GetNonNullSize(); ++n)
       {
       output_array->SetValueN(n, pow(output_array->GetValueN(n), 1.0 / this->L));
       }
@@ -147,7 +145,7 @@ int vtkArrayNorm::RequestData(
     // Optionally invert the output vector
     if(this->Invert)
       {
-      for(vtkIdType n = 0; n != vector_count; ++n)
+      for(vtkIdType n = 0; n != output_array->GetNonNullSize(); ++n)
         {
         if(output_array->GetValueN(n))
           output_array->SetValueN(n, 1.0 / output_array->GetValueN(n));
diff --git a/Infovis/vtkArrayToTable.cxx b/Infovis/vtkArrayToTable.cxx
index d97d0f03814..1b4584c32c6 100644
--- a/Infovis/vtkArrayToTable.cxx
+++ b/Infovis/vtkArrayToTable.cxx
@@ -47,14 +47,14 @@ static bool ConvertVector(vtkArray* Array, vtkTable* Output)
   if(!array)
     return false;
 
-  const vtkArrayExtents extents = array->GetExtents();
+  const vtkArrayRange extents = array->GetExtent(0);
 
   ColumnT* const column = ColumnT::New();
-  column->SetNumberOfTuples(extents[0]);
+  column->SetNumberOfTuples(extents.GetSize());
   column->SetName(array->GetName());
-  for(vtkIdType i = 0; i != extents[0]; ++i)
+  for(vtkIdType i = extents.GetBegin(); i != extents.GetEnd(); ++i)
     {
-    column->SetValue(i, array->GetValue(i));
+    column->SetValue(i - extents.GetBegin(), array->GetValue(i));
     }
 
   Output->AddColumn(column);
@@ -77,22 +77,22 @@ static bool ConvertMatrix(vtkArray* Array, vtkTable* Output)
   vtkSparseArray<ValueT>* const sparse_array = vtkSparseArray<ValueT>::SafeDownCast(array);
 
   const vtkIdType non_null_count = array->GetNonNullSize();
-  const vtkIdType column_count = array->GetExtents()[1];
-  const vtkIdType row_count = array->GetExtents()[0];
+  const vtkArrayRange columns = array->GetExtent(1);
+  const vtkArrayRange rows = array->GetExtent(0);
 
   vtkstd::vector<ColumnT*> new_columns;
-  for(vtkIdType j = 0; j != column_count; ++j)
+  for(vtkIdType j = columns.GetBegin(); j != columns.GetEnd(); ++j)
     {
     vtkstd::ostringstream column_name;
     column_name << j;
       
     ColumnT* const column = ColumnT::New();
-    column->SetNumberOfTuples(row_count);
+    column->SetNumberOfTuples(rows.GetSize());
     column->SetName(column_name.str().c_str());
 
     if(sparse_array)
       {
-      for(vtkIdType i = 0; i != row_count; ++i)
+      for(vtkIdType i = 0; i != rows.GetSize(); ++i)
         column->SetValue(i, sparse_array->GetNullValue());
       }
 
@@ -106,7 +106,7 @@ static bool ConvertMatrix(vtkArray* Array, vtkTable* Output)
     vtkArrayCoordinates coordinates;
     array->GetCoordinatesN(n, coordinates);
 
-    new_columns[coordinates[1]]->SetValue(coordinates[0], array->GetValueN(n));
+    new_columns[coordinates[1] - columns.GetBegin()]->SetValue(coordinates[0] - rows.GetBegin(), array->GetValueN(n));
     }
 
   return true;
@@ -114,7 +114,7 @@ static bool ConvertMatrix(vtkArray* Array, vtkTable* Output)
 
 // ----------------------------------------------------------------------
 
-vtkCxxRevisionMacro(vtkArrayToTable, "1.7");
+vtkCxxRevisionMacro(vtkArrayToTable, "1.8");
 vtkStandardNewMacro(vtkArrayToTable);
 
 // ----------------------------------------------------------------------
diff --git a/Infovis/vtkBoostRandomSparseArraySource.cxx b/Infovis/vtkBoostRandomSparseArraySource.cxx
index c7d3c7f728b..2cba1631083 100644
--- a/Infovis/vtkBoostRandomSparseArraySource.cxx
+++ b/Infovis/vtkBoostRandomSparseArraySource.cxx
@@ -19,7 +19,6 @@
 
 =========================================================================*/
 
-#include "vtkArrayCoordinateIterator.h"
 #include "vtkBoostRandomSparseArraySource.h"
 #include "vtkInformation.h"
 #include "vtkInformationVector.h"
@@ -31,7 +30,7 @@
 
 // ----------------------------------------------------------------------
 
-vtkCxxRevisionMacro(vtkBoostRandomSparseArraySource, "1.2");
+vtkCxxRevisionMacro(vtkBoostRandomSparseArraySource, "1.3");
 vtkStandardNewMacro(vtkBoostRandomSparseArraySource);
 
 // ----------------------------------------------------------------------
@@ -99,11 +98,10 @@ int vtkBoostRandomSparseArraySource::RequestData(
   vtkSparseArray<double>* const array = vtkSparseArray<double>::New();
   array->Resize(this->Extents);
 
-  vtkSmartPointer<vtkArrayCoordinateIterator> iterator = vtkSmartPointer<vtkArrayCoordinateIterator>::New();
-  iterator->SetExtents(this->Extents);
-  while(iterator->HasNext())
+  vtkArrayCoordinates coordinates;
+  for(vtkIdType n = 0; n != this->Extents.GetSize(); ++n)
     {
-    vtkArrayCoordinates coordinates = iterator->Next();
+    this->Extents.GetRightToLeftCoordinatesN(n, coordinates);
 
     // Although it seems wasteful, we calculate a value for every element in the array
     // so the results stay consistent as the ElementProbability varies
diff --git a/Infovis/vtkDotProductSimilarity.cxx b/Infovis/vtkDotProductSimilarity.cxx
index 9d678e0b4f1..dc58062ab3f 100644
--- a/Infovis/vtkDotProductSimilarity.cxx
+++ b/Infovis/vtkDotProductSimilarity.cxx
@@ -85,7 +85,7 @@ private:
 
 // ----------------------------------------------------------------------
 
-vtkCxxRevisionMacro(vtkDotProductSimilarity, "1.4");
+vtkCxxRevisionMacro(vtkDotProductSimilarity, "1.5");
 vtkStandardNewMacro(vtkDotProductSimilarity);
 
 // ----------------------------------------------------------------------
@@ -145,7 +145,15 @@ int vtkDotProductSimilarity::FillInputPortInformation(int port, vtkInformation*
 
 // ----------------------------------------------------------------------
 
-static double DotProduct(vtkDenseArray<double>* input_a, vtkDenseArray<double>* input_b, const vtkIdType vector_a, const vtkIdType vector_b, const vtkIdType vector_dimension, const vtkIdType component_dimension, const vtkIdType component_count)
+static double DotProduct(
+  vtkDenseArray<double>* input_a,
+  vtkDenseArray<double>* input_b,
+  const vtkIdType vector_a,
+  const vtkIdType vector_b,
+  const vtkIdType vector_dimension,
+  const vtkIdType component_dimension,
+  const vtkArrayRange range_a,
+  const vtkArrayRange range_b)
 {
   vtkArrayCoordinates coordinates_a(0, 0);
   vtkArrayCoordinates coordinates_b(0, 0);
@@ -154,10 +162,10 @@ static double DotProduct(vtkDenseArray<double>* input_a, vtkDenseArray<double>*
   coordinates_b[vector_dimension] = vector_b;
 
   double dot_product = 0.0;
-  for(vtkIdType component = 0; component != component_count; ++component)
+  for(vtkIdType component = 0; component != range_a.GetSize(); ++component)
     {
-    coordinates_a[component_dimension] = component;
-    coordinates_b[component_dimension] = component;
+    coordinates_a[component_dimension] = component + range_a.GetBegin();
+    coordinates_b[component_dimension] = component + range_b.GetBegin();
     dot_product += input_a->GetValue(coordinates_a) * input_b->GetValue(coordinates_b);
     }
   return dot_product;
@@ -203,13 +211,13 @@ int vtkDotProductSimilarity::RequestData(
 
     const vtkIdType component_dimension = 1 - vector_dimension;
 
-    const vtkIdType vector_count_a = input_array_a->GetExtents()[vector_dimension];
-    const vtkIdType component_count_a = input_array_a->GetExtents()[component_dimension];
+    const vtkArrayRange vectors_a = input_array_a->GetExtent(vector_dimension);
+    const vtkArrayRange components_a = input_array_a->GetExtent(component_dimension);
 
-    const vtkIdType vector_count_b = input_array_b ? input_array_b->GetExtents()[vector_dimension] : 0;
-    const vtkIdType component_count_b = input_array_b ? input_array_b->GetExtents()[component_dimension] : 0;
+    const vtkArrayRange vectors_b = input_array_b ? input_array_b->GetExtent(vector_dimension) : vtkArrayRange();
+    const vtkArrayRange components_b = input_array_b ? input_array_b->GetExtent(component_dimension) : vtkArrayRange();
 
-    if(input_array_b && (component_count_a != component_count_b))
+    if(input_array_b && (components_a.GetSize() != components_b.GetSize()))
       throw vtkstd::runtime_error("Input array vector lengths must match.");
 
     // Get output arrays ...
@@ -234,14 +242,14 @@ int vtkDotProductSimilarity::RequestData(
       // Compare the first matrix with the second matrix ...
       if(this->FirstSecond)
         {
-        for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
+        for(vtkIdType vector_a = vectors_a.GetBegin(); vector_a != vectors_a.GetEnd(); ++vector_a)
           {
           similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);
 
-          for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
+          for(vtkIdType vector_b = vectors_b.GetBegin(); vector_b != vectors_b.GetEnd(); ++vector_b)
             {
             // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
-            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_b, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
+            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_b, vector_a, vector_b, vector_dimension, component_dimension, components_a, components_b), vector_b));
             }
             
           for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
@@ -255,14 +263,14 @@ int vtkDotProductSimilarity::RequestData(
       // Compare the second matrix with the first matrix ...
       if(this->SecondFirst)
         {
-        for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
+        for(vtkIdType vector_b = vectors_b.GetBegin(); vector_b != vectors_b.GetEnd(); ++vector_b)
           {
           similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);
 
-          for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
+          for(vtkIdType vector_a = vectors_a.GetBegin(); vector_a != vectors_a.GetEnd(); ++vector_a)
             {
             // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
-            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_b, input_array_a, vector_b, vector_a, vector_dimension, component_dimension, component_count_a), vector_a));
+            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_b, input_array_a, vector_b, vector_a, vector_dimension, component_dimension, components_b, components_a), vector_a));
             }
             
           for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
@@ -277,11 +285,11 @@ int vtkDotProductSimilarity::RequestData(
     // Compare the one matrix with itself ...
     else
       {
-      for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
+      for(vtkIdType vector_a = vectors_a.GetBegin(); vector_a != vectors_a.GetEnd(); ++vector_a)
         {
         similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);
 
-        for(vtkIdType vector_b = 0; vector_b != vector_count_a; ++vector_b)
+        for(vtkIdType vector_b = vectors_a.GetBegin(); vector_b != vectors_a.GetEnd(); ++vector_b)
           {
           if((vector_b > vector_a) && !this->UpperDiagonal)
             continue;
@@ -293,7 +301,7 @@ int vtkDotProductSimilarity::RequestData(
             continue;
 
           // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
-          similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_a, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
+          similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_a, vector_a, vector_b, vector_dimension, component_dimension, components_a, components_a), vector_b));
           }
           
         for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
diff --git a/Infovis/vtkMatricizeArray.cxx b/Infovis/vtkMatricizeArray.cxx
index 3a9b7fac615..e484216d135 100644
--- a/Infovis/vtkMatricizeArray.cxx
+++ b/Infovis/vtkMatricizeArray.cxx
@@ -32,7 +32,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkMatricizeArray
 
-vtkCxxRevisionMacro(vtkMatricizeArray, "1.3");
+vtkCxxRevisionMacro(vtkMatricizeArray, "1.4");
 vtkStandardNewMacro(vtkMatricizeArray);
 
 vtkMatricizeArray::vtkMatricizeArray() :
@@ -82,7 +82,7 @@ int vtkMatricizeArray::RequestData(
   const vtkArrayExtents input_extents = input_array->GetExtents();
   vtkArrayExtents output_extents(0, 0);
   output_extents[0] = input_extents[this->SliceDimension];
-  output_extents[1] = input_extents.GetSize() / input_extents[this->SliceDimension];
+  output_extents[1] = vtkArrayRange(0, input_extents.GetSize() / input_extents[this->SliceDimension].GetSize());
   output_array->Resize(output_extents);
 
   // "Map" every non-null element in the input array to its position in the output array.
@@ -102,7 +102,7 @@ int vtkMatricizeArray::RequestData(
     else
       {
       strides[i] = stride;
-      stride *= input_extents[i];
+      stride *= input_extents[i].GetSize();
       }
     }
     
@@ -118,7 +118,7 @@ int vtkMatricizeArray::RequestData(
     new_coordinates[0] = coordinates[this->SliceDimension];
 
     for(vtkIdType i = 0; i != coordinates.GetDimensions(); ++i)
-      temp[i] = coordinates[i] * strides[i];
+      temp[i] = (coordinates[i] - input_extents[i].GetBegin()) * strides[i];
     new_coordinates[1] = vtkstd::accumulate(temp.begin(), temp.end(), 0);
 
     output_array->AddValue(new_coordinates, input_array->GetValueN(n));
diff --git a/Infovis/vtkNormalizeMatrixVectors.cxx b/Infovis/vtkNormalizeMatrixVectors.cxx
index 67d72d33aad..e95c1ba1af4 100644
--- a/Infovis/vtkNormalizeMatrixVectors.cxx
+++ b/Infovis/vtkNormalizeMatrixVectors.cxx
@@ -31,7 +31,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkNormalizeMatrixVectors
 
-vtkCxxRevisionMacro(vtkNormalizeMatrixVectors, "1.3");
+vtkCxxRevisionMacro(vtkNormalizeMatrixVectors, "1.4");
 vtkStandardNewMacro(vtkNormalizeMatrixVectors);
 
 vtkNormalizeMatrixVectors::vtkNormalizeMatrixVectors() :
@@ -78,22 +78,22 @@ int vtkNormalizeMatrixVectors::RequestData(
 
   vtkTypedArray<double>* const output_array = vtkTypedArray<double>::SafeDownCast(input_array->DeepCopy());
 
-  const vtkIdType vector_count = input_array->GetExtents()[vector_dimension];
+  const vtkArrayRange vectors = input_array->GetExtent(vector_dimension);
   const vtkIdType value_count = input_array->GetNonNullSize();
   
   // Create temporary storage for computed vector weights ...
-  vtkstd::vector<double> weight(vector_count, 0.0);
+  vtkstd::vector<double> weight(vectors.GetSize(), 0.0);
 
   // Store the sum of the squares of each vector value ...
   vtkArrayCoordinates coordinates;
   for(vtkIdType n = 0; n != value_count; ++n)
     {
     output_array->GetCoordinatesN(n, coordinates);
-    weight[coordinates[vector_dimension]] += pow(output_array->GetValueN(n), 2);
+    weight[coordinates[vector_dimension] - vectors.GetBegin()] += pow(output_array->GetValueN(n), 2);
     }
 
   // Convert the sums into weights, avoiding divide-by-zero ...
-  for(vtkIdType i = 0; i != vector_count; ++i)
+  for(vtkIdType i = 0; i != vectors.GetSize(); ++i)
     {
     const double length = sqrt(weight[i]);
     weight[i] = length ? 1.0 / length : 0.0;
@@ -103,7 +103,7 @@ int vtkNormalizeMatrixVectors::RequestData(
   for(vtkIdType n = 0; n != value_count; ++n)
     {
     output_array->GetCoordinatesN(n, coordinates);
-    output_array->SetValueN(n, output_array->GetValueN(n) * weight[coordinates[vector_dimension]]);
+    output_array->SetValueN(n, output_array->GetValueN(n) * weight[coordinates[vector_dimension] - vectors.GetBegin()]);
     }
   
   vtkArrayData* const output = vtkArrayData::GetData(outputVector);
diff --git a/Infovis/vtkTransposeMatrix.cxx b/Infovis/vtkTransposeMatrix.cxx
index 9373c6721cc..5d86f78470f 100644
--- a/Infovis/vtkTransposeMatrix.cxx
+++ b/Infovis/vtkTransposeMatrix.cxx
@@ -31,7 +31,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkTransposeMatrix
 
-vtkCxxRevisionMacro(vtkTransposeMatrix, "1.4");
+vtkCxxRevisionMacro(vtkTransposeMatrix, "1.5");
 vtkStandardNewMacro(vtkTransposeMatrix);
 
 vtkTransposeMatrix::vtkTransposeMatrix()
@@ -108,9 +108,9 @@ int vtkTransposeMatrix::RequestData(
       output_array->SetDimensionLabel(0, input_array2->GetDimensionLabel(1));
       output_array->SetDimensionLabel(1, input_array2->GetDimensionLabel(0));
       
-      for(vtkIdType i = 0; i != input_extents[0]; ++i)
+      for(vtkIdType i = input_extents[0].GetBegin(); i != input_extents[0].GetEnd(); ++i)
         {
-        for(vtkIdType j = 0; j != input_extents[1]; ++j)
+        for(vtkIdType j = input_extents[1].GetBegin(); j != input_extents[1].GetEnd(); ++j)
           {
           output_array->SetValue(
             vtkArrayCoordinates(j, i),
diff --git a/TextAnalysis/Testing/Cxx/TestExtractSelectedSlices.cxx b/TextAnalysis/Testing/Cxx/TestExtractSelectedSlices.cxx
index 9667de234c6..9fe0311a883 100644
--- a/TextAnalysis/Testing/Cxx/TestExtractSelectedSlices.cxx
+++ b/TextAnalysis/Testing/Cxx/TestExtractSelectedSlices.cxx
@@ -125,8 +125,8 @@ int TestExtractSelectedSlices(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
     vtkPrintMatrixFormat(cout, output_frequency_matrix);
     cout << "\n";
 
-    test_expression(output_frequency_matrix->GetExtents()[0] == 4);
-    test_expression(output_frequency_matrix->GetExtents()[1] == 3);
+    test_expression(output_frequency_matrix->GetExtent(0).GetSize() == 4);
+    test_expression(output_frequency_matrix->GetExtent(1).GetSize() == 3);
     test_expression(output_frequency_matrix->GetValue(1, 0) == 1);
     test_expression(output_frequency_matrix->GetValue(2, 1) == 2);
     test_expression(output_frequency_matrix->GetValue(3, 1) == 3);
diff --git a/TextAnalysis/Testing/Cxx/TestMatrixWeighting.cxx b/TextAnalysis/Testing/Cxx/TestMatrixWeighting.cxx
index 0236576e698..73aa2eef135 100644
--- a/TextAnalysis/Testing/Cxx/TestMatrixWeighting.cxx
+++ b/TextAnalysis/Testing/Cxx/TestMatrixWeighting.cxx
@@ -72,14 +72,14 @@ int TestMatrixWeighting(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
     vtkDenseArray<double>* const unity = vtkDenseArray<double>::SafeDownCast(unity_weighting->GetOutput()->GetArray(0));
     vtkDenseArray<double>* const entropy = vtkDenseArray<double>::SafeDownCast(entropy_weighting->GetOutput()->GetArray(0));
 
-    test_expression(unity->GetExtents()[0] == 10);
-    for(int i = 0; i<unity->GetExtents()[0]; i++)
+    test_expression(unity->GetExtent(0).GetSize() == 10);
+    for(int i = unity->GetExtent(0).GetBegin(); i<unity->GetExtent(0).GetEnd(); i++)
       {
       test_expression(int(unity->GetValue(i)) == 1);
       }
 
-    test_expression(entropy->GetExtents()[0]  == 15);
-    for(int i = 0; i<entropy->GetExtents()[0]; i++)
+    test_expression(entropy->GetExtent(0).GetSize()  == 15);
+    for(int i = entropy->GetExtent(0).GetBegin(); i<entropy->GetExtent(0).GetEnd(); i++)
       {
       test_expression(entropy->GetValue(i) < 0.00001);
       }
diff --git a/TextAnalysis/vtkConcatenateArray.cxx b/TextAnalysis/vtkConcatenateArray.cxx
index 5f4b468fe06..290cbd19ae3 100644
--- a/TextAnalysis/vtkConcatenateArray.cxx
+++ b/TextAnalysis/vtkConcatenateArray.cxx
@@ -44,13 +44,13 @@ static void CopyValues(vtkArray* const source, vtkArray* const target, const vtk
     target->CopyValue(source, source_index, target_coordinates);
     }
 
-  offset += source->GetExtents()[dimension];
+  offset += source->GetExtent(dimension).GetSize();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // vtkConcatenateArray
 
-vtkCxxRevisionMacro(vtkConcatenateArray, "1.1");
+vtkCxxRevisionMacro(vtkConcatenateArray, "1.2");
 vtkStandardNewMacro(vtkConcatenateArray);
 
 vtkConcatenateArray::vtkConcatenateArray() :
@@ -112,12 +112,15 @@ int vtkConcatenateArray::RequestData(
       if(i == this->AdjacentDimension)
         continue;
 
-      if(array1->GetExtents()[i] != array2->GetExtents()[i])
+      if(array1->GetExtent(i) != array2->GetExtent(i))
         throw vtkstd::runtime_error("array extent mismatch");
       }
 
     vtkArrayExtents output_extents = array1->GetExtents();
-    output_extents[this->AdjacentDimension] += array2->GetExtents()[this->AdjacentDimension];
+    output_extents[this->AdjacentDimension] =
+      vtkArrayRange(
+        array1->GetExtent(this->AdjacentDimension).GetBegin(),
+        array1->GetExtent(this->AdjacentDimension).GetEnd() + array2->GetExtent(this->AdjacentDimension).GetSize());
 
     vtkArray* const output_array = array1->NewInstance();
     output_array->Resize(output_extents);
diff --git a/TextAnalysis/vtkEntropyMatrixWeighting.cxx b/TextAnalysis/vtkEntropyMatrixWeighting.cxx
index d3dbc749097..adc46d542d5 100644
--- a/TextAnalysis/vtkEntropyMatrixWeighting.cxx
+++ b/TextAnalysis/vtkEntropyMatrixWeighting.cxx
@@ -41,7 +41,7 @@ static inline double log2(double n)
 ///////////////////////////////////////////////////////////////////////////////
 // vtkEntropyMatrixWeighting
 
-vtkCxxRevisionMacro(vtkEntropyMatrixWeighting, "1.1");
+vtkCxxRevisionMacro(vtkEntropyMatrixWeighting, "1.2");
 vtkStandardNewMacro(vtkEntropyMatrixWeighting);
 
 vtkEntropyMatrixWeighting::vtkEntropyMatrixWeighting() :
@@ -94,12 +94,12 @@ int vtkEntropyMatrixWeighting::RequestData(
         throw vtkstd::runtime_error("FeatureDimension out-of-bounds.");
       }
 
-    const vtkIdType feature_count = input_array->GetExtents()[feature_dimension];
-    const vtkIdType object_count = input_array->GetExtents()[object_dimension];
+    const vtkArrayRange features = input_array->GetExtent(feature_dimension);
+    const vtkArrayRange objects = input_array->GetExtent(object_dimension);
 
     // Setup our output ...
     vtkDenseArray<double>* const output_array = vtkDenseArray<double>::New();
-    output_array->Resize(feature_count);
+    output_array->Resize(features);
     output_array->Fill(0.0);
 
     vtkArrayData* const output = vtkArrayData::GetData(outputVector);
@@ -111,10 +111,10 @@ int vtkEntropyMatrixWeighting::RequestData(
     output_array->SetName("entropy_weight");
 
     // Cache log2( number of documents ) ...
-    const double logN = log2(static_cast<double>(object_count));
+    const double logN = log2(static_cast<double>(objects.GetSize()));
 
     // Cache the frequency of each feature across the entire corpus ...
-    vtkstd::vector<double> Fi(feature_count, 0);
+    vtkstd::vector<double> Fi(features.GetSize(), 0);
     vtkArrayCoordinates coordinates;
     const vtkIdType non_null_count = input_array->GetNonNullSize();
     for(vtkIdType n = 0; n != non_null_count; ++n)
@@ -122,7 +122,7 @@ int vtkEntropyMatrixWeighting::RequestData(
       input_array->GetCoordinatesN(n, coordinates);
       const vtkIdType i = coordinates[feature_dimension];
       const double fij = input_array->GetValueN(n);
-      Fi[i] += fij;
+      Fi[i - features.GetBegin()] += fij;
       }
 
     // Compute weights ...
@@ -131,12 +131,12 @@ int vtkEntropyMatrixWeighting::RequestData(
       input_array->GetCoordinatesN(n, coordinates);
       const vtkIdType i = coordinates[feature_dimension];
       const double fij = input_array->GetValueN(n);
-      const double pij = fij / Fi[i];
+      const double pij = fij / Fi[i - features.GetBegin()];
       output_array->SetValue(i, output_array->GetValue(i) + (pij * log2(pij) / logN));
       }
 
     // Add 1 to each weight ...
-    for(vtkIdType i = 0; i != feature_count; ++i)
+    for(vtkIdType i = features.GetBegin(); i != features.GetEnd(); ++i)
       {
       output_array->SetValue(i, output_array->GetValue(i) + 1);
       }
diff --git a/TextAnalysis/vtkExtractSelectedSlices.cxx b/TextAnalysis/vtkExtractSelectedSlices.cxx
index af85803ea23..f7e0c2d9e64 100644
--- a/TextAnalysis/vtkExtractSelectedSlices.cxx
+++ b/TextAnalysis/vtkExtractSelectedSlices.cxx
@@ -37,7 +37,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkExtractSelectedSlices
 
-vtkCxxRevisionMacro(vtkExtractSelectedSlices, "1.1");
+vtkCxxRevisionMacro(vtkExtractSelectedSlices, "1.2");
 vtkStandardNewMacro(vtkExtractSelectedSlices);
 
 vtkExtractSelectedSlices::vtkExtractSelectedSlices() :
@@ -97,7 +97,7 @@ int vtkExtractSelectedSlices::RequestData(
     if(slice_dimension < 0 || slice_dimension >= input_array->GetDimensions())
       throw vtkstd::runtime_error("SliceDimension out-of-range.");
 
-    const vtkIdType slice_extents = input_array->GetExtents()[slice_dimension];
+    const vtkArrayRange slices = input_array->GetExtent(slice_dimension);
 
     vtkSelection* const input_selection = vtkSelection::GetData(inputVector[1]);
     if(!input_selection)
@@ -117,19 +117,19 @@ int vtkExtractSelectedSlices::RequestData(
       throw vtkstd::runtime_error("Missing vtkIdTypeArray selection indices on input port 1.");
 
     // Convert selection indices into a bit-map for constant-time lookups ...
-    vtkstd::vector<bool> selected_slice(slice_extents, false);
+    vtkstd::vector<bool> selected_slice(slices.GetSize(), false);
     for(vtkIdType i = 0; i != input_selection_list->GetNumberOfTuples(); ++i)
       {
       const vtkIdType slice = input_selection_list->GetValue(i);
-      if(slice < 0 || slice >= slice_extents)
+      if(!slices.Contains(slice))
         throw vtkstd::runtime_error("Selected slice out-of-bounds.");
 
-      selected_slice[slice] = true;
+      selected_slice[slice - slices.GetBegin()] = true;
       }
 
     // Create a map from old coordinates to new coordinates for constant-time lookups ...
-    vtkstd::vector<vtkIdType> coordinate_map(slice_extents, 0);
-    for(vtkIdType i = 0, new_coordinate = 0; i != slice_extents; ++i)
+    vtkstd::vector<vtkIdType> coordinate_map(slices.GetSize(), 0);
+    for(vtkIdType i = 0, new_coordinate = 0; i != slices.GetSize(); ++i)
       {
       coordinate_map[i] = new_coordinate;
       if(selected_slice[i])
@@ -153,17 +153,15 @@ int vtkExtractSelectedSlices::RequestData(
     for(vtkIdType n = 0; n != non_null_count; ++n)
       {
       input_array->GetCoordinatesN(n, coordinates);
-      if(!selected_slice[coordinates[slice_dimension]])
+      if(!selected_slice[coordinates[slice_dimension] - slices.GetBegin()])
         continue;
 
-      coordinates[slice_dimension] = coordinate_map[coordinates[slice_dimension]];
+      coordinates[slice_dimension] = coordinate_map[coordinates[slice_dimension] - slices.GetBegin()];
       output_array->AddValue(coordinates, input_array->GetValueN(n));
       }
 
     // Reset the array extents ...
-    vtkArrayExtents extents = input_array->GetExtents();
-    extents[slice_dimension] = coordinate_map.size() ? coordinate_map.back() + 1 : 0;
-    output_array->SetExtents(extents);
+    output_array->SetExtentsFromContents();
 
     return 1;
     } 
diff --git a/TextAnalysis/vtkPointwiseMutualInformation.cxx b/TextAnalysis/vtkPointwiseMutualInformation.cxx
index e6df279d39f..aaff22efadb 100644
--- a/TextAnalysis/vtkPointwiseMutualInformation.cxx
+++ b/TextAnalysis/vtkPointwiseMutualInformation.cxx
@@ -35,7 +35,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkPointwiseMutualInformation
 
-vtkCxxRevisionMacro(vtkPointwiseMutualInformation, "1.2");
+vtkCxxRevisionMacro(vtkPointwiseMutualInformation, "1.3");
 vtkStandardNewMacro(vtkPointwiseMutualInformation);
 
 vtkPointwiseMutualInformation::vtkPointwiseMutualInformation()
@@ -92,7 +92,7 @@ int vtkPointwiseMutualInformation::RequestData(
     vtkstd::vector<vtkstd::vector<double> > dimension_sums(dimension_count);
     for(vtkIdType i = 0; i != dimension_count; ++i)
       {
-      dimension_sums[i].resize(input_array->GetExtents()[i], 0.0);
+      dimension_sums[i].resize(input_array->GetExtent(i).GetSize(), 0.0);
       }
 
     vtkArrayCoordinates coordinates;
diff --git a/TextAnalysis/vtkScaleDimension.cxx b/TextAnalysis/vtkScaleDimension.cxx
index bc17a389945..626db58f181 100644
--- a/TextAnalysis/vtkScaleDimension.cxx
+++ b/TextAnalysis/vtkScaleDimension.cxx
@@ -32,7 +32,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkScaleDimension
 
-vtkCxxRevisionMacro(vtkScaleDimension, "1.1");
+vtkCxxRevisionMacro(vtkScaleDimension, "1.2");
 vtkStandardNewMacro(vtkScaleDimension);
 
 vtkScaleDimension::vtkScaleDimension() :
@@ -99,11 +99,11 @@ int vtkScaleDimension::RequestData(
     if(scale_vector->GetDimensions() != 1)
       throw vtkstd::runtime_error("Vector input must have exactly one dimension.");
 
-    if(scale_vector->GetExtents()[0] != input_array->GetExtents()[this->Dimension])
+    if(scale_vector->GetExtent(0).GetSize() != input_array->GetExtent(this->Dimension).GetSize())
       throw vtkstd::runtime_error("Vector extents must match Array extents along the scale dimension.");
 
     // Optionally invert the input vector
-    vtkstd::vector<double> scale(scale_vector->GetStorage(), scale_vector->GetStorage() + scale_vector->GetExtents()[0]);
+    vtkstd::vector<double> scale(scale_vector->GetStorage(), scale_vector->GetStorage() + scale_vector->GetExtent(0).GetSize());
     if(this->Invert)
       {
       for(unsigned int i = 0; i != scale.size(); ++i)
@@ -122,11 +122,12 @@ int vtkScaleDimension::RequestData(
 
     // Multiply each element of our output array by the corresponding element in the scale vector.
     vtkArrayCoordinates coordinates;
+    const vtkIdType offset = output_array->GetExtent(this->Dimension).GetBegin();
     const vtkIdType element_count = output_array->GetNonNullSize();
     for(vtkIdType n = 0; n != element_count; ++n)
       {
       output_array->GetCoordinatesN(n, coordinates);
-      output_array->SetValueN(n, output_array->GetValueN(n) * scale[coordinates[this->Dimension]]);
+      output_array->SetValueN(n, output_array->GetValueN(n) * scale[coordinates[this->Dimension] - offset]);
 
       if( n % 100 == 0 )
         {
diff --git a/TextAnalysis/vtkSelectArraySlices.cxx b/TextAnalysis/vtkSelectArraySlices.cxx
index 89b1bfcf148..e6cbd392948 100644
--- a/TextAnalysis/vtkSelectArraySlices.cxx
+++ b/TextAnalysis/vtkSelectArraySlices.cxx
@@ -38,7 +38,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkSelectArraySlices
 
-vtkCxxRevisionMacro(vtkSelectArraySlices, "1.1");
+vtkCxxRevisionMacro(vtkSelectArraySlices, "1.2");
 vtkStandardNewMacro(vtkSelectArraySlices);
 
 vtkSelectArraySlices::vtkSelectArraySlices() :
@@ -114,22 +114,22 @@ int vtkSelectArraySlices::RequestData(
     if(dimension < 0 || dimension >= input_array->GetDimensions())
       throw vtkstd::runtime_error("SliceDimension out-of-range.");
 
-    const vtkIdType dimension_extents = input_array->GetExtents()[dimension];
+    const vtkArrayRange dimension_extents = input_array->GetExtent(dimension);
 
-    // Special-case: if the dimension extents are zero, there's nothing to select and we're done.
-    if(0 == dimension_extents)
+    // Special-case: if the dimension extents are empty, there's nothing to select and we're done.
+    if(0 == dimension_extents.GetSize())
       return 1;
     
-    const vtkIdType slice_extents = input_array->GetExtents().GetSize() / dimension_extents;
+    const vtkIdType slice_extents = input_array->GetExtents().GetSize() / dimension_extents.GetSize();
     const vtkIdType non_null_count = input_array->GetNonNullSize();
 
     // Compute the number of non-zero values in each slice along the target dimension ...
     vtkArrayCoordinates coordinates;
-    vtkstd::vector<vtkIdType> slice_counts(dimension_extents, 0);
+    vtkstd::vector<vtkIdType> slice_counts(dimension_extents.GetSize(), 0);
     for(vtkIdType n = 0; n != non_null_count; ++n)
       {
       input_array->GetCoordinatesN(n, coordinates);
-      slice_counts[coordinates[dimension]] += (input_array->GetValueN(n) ? 1 : 0);
+      slice_counts[coordinates[dimension] - dimension_extents.GetBegin()] += (input_array->GetValueN(n) ? 1 : 0);
       }
 
     // Select / deselect each slice based on whether its count meets our criteria ...
@@ -138,7 +138,7 @@ int vtkSelectArraySlices::RequestData(
     const vtkIdType minimum_percent_count = static_cast<vtkIdType>(this->MinimumPercent * slice_extents);
     const vtkIdType maximum_percent_count = static_cast<vtkIdType>(this->MaximumPercent * slice_extents);
 
-    for(vtkIdType i = 0; i != dimension_extents; ++i)
+    for(vtkIdType i = 0; i != dimension_extents.GetSize(); ++i)
       {
       const vtkIdType count = slice_counts[i];
       if(count >= minimum_count && count >= minimum_percent_count && count <= maximum_count && count <= maximum_percent_count)
diff --git a/TextAnalysis/vtkUnityMatrixWeighting.cxx b/TextAnalysis/vtkUnityMatrixWeighting.cxx
index 4e03a8d2cdc..6d772f4fb5a 100644
--- a/TextAnalysis/vtkUnityMatrixWeighting.cxx
+++ b/TextAnalysis/vtkUnityMatrixWeighting.cxx
@@ -32,7 +32,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // vtkUnityMatrixWeighting
 
-vtkCxxRevisionMacro(vtkUnityMatrixWeighting, "1.1");
+vtkCxxRevisionMacro(vtkUnityMatrixWeighting, "1.2");
 vtkStandardNewMacro(vtkUnityMatrixWeighting);
 
 vtkUnityMatrixWeighting::vtkUnityMatrixWeighting() :
@@ -82,11 +82,11 @@ int vtkUnityMatrixWeighting::RequestData(
         throw vtkstd::runtime_error("FeatureDimension out-of-bounds.");
       }
 
-    const vtkIdType feature_count = input_array->GetExtents()[feature_dimension];
+    const vtkArrayRange features = input_array->GetExtent(feature_dimension);
 
     // Setup our output ...
     vtkDenseArray<double>* const output_array = vtkDenseArray<double>::New();
-    output_array->Resize(feature_count);
+    output_array->Resize(features);
     output_array->Fill(1.0);
     output_array->SetName("trivial_term_weight");
 
-- 
GitLab