diff --git a/Filtering/vtkAlgorithm.cxx b/Filtering/vtkAlgorithm.cxx
index 4e80a73f5fcb29faee8de44b075f3a6c2bac0336..5721a60f8360dc8e37fcd75113e905f4f26c7b79 100644
--- a/Filtering/vtkAlgorithm.cxx
+++ b/Filtering/vtkAlgorithm.cxx
@@ -36,11 +36,12 @@
 #include "vtkPointData.h"
 #include "vtkSmartPointer.h"
 #include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkTable.h"
 
 #include <vtkstd/set>
 #include <vtkstd/vector>
 
-vtkCxxRevisionMacro(vtkAlgorithm, "1.43");
+vtkCxxRevisionMacro(vtkAlgorithm, "1.44");
 vtkStandardNewMacro(vtkAlgorithm);
 
 vtkCxxSetObjectMacro(vtkAlgorithm,Information,vtkInformation);
@@ -382,6 +383,18 @@ vtkAbstractArray* vtkAlgorithm::GetInputAbstractArrayToProcess(
       return fd->GetAbstractArray(name);
       }
     
+    if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_ROWS)
+      {
+      vtkTable *inputT = vtkTable::SafeDownCast(input);
+      if (!inputT)
+        {
+        vtkErrorMacro("Attempt to get row data from a non-table");
+        return NULL;
+        }
+      vtkFieldData *fd = inputT->GetRowData();
+      return fd->GetAbstractArray(name);
+      }
+
     if (fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_VERTICES ||
         fieldAssoc == vtkDataObject::FIELD_ASSOCIATION_EDGES)
       {
diff --git a/Filtering/vtkDataObject.cxx b/Filtering/vtkDataObject.cxx
index dcae5196afc675c28592eb47c4a83ccd3f4c0e39..24f22b2770458a00d1009f220b2333d3156edc98 100644
--- a/Filtering/vtkDataObject.cxx
+++ b/Filtering/vtkDataObject.cxx
@@ -36,7 +36,7 @@ PURPOSE.  See the above copyright notice for more information.
 #include "vtkInformationVector.h"
 #include "vtkDataSetAttributes.h"
 
-vtkCxxRevisionMacro(vtkDataObject, "1.40");
+vtkCxxRevisionMacro(vtkDataObject, "1.41");
 vtkStandardNewMacro(vtkDataObject);
 
 vtkCxxSetObjectMacro(vtkDataObject,Information,vtkInformation);
@@ -107,7 +107,8 @@ const char vtkDataObject
   "vtkDataObject::FIELD_ASSOCIATION_NONE",
   "vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS",
   "vtkDataObject::FIELD_ASSOCIATION_VERTICES",
-  "vtkDataObject::FIELD_ASSOCIATION_EDGES"
+  "vtkDataObject::FIELD_ASSOCIATION_EDGES",
+  "vtkDataObject::FIELD_ASSOCIATION_ROWS"
 };
 
 //----------------------------------------------------------------------------
diff --git a/Filtering/vtkDataObject.h b/Filtering/vtkDataObject.h
index 5f4f8f99fa35837d34e619059c9f2226780f7810..ae1fc2b05674d23bcdbe0f921e383ee5bab9ab93 100644
--- a/Filtering/vtkDataObject.h
+++ b/Filtering/vtkDataObject.h
@@ -426,6 +426,7 @@ public:
     FIELD_ASSOCIATION_POINTS_THEN_CELLS,
     FIELD_ASSOCIATION_VERTICES,
     FIELD_ASSOCIATION_EDGES,
+    FIELD_ASSOCIATION_ROWS,
     NUMBER_OF_ASSOCIATIONS
   };
   //ETX
diff --git a/Filtering/vtkDemandDrivenPipeline.cxx b/Filtering/vtkDemandDrivenPipeline.cxx
index 064c472c33363e33da64925c2bb2886f8f6d4697..9b8941a6fc1e97292f180bb3d5b7b934be658c91 100644
--- a/Filtering/vtkDemandDrivenPipeline.cxx
+++ b/Filtering/vtkDemandDrivenPipeline.cxx
@@ -37,7 +37,7 @@
 
 #include <vtkstd/vector>
 
-vtkCxxRevisionMacro(vtkDemandDrivenPipeline, "1.57");
+vtkCxxRevisionMacro(vtkDemandDrivenPipeline, "1.58");
 vtkStandardNewMacro(vtkDemandDrivenPipeline);
 
 vtkInformationKeyMacro(vtkDemandDrivenPipeline, DATA_NOT_GENERATED, Integer);
@@ -550,10 +550,7 @@ void vtkDemandDrivenPipeline::ExecuteDataStart(vtkInformation* request,
         {
         vtkInformation* outInfo = outputs->GetInformationObject(i);
         vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
-        // We want to pass the field data unless it is a table.
-        // Since a table's data is stored in the field data, we want
-        // table algorithms to start with an empty field data.
-        if(output && !output->IsA("vtkTable"))
+        if(output)
           {
           output->GetFieldData()->PassData(input->GetFieldData());
           }
diff --git a/Filtering/vtkSelection.h b/Filtering/vtkSelection.h
index f45b10abad7fdc64440dcad33cd299ba7c989288..96d10feb94fad9ce0a32e82d05983c0fbcc76fdb 100644
--- a/Filtering/vtkSelection.h
+++ b/Filtering/vtkSelection.h
@@ -211,7 +211,8 @@ public:
     POINT,
     FIELD,
     VERTEX,
-    EDGE
+    EDGE,
+    ROW
   };
 //ETX
   
diff --git a/Filtering/vtkTable.cxx b/Filtering/vtkTable.cxx
index 3228d9ad5565ebb452b325d1041205d85ce03daf..818c0f40ee3a86ff5bf27fad2a7fbfb61c78513e 100644
--- a/Filtering/vtkTable.cxx
+++ b/Filtering/vtkTable.cxx
@@ -24,7 +24,6 @@
 #include "vtkAbstractArray.h"
 #include "vtkDataArray.h"
 #include "vtkDataSetAttributes.h"
-#include "vtkFieldData.h"
 #include "vtkInformation.h"
 #include "vtkInformationVector.h"
 #include "vtkObjectFactory.h"
@@ -35,64 +34,61 @@
 // Standard functions
 //
 
-vtkCxxRevisionMacro(vtkTable, "1.13");
+vtkCxxRevisionMacro(vtkTable, "1.14");
 vtkStandardNewMacro(vtkTable);
+vtkCxxSetObjectMacro(vtkTable, RowData, vtkDataSetAttributes);
 
 //----------------------------------------------------------------------------
-
 vtkTable::vtkTable()
 {
-  this->Rows = 0;
   this->RowArray = vtkVariantArray::New();
+  this->RowData = vtkDataSetAttributes::New();
 
   this->Information->Set(vtkDataObject::DATA_EXTENT_TYPE(), VTK_PIECES_EXTENT);
   this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
   this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 1);
   this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
-
-  // Use vtkDataSetAttributes instance as the field data.
-  vtkDataSetAttributes* dsa = vtkDataSetAttributes::New();
-  this->SetFieldData(dsa);
-  dsa->Delete();
 }
 
 //----------------------------------------------------------------------------
-
 vtkTable::~vtkTable()
 {
-  this->RowArray->Delete();
+  if (this->RowArray)
+    {
+    this->RowArray->Delete();
+    }
+  if (this->RowData)
+    {
+    this->RowData->Delete();
+    }
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::PrintSelf(ostream &os, vtkIndent indent)
 {
   vtkDataObject::PrintSelf(os, indent);
-  os << indent << "Number Of Rows: " << this->Rows << endl;
+  os << indent << "RowData: " << (this->RowData ? "" : "(none)") << endl;
+  if (this->RowData)
+    {
+    this->RowData->PrintSelf(os, indent.GetNextIndent());
+    }
 }
 
 //----------------------------------------------------------------------------
-
-void vtkTable::SetFieldData(vtkFieldData* data)
+void vtkTable::Initialize()
 {
-  // Set the Rows field to the appropriate value
-  if (data != NULL && data->GetNumberOfArrays() > 0)
-    {
-    this->Rows = data->GetAbstractArray(0)->GetNumberOfTuples();
-    }
-  else
+  this->Superclass::Initialize();
+  if (this->RowData)
     {
-    this->Rows = 0;
+    this->RowData->Initialize();
     }
-  this->Superclass::SetFieldData(data);
 }
 
 //----------------------------------------------------------------------------
-
-void vtkTable::Initialize()
+unsigned long vtkTable::GetActualMemorySize()
 {
-  this->Superclass::Initialize();
-  this->Rows = 0;
+  return this->RowData->GetActualMemorySize() +
+         this->Superclass::GetActualMemorySize();
 }
 
 //
@@ -100,55 +96,61 @@ void vtkTable::Initialize()
 //
 
 //----------------------------------------------------------------------------
-
 vtkIdType vtkTable::GetNumberOfRows()
 {
-  return this->Rows;
+  if (this->GetNumberOfColumns() > 0)
+    {
+    return this->GetColumn(0)->GetNumberOfTuples();
+    }
+  return 0;
 }
 
 //----------------------------------------------------------------------------
-
 vtkVariantArray* vtkTable::GetRow(vtkIdType row)
 {
-  this->RowArray->SetNumberOfTuples(0);
-  for (int i = 0; i < this->FieldData->GetNumberOfArrays(); i++)
+  vtkIdType ncol = this->GetNumberOfColumns();
+  this->RowArray->SetNumberOfTuples(ncol);
+  for (vtkIdType i = 0; i < ncol; i++)
     {
-    this->RowArray->InsertNextValue(this->GetValue(row, i));
+    this->RowArray->SetValue(i, this->GetValue(row, i));
     }
   return this->RowArray;
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::GetRow(vtkIdType row, vtkVariantArray *values)
 {
-  values->SetNumberOfTuples(0);
-  for (int i = 0; i < this->FieldData->GetNumberOfArrays(); i++)
+  vtkIdType ncol = this->GetNumberOfColumns();
+  values->SetNumberOfTuples(ncol);
+  for (vtkIdType i = 0; i < ncol; i++)
     {
-    values->InsertNextValue(this->GetValue(row, i));
+    values->SetValue(i, this->GetValue(row, i));
     }
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::SetRow(vtkIdType row, vtkVariantArray *values)
 {
-  for (int i = 0; i < this->GetNumberOfColumns(); i++)
+  vtkIdType ncol = this->GetNumberOfColumns();
+  if (values->GetNumberOfTuples() != ncol)
+    {
+    vtkErrorMacro(<< "Incorrect number of tuples in SetRow");
+    }
+  for (vtkIdType i = 0; i < ncol; i++)
     {
     this->SetValue(row, i, values->GetValue(i));
     }
 }
 
 //----------------------------------------------------------------------------
-
 vtkIdType vtkTable::InsertNextBlankRow()
 {
-  int n = this->FieldData->GetNumberOfArrays();
-  for (int i = 0; i < n; i++)
+  vtkIdType ncol = this->GetNumberOfColumns();
+  for (vtkIdType i = 0; i < ncol; i++)
     {
-    vtkAbstractArray* arr = this->FieldData->GetAbstractArray(i);
+    vtkAbstractArray* arr = this->GetColumn(i);
     int comps = arr->GetNumberOfComponents();
-    if (arr->IsA("vtkDataArray"))
+    if (vtkDataArray::SafeDownCast(arr))
       {
       vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
       double* tuple = new double[comps];
@@ -159,7 +161,7 @@ vtkIdType vtkTable::InsertNextBlankRow()
       data->InsertNextTuple(tuple);
       delete[] tuple;
       }
-    else if (arr->IsA("vtkStringArray"))
+    else if (vtkStringArray::SafeDownCast(arr))
       {
       vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
       for (int j = 0; j < comps; j++)
@@ -167,7 +169,7 @@ vtkIdType vtkTable::InsertNextBlankRow()
         data->InsertNextValue(vtkStdString(""));
         }
       }
-    else if (arr->IsA("vtkVariantArray"))
+    else if (vtkVariantArray::SafeDownCast(arr))
       {
       vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
       for (int j = 0; j < comps; j++)
@@ -175,17 +177,24 @@ vtkIdType vtkTable::InsertNextBlankRow()
         data->InsertNextValue(vtkVariant());
         }
       }
+    else
+      {
+      vtkErrorMacro(<< "Unsupported array type for InsertNextBlankRow");
+      }
     }
-  this->Rows++;
-  return this->Rows - 1;
+  return this->GetNumberOfRows() - 1;
 }
 
 //----------------------------------------------------------------------------
-
 vtkIdType vtkTable::InsertNextRow(vtkVariantArray* values)
 {
+  vtkIdType ncol = this->GetNumberOfColumns();
+  if (values->GetNumberOfTuples() != ncol)
+    {
+    vtkErrorMacro(<< "Incorrect number of tuples in SetRow");
+    }
   vtkIdType row = this->InsertNextBlankRow();
-  for (int i = 0; i < this->GetNumberOfColumns(); i++)
+  for (vtkIdType i = 0; i < ncol; i++)
     {
     this->SetValue(row, i, values->GetValue(i));
     }
@@ -193,20 +202,19 @@ vtkIdType vtkTable::InsertNextRow(vtkVariantArray* values)
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::RemoveRow(vtkIdType row)
 {
-  int n = this->FieldData->GetNumberOfArrays();
-  for (int i = 0; i < n; i++)
+  vtkIdType ncol = this->GetNumberOfColumns();
+  for (vtkIdType i = 0; i < ncol; i++)
     {
-    vtkAbstractArray* arr = this->FieldData->GetAbstractArray(i);
+    vtkAbstractArray* arr = this->GetColumn(i);
     int comps = arr->GetNumberOfComponents();
-    if (arr->IsA("vtkDataArray"))
+    if (vtkDataArray::SafeDownCast(arr))
       {
       vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
       data->RemoveTuple(row);
       }
-    else if (arr->IsA("vtkStringArray"))
+    else if (vtkStringArray::SafeDownCast(arr))
       {
       // Manually move all elements past the index back one place.
       vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
@@ -216,7 +224,7 @@ void vtkTable::RemoveRow(vtkIdType row)
         }
       data->Resize(data->GetNumberOfTuples() - 1);
       }
-    else if (arr->IsA("vtkVariantArray"))
+    else if (vtkVariantArray::SafeDownCast(arr))
       {
       // Manually move all elements past the index back one place.
       vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
@@ -227,7 +235,6 @@ void vtkTable::RemoveRow(vtkIdType row)
       data->Resize(data->GetNumberOfTuples() - 1);
       }
     }
-  this->Rows--;
 }
 
 //
@@ -235,69 +242,56 @@ void vtkTable::RemoveRow(vtkIdType row)
 //
 
 //----------------------------------------------------------------------------
-
 vtkIdType vtkTable::GetNumberOfColumns()
 {
-  return this->FieldData->GetNumberOfArrays();
+  return this->RowData->GetNumberOfArrays();
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::AddColumn(vtkAbstractArray* arr)
 {
-  if (this->FieldData->GetNumberOfArrays() == 0)
+  if (this->GetNumberOfColumns() > 0 &&
+      arr->GetNumberOfTuples() != this->GetNumberOfRows())
     {
-    this->FieldData->AddArray(arr);
-    this->Rows = arr->GetNumberOfTuples();
-    }
-  else
-    {
-    if (arr->GetNumberOfTuples() != this->Rows)
-      {
-      vtkErrorMacro(<< "Column \"" << arr->GetName() << "\" must have " 
-        << this->Rows << " rows, but has " << arr->GetNumberOfTuples() << ".");
-      return;
-      }
-    this->FieldData->AddArray(arr);
+    vtkErrorMacro(<< "Column \"" << arr->GetName() << "\" must have " 
+      << this->GetNumberOfRows() << " rows, but has "
+      << arr->GetNumberOfTuples() << ".");
+    return;
     }
+  this->RowData->AddArray(arr);
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::RemoveColumnByName(const char* name)
 {
-  this->FieldData->RemoveArray(name);
+  this->RowData->RemoveArray(name);
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::RemoveColumn(vtkIdType col)
 {
   int column = static_cast<int>(col);
-  this->FieldData->RemoveArray(this->FieldData->GetArrayName(column));
+  this->RowData->RemoveArray(this->RowData->GetArrayName(column));
 }
 
 //----------------------------------------------------------------------------
-
 const char* vtkTable::GetColumnName(vtkIdType col)
 {
   int column = static_cast<int>(col);
-  return this->FieldData->GetArrayName(column);
+  return this->RowData->GetArrayName(column);
 }
 
 //----------------------------------------------------------------------------
-
 vtkAbstractArray* vtkTable::GetColumnByName(const char* name)
 {
-  return this->FieldData->GetAbstractArray(name);
+  return this->RowData->GetAbstractArray(name);
 }
 
 //----------------------------------------------------------------------------
-
 vtkAbstractArray* vtkTable::GetColumn(vtkIdType col)
 {
   int column = static_cast<int>(col);
-  return this->FieldData->GetAbstractArray(column);
+  return this->RowData->GetAbstractArray(column);
 }
 
 //
@@ -305,7 +299,6 @@ vtkAbstractArray* vtkTable::GetColumn(vtkIdType col)
 //
 
 //----------------------------------------------------------------------------
-
 void vtkTable::SetValue(vtkIdType row, vtkIdType col, vtkVariant value)
 {
   int column = static_cast<int>(col);
@@ -313,12 +306,16 @@ void vtkTable::SetValue(vtkIdType row, vtkIdType col, vtkVariant value)
 }
 
 //----------------------------------------------------------------------------
-
 void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
 {
   vtkAbstractArray* arr = this->GetColumnByName(col);
+  if (!arr)
+    {
+    vtkErrorMacro(<< "Could not find column named " << col);
+    return;
+    }
   int comps = arr->GetNumberOfComponents();
-  if (arr->IsA("vtkDataArray"))
+  if (vtkDataArray::SafeDownCast(arr))
     {
     vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
     if (comps == 1)
@@ -327,7 +324,8 @@ void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
       }
     else
       {
-      if (value.IsArray() && value.ToArray()->IsA("vtkDataArray") && value.ToArray()->GetNumberOfComponents() == comps)
+      if (value.IsArray() && vtkDataArray::SafeDownCast(value.ToArray()) &&
+          value.ToArray()->GetNumberOfComponents() == comps)
         {
         data->SetTuple(row, vtkDataArray::SafeDownCast(value.ToArray())->GetTuple(0));
         }
@@ -338,7 +336,7 @@ void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
         }
       }
     }
-  else if (arr->IsA("vtkStringArray"))
+  else if (vtkStringArray::SafeDownCast(arr))
     {
     vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
     if (comps == 1)
@@ -347,7 +345,8 @@ void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
       }
     else
       {
-      if (value.IsArray() && value.ToArray()->IsA("vtkStringArray") && value.ToArray()->GetNumberOfComponents() == comps)
+      if (value.IsArray() && vtkStringArray::SafeDownCast(value.ToArray()) &&
+          value.ToArray()->GetNumberOfComponents() == comps)
         {
         data->SetTuple(row, 0, vtkStringArray::SafeDownCast(value.ToArray()));
         }
@@ -358,7 +357,7 @@ void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
         }
       }
     }
-  else if (arr->IsA("vtkVariantArray"))
+  else if (vtkVariantArray::SafeDownCast(arr))
     {
     vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
     if (comps == 1)
@@ -381,16 +380,13 @@ void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
 }
 
 //----------------------------------------------------------------------------
-
 vtkVariant vtkTable::GetValue(vtkIdType row, vtkIdType col)
 {
   int column = static_cast<int>(col);
   return this->GetValueByName(row, this->GetColumnName(column));
 }
 
-
 //----------------------------------------------------------------------------
-
 template <typename iterT>
 vtkVariant vtkTableGetVariantValue(iterT* it, vtkIdType row)
 {
@@ -398,7 +394,6 @@ vtkVariant vtkTableGetVariantValue(iterT* it, vtkIdType row)
 }
 
 //----------------------------------------------------------------------------
-
 vtkVariant vtkTable::GetValueByName(vtkIdType row, const char* col)
 {
   vtkAbstractArray* arr = this->GetColumnByName(col);
@@ -408,7 +403,7 @@ vtkVariant vtkTable::GetValueByName(vtkIdType row, const char* col)
     }
 
   int comps = arr->GetNumberOfComponents();
-  if (arr->IsA("vtkDataArray"))
+  if (vtkDataArray::SafeDownCast(arr))
     {
     if (comps == 1)
       {
@@ -434,7 +429,7 @@ vtkVariant vtkTable::GetValueByName(vtkIdType row, const char* col)
       return v;
       }
     }
-  else if (arr->IsA("vtkStringArray"))
+  else if (vtkStringArray::SafeDownCast(arr))
     {
     vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
     if (comps == 1)
@@ -452,7 +447,7 @@ vtkVariant vtkTable::GetValueByName(vtkIdType row, const char* col)
       return v;
       }
     }
-  else if (arr->IsA("vtkVariantArray"))
+  else if (vtkVariantArray::SafeDownCast(arr))
     {
     vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
     if (comps == 1)
@@ -485,12 +480,14 @@ vtkTable* vtkTable::GetData(vtkInformationVector* v, int i)
   return vtkTable::GetData(v->GetInformationObject(i));
 }
 
+//----------------------------------------------------------------------------
 void vtkTable::ShallowCopy(vtkDataObject* src)
 {
-  if(vtkTable* const table = vtkTable::SafeDownCast(src))
+  if (vtkTable* const table = vtkTable::SafeDownCast(src))
     {
-    this->Rows = table->Rows;
+    this->RowData->ShallowCopy(table->RowData);
     }
 
   Superclass::ShallowCopy(src);
 }
+
diff --git a/Filtering/vtkTable.h b/Filtering/vtkTable.h
index 6f4ddbd7c5afb3224b3778806dc21c58d8618704..c61bd3a083abeab09508960e232e40a9db27fbd3 100644
--- a/Filtering/vtkTable.h
+++ b/Filtering/vtkTable.h
@@ -21,16 +21,19 @@
 //
 // .SECTION Description
 // vtkTable is a basic data structure for storing columns of data.
-// Internally, columns are stored in a vtkFieldData structure.
-// However, using the vtkTable API additionally ensures that every column
+// Internally, columns are stored in a vtkDataSetAttributes structure called
+// RowData. However, using the vtkTable API additionally ensures that every column
 // has the same number of entries, and provides row access (using vtkVariantArray)
 // and single entry access (using vtkVariant).
 //
+// The field data inherited from vtkDataObject may be used to store metadata
+// related to the table.
+//
 // .SECTION Caveats
-// You should use the vtkTable API to change the table data.  Performing
-// vtkFieldData operations on the object returned by GetFieldData() may
-// yield unexpected results.  vtkTable does allow the user to set the field
-// data using SetFieldData(); the number of rows in the table is determined
+// You should use the vtkTable API to change the table data. Performing
+// operations on the object returned by GetRowData() may
+// yield unexpected results. vtkTable does allow the user to set the field
+// data using SetRowData(); the number of rows in the table is determined
 // by the number of tuples in the first array (it is assumed that all arrays
 // are the same length).
 //
@@ -47,6 +50,7 @@
 #include "vtkDataObject.h"
 
 class vtkAbstractArray;
+class vtkDataSetAttributes;
 class vtkVariant;
 class vtkVariantArray;
 
@@ -62,8 +66,17 @@ public:
   int GetDataObjectType() {return VTK_TABLE;}
 
   // Description:
-  // Sets the field data for the table.
-  virtual void SetFieldData(vtkFieldData* data);
+  // Return the actual size of the data in kilobytes. This number
+  // is valid only after the pipeline has updated. The memory size
+  // returned is guaranteed to be greater than or equal to the
+  // memory required to represent the data (e.g., extra space in
+  // arrays, etc. are not included in the return value).
+  virtual unsigned long GetActualMemorySize();
+
+  // Description:
+  // Get/Set the main data (columns) of the table.
+  vtkGetObjectMacro(RowData, vtkDataSetAttributes);
+  virtual void SetRowData(vtkDataSetAttributes* data);
 
   //
   // Row functions
@@ -172,12 +185,12 @@ protected:
   ~vtkTable();
 
   // Description:
-  // Holds row information returned by GetRow().
-  vtkVariantArray *RowArray;
+  // Holds the column data of the table.
+  vtkDataSetAttributes* RowData;
 
   // Description:
-  // The number of rows in the table.
-  vtkIdType Rows;
+  // Holds row information returned by GetRow().
+  vtkVariantArray* RowArray;
 
 private:
   vtkTable(const vtkTable&); // Not implemented
diff --git a/GUISupport/Qt/vtkQtListView.cxx b/GUISupport/Qt/vtkQtListView.cxx
index 8cde6b417f432895b69d1880d2020549568f5bce..9c6c7940f6b9ec1d211178aaeb85167865c4fa11 100644
--- a/GUISupport/Qt/vtkQtListView.cxx
+++ b/GUISupport/Qt/vtkQtListView.cxx
@@ -22,11 +22,10 @@
 
 #include <QListView>
 
-#include "vtkTable.h"
 #include "vtkQtTableModelAdapter.h"
 #include "vtkObjectFactory.h"
 
-vtkCxxRevisionMacro(vtkQtListView, "1.2");
+vtkCxxRevisionMacro(vtkQtListView, "1.3");
 vtkStandardNewMacro(vtkQtListView);
 
 //----------------------------------------------------------------------------
diff --git a/GUISupport/Qt/vtkQtTableModelAdapter.cxx b/GUISupport/Qt/vtkQtTableModelAdapter.cxx
index b1660b8a24451253f1368422da62406410eb1625..3a68f05de2f140fbfdac69c8aeb9c20ec783982a 100644
--- a/GUISupport/Qt/vtkQtTableModelAdapter.cxx
+++ b/GUISupport/Qt/vtkQtTableModelAdapter.cxx
@@ -24,7 +24,6 @@
 #include "vtkIdTypeArray.h"
 #include "vtkStdString.h"
 #include "vtkVariant.h"
-#include "vtkFieldData.h"
 
 #include <QIcon>
 #include <QPixmap>
diff --git a/Graphics/vtkConvertSelection.cxx b/Graphics/vtkConvertSelection.cxx
index dbb1fe0463670cbbbc48daeaba41b6ce0bb612d3..ed5a01e38843a4a14bf2d57d513bd7b2faf1ab13 100644
--- a/Graphics/vtkConvertSelection.cxx
+++ b/Graphics/vtkConvertSelection.cxx
@@ -53,7 +53,7 @@
 
 vtkCxxSetObjectMacro(vtkConvertSelection, ArrayNames, vtkStringArray);
 
-vtkCxxRevisionMacro(vtkConvertSelection, "1.18");
+vtkCxxRevisionMacro(vtkConvertSelection, "1.19");
 vtkStandardNewMacro(vtkConvertSelection);
 //----------------------------------------------------------------------------
 vtkConvertSelection::vtkConvertSelection()
@@ -567,6 +567,23 @@ int vtkConvertSelection::Convert(
       return 0;
       }
     }
+  else if (vtkTable::SafeDownCast(data))
+    {
+    if (!input->GetProperties()->Has(vtkSelection::FIELD_TYPE()) ||
+        input->GetFieldType() == vtkSelection::ROW)
+      {
+      dsa = vtkTable::SafeDownCast(data)->GetRowData();
+      }
+    else if (input->GetFieldType() == vtkSelection::FIELD)
+      {
+      fd = data->GetFieldData();
+      }
+    else
+      {
+      vtkErrorMacro("Inappropriate selection type for a vtkTable");
+      return 0;
+      }
+    }
   else
     {
     if (!input->GetProperties()->Has(vtkSelection::FIELD_TYPE()) ||
@@ -646,7 +663,7 @@ int vtkConvertSelection::Convert(
     {
     vtkFieldData* selData = input->GetSelectionData();
     VTK_CREATE(vtkTable, selTable);
-    selTable->SetFieldData(selData);
+    selTable->GetRowData()->ShallowCopy(selData);
     VTK_CREATE(vtkTable, dataTable);
     for (vtkIdType col = 0; col < selTable->GetNumberOfColumns(); col++)
       {
diff --git a/Graphics/vtkSelectionSource.cxx b/Graphics/vtkSelectionSource.cxx
index 800b32e9df69adf6f350b7af43d577f586274677..93d4609836733cc06f877eb797f72f4d1d4da9d8 100644
--- a/Graphics/vtkSelectionSource.cxx
+++ b/Graphics/vtkSelectionSource.cxx
@@ -29,7 +29,7 @@
 #include "vtkstd/vector"
 #include "vtkstd/set"
 
-vtkCxxRevisionMacro(vtkSelectionSource, "1.23");
+vtkCxxRevisionMacro(vtkSelectionSource, "1.24");
 vtkStandardNewMacro(vtkSelectionSource);
 
 class vtkSelectionSourceInternals
@@ -236,6 +236,9 @@ void vtkSelectionSource::PrintSelf(ostream& os, vtkIndent indent)
     case vtkSelection::EDGE:
       os << "EDGE";
       break;
+    case vtkSelection::ROW:
+      os << "ROW";
+      break;
     default:
       os << "UNKNOWN";
     }
diff --git a/IO/vtkDataReader.cxx b/IO/vtkDataReader.cxx
index 4bff92615a860d13e80c5bc0cba5e49d915ca109..4cdb23bb23418def50e943ef7c91ce84cf210011 100644
--- a/IO/vtkDataReader.cxx
+++ b/IO/vtkDataReader.cxx
@@ -36,6 +36,7 @@
 #include "vtkShortArray.h"
 #include "vtkStreamingDemandDrivenPipeline.h"
 #include "vtkStringArray.h"
+#include "vtkTable.h"
 #include "vtkTypeInt64Array.h"
 #include "vtkUnsignedCharArray.h"
 #include "vtkUnsignedIntArray.h"
@@ -60,7 +61,7 @@
 // so it would be nice to put this in a common file.
 static int my_getline(istream& stream, vtkStdString &output, char delim='\n');
 
-vtkCxxRevisionMacro(vtkDataReader, "1.153");
+vtkCxxRevisionMacro(vtkDataReader, "1.154");
 vtkStandardNewMacro(vtkDataReader);
 
 vtkCxxSetObjectMacro(vtkDataReader, InputArray, vtkCharArray);
@@ -1211,6 +1212,136 @@ int vtkDataReader::ReadEdgeData(vtkGraph *g, int numEdges)
   return 1;
 }
 
+// Read the row data of a vtk data file.
+int vtkDataReader::ReadRowData(vtkTable *t, int numEdges)
+{
+  char line[256];
+  vtkDataSetAttributes *a=t->GetRowData();
+
+  vtkDebugMacro(<< "Reading vtk row data");
+    
+  //
+  // Read keywords until end-of-file
+  //
+  while (this->ReadString(line))
+    {
+    //
+    // read scalar data
+    //
+    if ( ! strncmp(this->LowerCase(line), "scalars", 7) )
+      {
+      if ( ! this->ReadScalarData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read vector data
+    //
+    else if ( ! strncmp(line, "vectors", 7) )
+      {
+      if ( ! this->ReadVectorData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read 3x3 tensor data
+    //
+    else if ( ! strncmp(line, "tensors", 7) )
+      {
+      if ( ! this->ReadTensorData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read normals data
+    //
+    else if ( ! strncmp(line, "normals", 7) )
+      {
+      if ( ! this->ReadNormalData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read texture coordinates data
+    //
+    else if ( ! strncmp(line, "texture_coordinates", 19) )
+      {
+      if ( ! this->ReadTCoordsData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read the global id data
+    //
+    else if ( ! strncmp(line, "global_ids", 10) )
+      {
+      if ( ! this->ReadGlobalIds(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read the pedigree id data
+    //
+    else if ( ! strncmp(line, "pedigree_ids", 10) )
+      {
+      if ( ! this->ReadPedigreeIds(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read color scalars data
+    //
+    else if ( ! strncmp(line, "color_scalars", 13) )
+      {
+      if ( ! this->ReadCoScalarData(a, numEdges) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read lookup table. Associate with scalar data.
+    //
+    else if ( ! strncmp(line, "lookup_table", 12) )
+      {
+      if ( ! this->ReadLutData(a) )
+        {
+        return 0;
+        }
+      }
+    //
+    // read field of data
+    //
+    else if ( ! strncmp(line, "field", 5) )
+      {
+      vtkFieldData *f;
+      if ( ! (f=this->ReadFieldData()) )
+        {
+        return 0;
+        }
+      for(int i=0; i<f->GetNumberOfArrays(); i++)
+        {
+        a->AddArray(f->GetAbstractArray(i));
+        }
+      f->Delete();
+      }
+    else
+      {
+      vtkErrorMacro(<< "Unsupported row attribute type: " << line 
+                    << " for file: " << (this->FileName?this->FileName:"(Null FileName)"));
+      return 0;
+      }
+    }
+
+  return 1;
+}
+
 // General templated function to read data of various types.
 template <class T>
 int vtkReadBinaryData(istream *IS, T *data, int numTuples, int numComp)
diff --git a/IO/vtkDataReader.h b/IO/vtkDataReader.h
index a68276f6e20eec25ffb91f17e8230c0b8944813f..664c2f677dec9a083ae60cf2d884ef68473de5f2 100644
--- a/IO/vtkDataReader.h
+++ b/IO/vtkDataReader.h
@@ -39,6 +39,7 @@ class vtkFieldData;
 class vtkGraph;
 class vtkPointSet;
 class vtkRectilinearGrid;
+class vtkTable;
 
 class VTK_IO_EXPORT vtkDataReader : public vtkAlgorithm
 {
@@ -258,6 +259,10 @@ public:
   // (unless no geometry was defined).
   int ReadEdgeData(vtkGraph *g, int numEdges);
 
+  // Description:
+  // Read the row data of a vtk data file.
+  int ReadRowData(vtkTable *t, int numEdges);
+
   // Description:
   // Read a bunch of "cells". Return 0 if error.
   int ReadCells(int size, int *data);
diff --git a/IO/vtkDataWriter.cxx b/IO/vtkDataWriter.cxx
index 0fb7f8179d6461a58a73c744b9cbf2af3225609b..d0a65946db1bb393a4c80573006f7bbcd7a3bea3 100644
--- a/IO/vtkDataWriter.cxx
+++ b/IO/vtkDataWriter.cxx
@@ -33,6 +33,7 @@
 #include "vtkPoints.h"
 #include "vtkShortArray.h"
 #include "vtkStringArray.h"
+#include "vtkTable.h"
 #include "vtkTypeTraits.h"
 #include "vtkUnsignedCharArray.h"
 #include "vtkUnsignedIntArray.h"
@@ -42,7 +43,7 @@
 #include <vtksys/ios/sstream>
 
 
-vtkCxxRevisionMacro(vtkDataWriter, "1.131");
+vtkCxxRevisionMacro(vtkDataWriter, "1.132");
 vtkStandardNewMacro(vtkDataWriter);
 
 // this undef is required on the hp. vtkMutexLock ends up including
@@ -819,6 +820,146 @@ int vtkDataWriter::WriteEdgeData(ostream *fp, vtkGraph *g)
   return 1;
 }
 
+// Write the row data (e.g., scalars, vectors, ...) of a vtk table.
+// Returns 0 if error.
+int vtkDataWriter::WriteRowData(ostream *fp, vtkTable *t)
+{
+  int numEdges;
+  vtkDataArray *scalars;
+  vtkDataArray *vectors;
+  vtkDataArray *normals;
+  vtkDataArray *tcoords;
+  vtkDataArray *tensors;
+  vtkDataArray *globalIds;
+  vtkAbstractArray *pedigreeIds;
+  vtkFieldData *field;
+  vtkDataSetAttributes *cd=t->GetRowData();
+
+  vtkDebugMacro(<<"Writing row data...");
+
+  scalars = cd->GetScalars();
+  if(scalars && scalars->GetNumberOfTuples() <= 0)
+    scalars = 0;
+    
+  vectors = cd->GetVectors();
+  if(vectors && vectors->GetNumberOfTuples() <= 0)
+    vectors = 0;
+    
+  normals = cd->GetNormals();
+  if(normals && normals->GetNumberOfTuples() <= 0)
+    normals = 0;
+    
+  tcoords = cd->GetTCoords();
+  if(tcoords && tcoords->GetNumberOfTuples() <= 0)
+    tcoords = 0;
+    
+  tensors = cd->GetTensors();
+  if(tensors && tensors->GetNumberOfTuples() <= 0)
+    tensors = 0;
+    
+  globalIds = cd->GetGlobalIds();
+  if(globalIds && globalIds->GetNumberOfTuples() <= 0)
+    globalIds = 0;
+    
+  pedigreeIds = cd->GetPedigreeIds();
+  if(pedigreeIds && pedigreeIds->GetNumberOfTuples() <= 0)
+    pedigreeIds = 0;
+    
+  field = cd;
+  if(field && field->GetNumberOfTuples() <= 0)
+    field = 0;
+
+  if(!(scalars || vectors || normals || tcoords || tensors || globalIds || pedigreeIds || field))
+    {
+    vtkDebugMacro(<<"No row data to write!");
+    return 1;
+    }
+
+  *fp << "ROW_DATA " << numEdges << "\n";
+  //
+  // Write scalar data
+  //
+  if( scalars )
+    {
+    if ( ! this->WriteScalarData(fp, scalars, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write vector data
+  //
+  if( vectors )
+    {
+    if ( ! this->WriteVectorData(fp, vectors, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write normals
+  //
+  if ( normals )
+    {
+    if ( ! this->WriteNormalData(fp, normals, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write texture coords
+  //
+  if ( tcoords )
+    {
+    if ( ! this->WriteTCoordData(fp, tcoords, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write tensors
+  //
+  if ( tensors )
+    {
+    if ( ! this->WriteTensorData(fp, tensors, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write global ids
+  //
+  if ( globalIds )
+    {
+    if ( ! this->WriteGlobalIdData(fp, globalIds, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write pedigree ids
+  //
+  if ( pedigreeIds )
+    {
+    if ( ! this->WritePedigreeIdData(fp, pedigreeIds, numEdges) )
+      {
+      return 0;
+      }
+    }
+  //
+  // Write field
+  //
+  if ( field )
+    {
+    if ( ! this->WriteFieldData(fp, field) )
+      {
+      return 0;
+      }
+    }
+
+  return 1;
+}
+
 // Template to handle writing data in ascii or binary
 // We could change the format into C++ io standard ...
 template <class T>
diff --git a/IO/vtkDataWriter.h b/IO/vtkDataWriter.h
index 2ccac9664a3efc00896548220501dc589d6592cb..b9f9c176eb0888cd109b5354f7dfecfc47feb854 100644
--- a/IO/vtkDataWriter.h
+++ b/IO/vtkDataWriter.h
@@ -34,6 +34,7 @@ class vtkDataSet;
 class vtkFieldData;
 class vtkGraph;
 class vtkPoints;
+class vtkTable;
 
 class VTK_IO_EXPORT vtkDataWriter : public vtkWriter
 {
@@ -180,6 +181,11 @@ public:
   // Returns 0 if error.
   int WriteVertexData(ostream *fp, vtkGraph *g);
 
+  // Description:
+  // Write the row data (e.g., scalars, vectors, ...) of a vtk table.
+  // Returns 0 if error.
+  int WriteRowData(ostream *fp, vtkTable *g);
+
   // Description:
   // Write out the field data.
   int WriteFieldData(ostream *fp, vtkFieldData *f);
diff --git a/IO/vtkTableReader.cxx b/IO/vtkTableReader.cxx
index 36ba449a972893761293aacfb3a242848b756ca8..8a0dbb458fa457dc4d056b5753a4dc2b6906bec0 100644
--- a/IO/vtkTableReader.cxx
+++ b/IO/vtkTableReader.cxx
@@ -23,7 +23,7 @@
 #include "vtkStreamingDemandDrivenPipeline.h"
 #include "vtkTable.h"
 
-vtkCxxRevisionMacro(vtkTableReader, "1.1");
+vtkCxxRevisionMacro(vtkTableReader, "1.2");
 vtkStandardNewMacro(vtkTableReader);
 
 #ifdef read
@@ -156,6 +156,21 @@ int vtkTableReader::RequestData(
       continue;
       }
 
+    if(!strncmp(this->LowerCase(line), "row_data", 8))
+      {
+      int row_count = 0;
+      if(!this->Read(&row_count))
+        {
+        vtkErrorMacro(<<"Cannot read number of rows!");
+        this->CloseVTKFile();
+        return 1;
+        }
+
+
+      this->ReadRowData(output, row_count);
+      continue;
+      }
+
     vtkErrorMacro(<< "Unrecognized keyword: " << line);
     }
 
diff --git a/IO/vtkTableWriter.cxx b/IO/vtkTableWriter.cxx
index cf5b1c6943ea21468d492c8b8ecc768e89e3955e..b686ebc61f1c9a7caee020bf7f5da937cf2b9324 100644
--- a/IO/vtkTableWriter.cxx
+++ b/IO/vtkTableWriter.cxx
@@ -26,7 +26,7 @@
 # include <io.h> /* unlink */
 #endif
 
-vtkCxxRevisionMacro(vtkTableWriter, "1.1");
+vtkCxxRevisionMacro(vtkTableWriter, "1.2");
 vtkStandardNewMacro(vtkTableWriter);
 
 void vtkTableWriter::WriteData()
@@ -51,6 +51,7 @@ void vtkTableWriter::WriteData()
   *fp << "DATASET TABLE\n"; 
 
   this->WriteFieldData(fp, this->GetInput()->GetFieldData());
+  this->WriteRowData(fp, this->GetInput());
 
   this->CloseVTKFile(fp);  
 }
diff --git a/Infovis/Testing/Cxx/TestGroupLeafVertices.cxx b/Infovis/Testing/Cxx/TestGroupLeafVertices.cxx
index cc8f66411a816f4e5e8e731a7b1bfbd535495cff..be0ea2809bd146b6879f1f301ea6ea77345d3770 100644
--- a/Infovis/Testing/Cxx/TestGroupLeafVertices.cxx
+++ b/Infovis/Testing/Cxx/TestGroupLeafVertices.cxx
@@ -122,8 +122,8 @@ int TestGroupLeafVertices(int argc, char* argv[])
 
   VTK_CREATE(vtkGroupLeafVertices, group);
   group->SetInputConnection(tableToTree->GetOutputPort());
-  group->SetInputArrayToProcess(0, 0, 0, vtkDataSet::FIELD_ASSOCIATION_NONE, "type");
-  group->SetInputArrayToProcess(1, 0, 0, vtkDataSet::FIELD_ASSOCIATION_NONE, "name");
+  group->SetInputArrayToProcess(0, 0, 0, vtkDataSet::FIELD_ASSOCIATION_VERTICES, "type");
+  group->SetInputArrayToProcess(1, 0, 0, vtkDataSet::FIELD_ASSOCIATION_VERTICES, "name");
   group->Update();
   tree = group->GetOutput();
   for (vtkIdType i = 0; i < tree->GetNumberOfVertices(); i++)
@@ -133,8 +133,8 @@ int TestGroupLeafVertices(int argc, char* argv[])
 
   VTK_CREATE(vtkGroupLeafVertices, group2);
   group2->SetInputConnection(group->GetOutputPort());
-  group2->SetInputArrayToProcess(0, 0, 0, vtkDataSet::FIELD_ASSOCIATION_NONE, "color");
-  group2->SetInputArrayToProcess(1, 0, 0, vtkDataSet::FIELD_ASSOCIATION_NONE, "name");
+  group2->SetInputArrayToProcess(0, 0, 0, vtkDataSet::FIELD_ASSOCIATION_VERTICES, "color");
+  group2->SetInputArrayToProcess(1, 0, 0, vtkDataSet::FIELD_ASSOCIATION_VERTICES, "name");
   group2->Update();
   tree = group2->GetOutput();
   for (vtkIdType i = 0; i < tree->GetNumberOfVertices(); i++)
diff --git a/Infovis/Testing/Cxx/TestTable.cxx b/Infovis/Testing/Cxx/TestTable.cxx
index ab5452ae0b99328ff371cccec2fad81bf1555aea..676962db36e5d5bfa16fb86fd9b7383b17da1b2c 100644
--- a/Infovis/Testing/Cxx/TestTable.cxx
+++ b/Infovis/Testing/Cxx/TestTable.cxx
@@ -17,13 +17,12 @@
   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
   the U.S. Government retains certain rights in this software.
 -------------------------------------------------------------------------*/
-#include "vtkTable.h"
+#include "vtkDoubleArray.h"
 #include "vtkIntArray.h"
+#include "vtkMath.h"
 #include "vtkStringArray.h"
-#include "vtkDoubleArray.h"
+#include "vtkTable.h"
 #include "vtkVariantArray.h"
-#include "vtkFieldData.h"
-#include "vtkMath.h"
 
 #include <time.h>
 #include <vtkstd/vector>
diff --git a/Infovis/Testing/Cxx/TestThresholdTable.cxx b/Infovis/Testing/Cxx/TestThresholdTable.cxx
index a71087c63391a68778305c2bc98c7b957bad92f5..42d771c0a2cb85fbae90f1fb1209db2cacac6152 100644
--- a/Infovis/Testing/Cxx/TestThresholdTable.cxx
+++ b/Infovis/Testing/Cxx/TestThresholdTable.cxx
@@ -63,7 +63,7 @@ int TestThresholdTable(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
   threshold->SetInput(table);
   
   int errors = 0;
-  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "intArr");
+  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "intArr");
   threshold->SetMinValue(vtkVariant(3));
   threshold->SetMaxValue(vtkVariant(5));
   threshold->SetMode(vtkThresholdTable::ACCEPT_BETWEEN);
@@ -96,7 +96,7 @@ int TestThresholdTable(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
       }
     }
   
-  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "doubleArr");
+  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "doubleArr");
   threshold->SetMaxValue(vtkVariant(1.2));
   threshold->SetMode(vtkThresholdTable::ACCEPT_LESS_THAN);
   threshold->Update();
@@ -133,7 +133,7 @@ int TestThresholdTable(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
       }
     }
   
-  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "stringArr");
+  threshold->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "stringArr");
   threshold->SetMinValue(vtkVariant("10"));
   threshold->SetMaxValue(vtkVariant("13"));
   threshold->SetMode(vtkThresholdTable::ACCEPT_OUTSIDE);
diff --git a/Infovis/Testing/Cxx/TestTimePoint.cxx b/Infovis/Testing/Cxx/TestTimePoint.cxx
index ee1ddeb16c2e64d54369c89dd7ff240dfa846100..2e466f07f3b413b35672f36b72f300696e298b20 100644
--- a/Infovis/Testing/Cxx/TestTimePoint.cxx
+++ b/Infovis/Testing/Cxx/TestTimePoint.cxx
@@ -83,7 +83,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Testing vtkTimePointToString on a vtkTable with datetime array ..." << endl;
   timeToString->SetInput(table);
-  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "datetime");
+  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "datetime");
   timeToString->SetOutputArrayName("datetime [to string]");
   timeToString->SetISO8601Format(vtkTimePointUtility::ISO8601_DATETIME_MILLIS);
   timeToString->Update();
@@ -102,7 +102,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Converting string array back to a datetime ..." << endl;
   stringToTime->SetInput(tableOutput);
-  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "datetime [to string]");
+  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "datetime [to string]");
   stringToTime->SetOutputArrayName("datetime [to string] [to datetime]");
   stringToTime->Update();
   tableOutput2 = vtkTable::SafeDownCast(stringToTime->GetOutput());
@@ -125,7 +125,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Testing vtkTimePointToString on a vtkTable with date array ..." << endl;
   timeToString->SetInput(table);
-  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "date");
+  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "date");
   timeToString->SetISO8601Format(vtkTimePointUtility::ISO8601_DATE);
   timeToString->SetOutputArrayName("date [to string]");
   timeToString->Update();
@@ -144,7 +144,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Converting string array back to a date ..." << endl;
   stringToTime->SetInput(tableOutput);
-  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "date [to string]");
+  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "date [to string]");
   stringToTime->SetOutputArrayName("date [to string] [to date]");
   stringToTime->Update();
   tableOutput2 = vtkTable::SafeDownCast(stringToTime->GetOutput());
@@ -167,7 +167,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Testing vtkTimePointToString on a vtkTable with time array ..." << endl;
   timeToString->SetInput(table);
-  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "time");
+  timeToString->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "time");
   timeToString->SetISO8601Format(vtkTimePointUtility::ISO8601_TIME_MILLIS);
   timeToString->SetOutputArrayName("time [to string]");
   timeToString->Update();
@@ -186,7 +186,7 @@ int TestTimePoint(int, char*[])
 
   cerr << "Converting string array back to a time ..." << endl;
   stringToTime->SetInput(tableOutput);
-  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "time [to string]");
+  stringToTime->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "time [to string]");
   stringToTime->SetOutputArrayName("time [to string] [to time]");
   stringToTime->Update();
   tableOutput2 = vtkTable::SafeDownCast(stringToTime->GetOutput());
diff --git a/Infovis/vtkDataObjectToTable.cxx b/Infovis/vtkDataObjectToTable.cxx
index e66d6f86c15607e521e73bb6c22c4ac3759e2153..70555aa3702315148667bb7c5379a339848dc4c6 100644
--- a/Infovis/vtkDataObjectToTable.cxx
+++ b/Infovis/vtkDataObjectToTable.cxx
@@ -23,7 +23,7 @@
 #include "vtkCellData.h"
 #include "vtkDataObject.h"
 #include "vtkDataSet.h"
-#include "vtkFieldData.h"
+#include "vtkDataSetAttributes.h"
 #include "vtkGraph.h"
 #include "vtkInformation.h"
 #include "vtkInformationVector.h"
@@ -31,7 +31,7 @@
 #include "vtkPointData.h"
 #include "vtkTable.h"
 
-vtkCxxRevisionMacro(vtkDataObjectToTable, "1.5");
+vtkCxxRevisionMacro(vtkDataObjectToTable, "1.6");
 vtkStandardNewMacro(vtkDataObjectToTable);
 //---------------------------------------------------------------------------
 vtkDataObjectToTable::vtkDataObjectToTable()
@@ -67,7 +67,14 @@ int vtkDataObjectToTable::RequestData(
   vtkTable* output = vtkTable::SafeDownCast(
     outputInfo->Get(vtkDataObject::DATA_OBJECT()));
 
-  vtkFieldData* data = vtkFieldData::New();
+  // If the input is a table, just copy it into the output.
+  if (vtkTable::SafeDownCast(input))
+    {
+    output->ShallowCopy(input);
+    return 1;
+    }
+
+  vtkDataSetAttributes* data = vtkDataSetAttributes::New();
   
   switch(this->FieldType)
     {
@@ -115,7 +122,7 @@ int vtkDataObjectToTable::RequestData(
       break;
     }
     
-  output->SetFieldData(data);
+  output->SetRowData(data);
   data->Delete();
   return 1;
 }
diff --git a/Infovis/vtkDelimitedTextReader.cxx b/Infovis/vtkDelimitedTextReader.cxx
index 8898c21c87ad67060ef5ba8570ce3d7943e2cbed..c4112a5f5f56643193fe1d70eb1fe2211420cfc1 100644
--- a/Infovis/vtkDelimitedTextReader.cxx
+++ b/Infovis/vtkDelimitedTextReader.cxx
@@ -36,7 +36,7 @@
 #include <vtkstd/vector>
 #include <vtkstd/string>
 
-vtkCxxRevisionMacro(vtkDelimitedTextReader, "1.21");
+vtkCxxRevisionMacro(vtkDelimitedTextReader, "1.22");
 vtkStandardNewMacro(vtkDelimitedTextReader);
 
 struct vtkDelimitedTextReaderInternals
@@ -288,13 +288,6 @@ int vtkDelimitedTextReader::RequestData(
     dataArray->Delete();
     }
 
-  // Use vtkDataSetAttributes to store the data in the table,
-  // so we get attribute capabilities.
-  vtkSmartPointer<vtkDataSetAttributes> dsa =
-    vtkSmartPointer<vtkDataSetAttributes>::New();
-  dsa->ShallowCopy(table->GetFieldData());
-  table->SetFieldData(dsa);
-
   // Look for pedigree id array.
   vtkAbstractArray* pedIds = table->GetColumnByName("id");
   if (!pedIds)
@@ -307,7 +300,7 @@ int vtkDelimitedTextReader::RequestData(
     }
   if (pedIds)
     {
-    dsa->SetPedigreeIds(pedIds);
+    table->GetRowData()->SetPedigreeIds(pedIds);
     }
  
   return 1;
diff --git a/Infovis/vtkGroupLeafVertices.cxx b/Infovis/vtkGroupLeafVertices.cxx
index 882c1a1610885cc64b04f4cd1ebbb81b218f8888..0678fcd18f0d798e13b6eb41d4d0de418c4b3224 100644
--- a/Infovis/vtkGroupLeafVertices.cxx
+++ b/Infovis/vtkGroupLeafVertices.cxx
@@ -37,7 +37,7 @@
 #include <vtksys/stl/utility>
 #include <vtksys/stl/vector>
 
-vtkCxxRevisionMacro(vtkGroupLeafVertices, "1.8");
+vtkCxxRevisionMacro(vtkGroupLeafVertices, "1.9");
 vtkStandardNewMacro(vtkGroupLeafVertices);
 
 //---------------------------------------------------------------------------
@@ -148,7 +148,7 @@ int vtkGroupLeafVertices::RequestData(
   // so we can call InsertNextBlankRow.
   vtkSmartPointer<vtkTable> treeTable = 
     vtkSmartPointer<vtkTable>::New();
-  treeTable->SetFieldData(builder->GetVertexData());
+  treeTable->SetRowData(builder->GetVertexData());
 
   // Copy everything into the new tree, adding group nodes.
   // Make a map of (parent id, group-by string) -> group vertex id.
diff --git a/Infovis/vtkMergeColumns.h b/Infovis/vtkMergeColumns.h
index cf618db92be601e961778bb6c302ca276144ac50..a05a54bc2920b8eff9abe90179cfe00d068aa0ae 100644
--- a/Infovis/vtkMergeColumns.h
+++ b/Infovis/vtkMergeColumns.h
@@ -23,11 +23,11 @@
 // vtkMergeColumns replaces two columns in a table with a single column
 // containing data in both columns.  The columns are set using
 //
-//   SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "col1")
+//   SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "col1")
 //
 // and
 //
-//   SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "col2")
+//   SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_ROWS, "col2")
 //
 // where "col1" and "col2" are the names of the columns to merge.
 // The user may also specify the name of the merged column.
diff --git a/Infovis/vtkStringToNumeric.cxx b/Infovis/vtkStringToNumeric.cxx
index 99d2bcad92f1ddf08073d39bfc62131ab5c88cf1..25197b031e156e46fed7dd417c95d911968a1ff4 100644
--- a/Infovis/vtkStringToNumeric.cxx
+++ b/Infovis/vtkStringToNumeric.cxx
@@ -32,9 +32,10 @@
 #include "vtkObjectFactory.h"
 #include "vtkPointData.h"
 #include "vtkStringArray.h"
+#include "vtkTable.h"
 #include "vtkVariant.h"
 
-vtkCxxRevisionMacro(vtkStringToNumeric, "1.4");
+vtkCxxRevisionMacro(vtkStringToNumeric, "1.5");
 vtkStandardNewMacro(vtkStringToNumeric);
 
 vtkStringToNumeric::vtkStringToNumeric()
@@ -84,6 +85,11 @@ int vtkStringToNumeric::RequestData(
     {
     this->ConvertArrays(outputGraph->GetEdgeData());
     }
+  vtkTable *outputTable = vtkTable::SafeDownCast(output);
+  if (outputTable && this->ConvertPointData)
+    {
+    this->ConvertArrays(outputTable->GetRowData());
+    }
   
   return 1;
 }
diff --git a/Infovis/vtkStringToNumeric.h b/Infovis/vtkStringToNumeric.h
index 8a8f75519455aeedd02e2a4f8a24f85031ae0c6e..8a692873b09cdf502907cf858ac2758b5bcc3a94 100644
--- a/Infovis/vtkStringToNumeric.h
+++ b/Infovis/vtkStringToNumeric.h
@@ -69,6 +69,14 @@ public:
     { return this->GetConvertCellData(); }
   vtkBooleanMacro(ConvertEdgeData, bool);
 
+  // Description:
+  // Whether to detect and convert row data arrays.  Default is on.
+  virtual void SetConvertRowData(bool b)
+    { this->SetConvertPointData(b); }
+  virtual bool GetConvertRowData()
+    { return this->GetConvertPointData(); }
+  vtkBooleanMacro(ConvertRowData, bool);
+
   // Description:
   // This is required to capture REQUEST_DATA_OBJECT requests.
   virtual int ProcessRequest(vtkInformation* request, 
diff --git a/Infovis/vtkStringToTimePoint.cxx b/Infovis/vtkStringToTimePoint.cxx
index 30bb233e7bf3da7ad2dadca409f5c806551f30b8..b31237995463b4674aed25a7c50df7a1f015edc8 100644
--- a/Infovis/vtkStringToTimePoint.cxx
+++ b/Infovis/vtkStringToTimePoint.cxx
@@ -24,15 +24,17 @@
 #include "vtkDataSet.h"
 #include "vtkDemandDrivenPipeline.h"
 #include "vtkFieldData.h"
+#include "vtkGraph.h"
 #include "vtkInformation.h"
 #include "vtkInformationVector.h"
 #include "vtkObjectFactory.h"
 #include "vtkPointData.h"
 #include "vtkStringArray.h"
+#include "vtkTable.h"
 #include "vtkTimePointUtility.h"
 #include "vtkTypeUInt64Array.h"
 
-vtkCxxRevisionMacro(vtkStringToTimePoint, "1.3");
+vtkCxxRevisionMacro(vtkStringToTimePoint, "1.4");
 vtkStandardNewMacro(vtkStringToTimePoint);
 
 vtkStringToTimePoint::vtkStringToTimePoint()
@@ -133,6 +135,38 @@ int vtkStringToTimePoint::RequestData(
         }
       }
     }
+  vtkGraph* outputGraph;
+  if (!addedArray && (outputGraph = vtkGraph::SafeDownCast(output)))
+    {
+    for (vtkIdType i = 0; i < outputGraph->GetVertexData()->GetNumberOfArrays(); i++)
+      {
+      if (stringArray == outputGraph->GetVertexData()->GetAbstractArray(i))
+        {
+        outputGraph->GetVertexData()->AddArray(outputArray);
+        addedArray = true;
+        }
+      }
+    for (vtkIdType i = 0; i < outputGraph->GetEdgeData()->GetNumberOfArrays(); i++)
+      {
+      if (stringArray == outputGraph->GetEdgeData()->GetAbstractArray(i))
+        {
+        outputGraph->GetEdgeData()->AddArray(outputArray);
+        addedArray = true;
+        }
+      }
+    }
+  vtkTable* outputTable;
+  if (!addedArray && (outputTable = vtkTable::SafeDownCast(output)))
+    {
+    for (vtkIdType i = 0; i < outputTable->GetRowData()->GetNumberOfArrays(); i++)
+      {
+      if (stringArray == outputTable->GetRowData()->GetAbstractArray(i))
+        {
+        outputTable->GetRowData()->AddArray(outputArray);
+        addedArray = true;
+        }
+      }
+    }
   if (!addedArray)
     {
     vtkErrorMacro(<< "The input array was not found in the field, point, or cell data.");
diff --git a/Infovis/vtkTableToGraph.cxx b/Infovis/vtkTableToGraph.cxx
index b1d5936fdb06efcf9cb296a315ef2fb1b9235e30..7c8efbe143a9c95decc66d93f5ad2a9fef5d2738 100644
--- a/Infovis/vtkTableToGraph.cxx
+++ b/Infovis/vtkTableToGraph.cxx
@@ -51,7 +51,7 @@
 #define VTK_CREATE(type, name) \
   vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
 
-vtkCxxRevisionMacro(vtkTableToGraph, "1.15");
+vtkCxxRevisionMacro(vtkTableToGraph, "1.16");
 vtkStandardNewMacro(vtkTableToGraph);
 vtkCxxSetObjectMacro(vtkTableToGraph, LinkGraph, vtkMutableDirectedGraph);
 //---------------------------------------------------------------------------
@@ -679,7 +679,7 @@ int vtkTableToGraph::RequestData(
 
   // Add the correct number of vertices to the graph based on the number of
   // rows in the vertex table.
-  builder->GetVertexData()->PassData(vertexTable->GetFieldData());
+  builder->GetVertexData()->PassData(vertexTable->GetRowData());
   for (vtkIdType i = 0; i < vertexTable->GetNumberOfRows(); ++i)
     {
     if (this->Directed)
@@ -701,7 +701,7 @@ int vtkTableToGraph::RequestData(
   // For each row in the edge table, add one edge to the
   // output graph for each edge in the link graph.
   VTK_CREATE(vtkDataSetAttributes, edgeTableData);
-  edgeTableData->ShallowCopy(edgeTable->GetFieldData());
+  edgeTableData->ShallowCopy(edgeTable->GetRowData());
   builder->GetEdgeData()->CopyAllocate(edgeTableData);
   vtksys_stl::map<vtkIdType, vtksys_stl::vector< vtksys_stl::pair<vtkIdType, vtkIdType> > > hiddenInEdges;
   vtksys_stl::map<vtkIdType, vtksys_stl::vector<vtkIdType> > hiddenOutEdges;
diff --git a/Infovis/vtkTableToTreeFilter.cxx b/Infovis/vtkTableToTreeFilter.cxx
index 224ec9675f8eadb78742e6525de41c2245f7e6b8..af1aefe749b29f7e24dccfa501fb383a8a0439d7 100644
--- a/Infovis/vtkTableToTreeFilter.cxx
+++ b/Infovis/vtkTableToTreeFilter.cxx
@@ -35,7 +35,7 @@
 #include <vtkstd/vector>
 #include <vtkstd/string>
 
-vtkCxxRevisionMacro(vtkTableToTreeFilter, "1.4");
+vtkCxxRevisionMacro(vtkTableToTreeFilter, "1.5");
 vtkStandardNewMacro(vtkTableToTreeFilter);
 
 
@@ -114,7 +114,7 @@ int vtkTableToTreeFilter::RequestData(
     }
 
   // Copy the table data into the tree vertex data
-  tree->GetVertexData()->PassData(table->GetFieldData());
+  tree->GetVertexData()->PassData(table->GetRowData());
  
   return 1;
 }
diff --git a/Infovis/vtkTimePointToString.cxx b/Infovis/vtkTimePointToString.cxx
index 49345ca8288b6014a0e7126421fbc51bea95cec7..a027c31550e8e9e7ed6912cf1cbbc7a81406f3f8 100644
--- a/Infovis/vtkTimePointToString.cxx
+++ b/Infovis/vtkTimePointToString.cxx
@@ -31,10 +31,11 @@
 #include "vtkObjectFactory.h"
 #include "vtkPointData.h"
 #include "vtkStringArray.h"
+#include "vtkTable.h"
 #include "vtkTimePointUtility.h"
 #include "vtkTypeUInt64Array.h"
 
-vtkCxxRevisionMacro(vtkTimePointToString, "1.5");
+vtkCxxRevisionMacro(vtkTimePointToString, "1.6");
 vtkStandardNewMacro(vtkTimePointToString);
 
 vtkTimePointToString::vtkTimePointToString()
@@ -211,6 +212,18 @@ int vtkTimePointToString::RequestData(
         }
       }
     }
+  vtkTable* outputTable;
+  if (!addedArray && (outputTable = vtkTable::SafeDownCast(output)))
+    {
+    for (vtkIdType i = 0; i < outputTable->GetRowData()->GetNumberOfArrays(); i++)
+      {
+      if (inputArray == outputTable->GetRowData()->GetAbstractArray(i))
+        {
+        outputTable->GetRowData()->AddArray(stringArray);
+        addedArray = true;
+        }
+      }
+    }
   if (!addedArray)
     {
     vtkErrorMacro(<< "The input array was not found in the field, point, or cell data.");
diff --git a/Parallel/vtkCollectGraph.cxx b/Parallel/vtkCollectGraph.cxx
index 7092e4e1fb65326376303d4951233c93e9871f2c..32cc32ed348bc70f5527f72a5b93838f300f72e4 100644
--- a/Parallel/vtkCollectGraph.cxx
+++ b/Parallel/vtkCollectGraph.cxx
@@ -45,7 +45,7 @@ using vtksys_stl::map;
 using vtksys_stl::pair;
 using vtksys_stl::vector;
 
-vtkCxxRevisionMacro(vtkCollectGraph, "1.4");
+vtkCxxRevisionMacro(vtkCollectGraph, "1.5");
 vtkStandardNewMacro(vtkCollectGraph);
 
 vtkCxxSetObjectMacro(vtkCollectGraph,Controller, vtkMultiProcessController);
@@ -58,7 +58,7 @@ vtkCollectGraph::vtkCollectGraph()
   this->SocketController = NULL;
 
   // Default vertex id array.
-  this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_NONE, "id");
+  this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_VERTICES, "id");
 
   // Controller keeps a reference to this object as well.
   this->Controller = NULL;
diff --git a/Views/vtkConvertSelectionDomain.cxx b/Views/vtkConvertSelectionDomain.cxx
index 3edf9f254b03a415e0b46867d5ee0bfcf2d2c50c..a0e55044687d0e9c3890298af08974a34f5787a2 100644
--- a/Views/vtkConvertSelectionDomain.cxx
+++ b/Views/vtkConvertSelectionDomain.cxx
@@ -37,7 +37,7 @@
 
 #include <vtksys/stl/set>
 
-vtkCxxRevisionMacro(vtkConvertSelectionDomain, "1.3");
+vtkCxxRevisionMacro(vtkConvertSelectionDomain, "1.4");
 vtkStandardNewMacro(vtkConvertSelectionDomain);
 //----------------------------------------------------------------------------
 vtkConvertSelectionDomain::vtkConvertSelectionDomain()
@@ -123,8 +123,8 @@ int vtkConvertSelectionDomain::RequestData(
     }
   else if (vtkTable::SafeDownCast(data))
     {
-    dsa1 = vtkDataSetAttributes::SafeDownCast(vtkTable::SafeDownCast(data)->GetFieldData());
-    fieldType1 = vtkSelection::FIELD;
+    dsa1 = vtkDataSetAttributes::SafeDownCast(vtkTable::SafeDownCast(data)->GetRowData());
+    fieldType1 = vtkSelection::ROW;
     }
 
   vtksys_stl::set<vtkStdString> domains1;