Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing.Views/3.3/DataPreprocessingView.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing.Views/3.3/DataPreprocessingView.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing.Views/3.3/DataPreprocessingView.cs	(revision 10586)
@@ -64,5 +64,5 @@
 
       //create content items
-      IPreprocessingData data = Content.Data;
+      ITransactionalPreprocessingData data = Content.Data;
       ISearchLogic searchLogic = new SearchLogic(data);
       var dataGridLogic = new DataGridLogic(data);
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/HeuristicLab.DataPreprocessing-3.3.csproj
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/HeuristicLab.DataPreprocessing-3.3.csproj	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/HeuristicLab.DataPreprocessing-3.3.csproj	(revision 10586)
@@ -71,4 +71,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Implementations\PreprocessingData.cs" />
     <Compile Include="Implementations\DataGridLogic.cs" />
     <Compile Include="Implementations\DataPreprocessingChangedEvent.cs" />
@@ -76,4 +77,5 @@
     <Compile Include="Implementations\Filter\IFilter.cs" />
     <Compile Include="Implementations\ManipulationLogic.cs" />
+    <Compile Include="Interfaces\IPreprocessingData.cs" />
     <Compile Include="Interfaces\IDataGridLogic.cs" />
     <Compile Include="Implementations\FilterContent.cs" />
@@ -95,5 +97,5 @@
     <Compile Include="Implementations\DataGridContent.cs" />
     <Compile Include="Implementations\PreprocessingContext.cs" />
-    <Compile Include="Implementations\PreprocessingData.cs" />
+    <Compile Include="Implementations\TransactionalPreprocessingData.cs" />
     <Compile Include="Implementations\SearchLogic.cs" />
     <Compile Include="Implementations\StatisticsLogic.cs" />
@@ -102,5 +104,5 @@
     <Compile Include="Interfaces\ISearchLogic.cs" />
     <Compile Include="Interfaces\IStatisticsLogic.cs" />
-    <Compile Include="Interfaces\IPreprocessingData.cs" />
+    <Compile Include="Interfaces\ITransactionalPreprocessingData.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/DataGridLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/DataGridLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/DataGridLogic.cs	(revision 10586)
@@ -29,7 +29,7 @@
   public class DataGridLogic : IDataGridLogic {
 
-    private IPreprocessingData preprocessingData;
+    private ITransactionalPreprocessingData preprocessingData;
 
-    public DataGridLogic(IPreprocessingData preprocessingData) {
+    public DataGridLogic(ITransactionalPreprocessingData preprocessingData) {
       this.preprocessingData = preprocessingData;
     }
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/HistogramLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/HistogramLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/HistogramLogic.cs	(revision 10586)
@@ -26,8 +26,8 @@
 namespace HeuristicLab.DataPreprocessing {
   public class HistogramLogic : IHistogramLogic {
-    private IPreprocessingData preprocessingData;
+    private ITransactionalPreprocessingData preprocessingData;
     private DataTable dataTable;
 
-    public HistogramLogic(IPreprocessingData preprocessingData) {
+    public HistogramLogic(ITransactionalPreprocessingData preprocessingData) {
       this.preprocessingData = preprocessingData;
       dataTable = new DataTable("Histogram");
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/LineChartLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/LineChartLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/LineChartLogic.cs	(revision 10586)
@@ -26,8 +26,8 @@
 namespace HeuristicLab.DataPreprocessing {
   public class LineChartLogic : ILineChartLogic {
-    private IPreprocessingData preprocessingData;
+    private ITransactionalPreprocessingData preprocessingData;
     private DataTable dataTable;
 
-    public LineChartLogic(IPreprocessingData preprocessingData) {
+    public LineChartLogic(ITransactionalPreprocessingData preprocessingData) {
       this.preprocessingData = preprocessingData;
       dataTable = new DataTable("LineChart");
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/ManipulationLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/ManipulationLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/ManipulationLogic.cs	(revision 10586)
@@ -27,9 +27,9 @@
 namespace HeuristicLab.DataPreprocessing {
   public class ManipulationLogic : IManipulationLogic {
-    private IPreprocessingData preprocessingData;
+    private ITransactionalPreprocessingData preprocessingData;
     private IStatisticsLogic statisticInfo;
     private ISearchLogic searchLogic;
 
-    public ManipulationLogic(IPreprocessingData _prepocessingData, ISearchLogic theSearchLogic, IStatisticsLogic theStatisticsLogic) {
+    public ManipulationLogic(ITransactionalPreprocessingData _prepocessingData, ISearchLogic theSearchLogic, IStatisticsLogic theStatisticsLogic) {
       preprocessingData = _prepocessingData;
       searchLogic = theSearchLogic;
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingContext.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingContext.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingContext.cs	(revision 10586)
@@ -32,5 +32,5 @@
 
     public PreprocessingContext(IDataAnalysisProblemData dataAnalysisProblemData, IAlgorithm algorithm, IDataAnalysisProblem problem) {
-      Data = new PreprocessingData(dataAnalysisProblemData);
+      Data = new TransactionalPreprocessingData(dataAnalysisProblemData);
       DataAnalysisProblemData = dataAnalysisProblemData;
       Algorithm = algorithm;
@@ -46,5 +46,5 @@
     }
 
-    public IPreprocessingData Data { get; private set; }
+    public ITransactionalPreprocessingData Data { get; private set; }
 
     public IDataAnalysisProblemData DataAnalysisProblemData { get; private set; }
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingData.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingData.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/PreprocessingData.cs	(revision 10586)
@@ -31,40 +31,18 @@
 namespace HeuristicLab.DataPreprocessing {
 
-  internal class PDSnapshot {
-    public IDictionary<int, IList> VariableValues { get; set; }
-
-    public IList<string> VariableNames { get; set; }
-
-    public double TrainingToTestRatio { get; set; }
-
-    public DataPreprocessingChangedEventType ChangedType { get; set; }
-
-    public int ChangedColumn { get; set; }
-
-    public int ChangedRow { get; set; }
-  }
-
   [Item("PreprocessingData", "Represents data used for preprocessing.")]
   public class PreprocessingData : NamedItem, IPreprocessingData {
 
-    private const int MAX_UNDO_DEPTH = 5;
-
-    private IDictionary<int, IList> variableValues;
-
-    private IList<string> variableNames;
-
-    private double trainingToTestRatio;
-
-    private IList<PDSnapshot> undoHistory;
-
-    //TODO: refactor extract Transaction logic in a own class
-    private int transactionDepth = 0;
-
-    private PreprocessingData(PreprocessingData original, Cloner cloner)
+    protected IDictionary<int, IList> variableValues;
+
+    protected IList<string> variableNames;
+
+    protected double trainingToTestRatio;
+
+    protected PreprocessingData(PreprocessingData original, Cloner cloner)
       : base(original, cloner) {
       variableValues = CopyVariableValues(original.variableValues);
       variableNames = new List<string>(original.variableNames);
       trainingToTestRatio = original.trainingToTestRatio;
-      undoHistory = new List<PDSnapshot>();
     }
 
@@ -92,5 +70,4 @@
 
       trainingToTestRatio = (double)problemData.TrainingPartition.Size / Math.Max(problemData.Dataset.Rows, double.Epsilon);
-      undoHistory = new List<PDSnapshot>();
     }
 
@@ -103,5 +80,5 @@
     }
 
-    private IDictionary<int, IList> CopyVariableValues(IDictionary<int, IList> original) {
+    protected IDictionary<int, IList> CopyVariableValues(IDictionary<int, IList> original) {
       var copy = new Dictionary<int, IList>(variableValues);
       for (int i = 0; i < original.Count; i++) {
@@ -111,21 +88,4 @@
     }
 
-    private void SaveSnapshot(DataPreprocessingChangedEventType changedType, int column, int row) {
-      if (transactionDepth > 0) return;
-
-      PDSnapshot currentSnapshot = new PDSnapshot();
-      currentSnapshot.VariableValues = CopyVariableValues(variableValues);
-      currentSnapshot.VariableNames = new List<string>(variableNames);
-      currentSnapshot.TrainingToTestRatio = trainingToTestRatio;
-      currentSnapshot.ChangedType = changedType;
-      currentSnapshot.ChangedColumn = column;
-      currentSnapshot.ChangedRow = row;
-
-      if (undoHistory.Count >= MAX_UNDO_DEPTH)
-        undoHistory.RemoveAt(0);
-
-      undoHistory.Add(currentSnapshot);
-    }
-
     #region NamedItem abstract Member Implementations
 
@@ -143,9 +103,6 @@
 
 
-    public void SetCell<T>(int columnIndex, int rowIndex, T value) {
-      SaveSnapshot(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
+    public virtual void SetCell<T>(int columnIndex, int rowIndex, T value) {
       variableValues[columnIndex][rowIndex] = value;
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
     }
 
@@ -165,48 +122,33 @@
     }
 
-    public void SetValues<T>(int columnIndex, IList<T> values) {
+    public virtual void SetValues<T>(int columnIndex, IList<T> values) {
       if (IsType<T>(columnIndex)) {
-        SaveSnapshot(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
         variableValues[columnIndex] = (IList)values;
       } else {
         throw new ArgumentException("The datatype of column " + columnIndex + " must be of type " + variableValues[columnIndex].GetType().Name + " but was " + typeof(T).Name);
       }
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
-    }
-
-    public void InsertRow(int rowIndex) {
-      SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
+    }
+
+    public virtual void InsertRow(int rowIndex) {
       foreach (IList column in variableValues.Values) {
         Type type = column.GetType().GetGenericArguments()[0];
         column.Insert(rowIndex, type.IsValueType ? Activator.CreateInstance(type) : null);
       }
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
-    }
-
-    public void DeleteRow(int rowIndex) {
-      SaveSnapshot(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
+    }
+
+    public virtual void DeleteRow(int rowIndex) {
       foreach (IList column in variableValues.Values) {
         column.RemoveAt(rowIndex);
       }
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
-    }
-
-    public void InsertColumn<T>(string variableName, int columnIndex) {
-      SaveSnapshot(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
+    }
+
+    public virtual void InsertColumn<T>(string variableName, int columnIndex) {
       variableValues.Add(columnIndex, new List<T>(Rows));
       variableNames.Insert(columnIndex, variableName);
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
-    }
-
-    public void DeleteColumn(int columnIndex) {
-      SaveSnapshot(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
+    }
+
+    public virtual void DeleteColumn(int columnIndex) {
       variableValues.Remove(columnIndex);
       variableNames.RemoveAt(columnIndex);
-      if (transactionDepth <= 0)
-        OnChanged(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
     }
 
@@ -252,40 +194,4 @@
       var dataset = new Dataset(variableNames, values);
       return dataset;
-    }
-
-    public event DataPreprocessingChangedEventHandler Changed;
-    protected virtual void OnChanged(DataPreprocessingChangedEventType type, int column, int row) {
-      var listeners = Changed;
-      if (listeners != null) listeners(this, new DataPreprocessingChangedEventArgs(type, column, row));
-    }
-
-    public bool IsUndoAvailable {
-      get { return undoHistory.Count > 0; }
-    }
-
-    public void Undo() {
-      if (IsUndoAvailable) {
-        PDSnapshot previousSnapshot = undoHistory[undoHistory.Count - 1];
-        variableValues = previousSnapshot.VariableValues;
-        variableNames = previousSnapshot.VariableNames;
-        trainingToTestRatio = previousSnapshot.TrainingToTestRatio;
-        undoHistory.Remove(previousSnapshot);
-        OnChanged(previousSnapshot.ChangedType,
-          previousSnapshot.ChangedColumn,
-          previousSnapshot.ChangedRow);
-      }
-    }
-
-    public void BeginTransaction() {
-      SaveSnapshot(DataPreprocessingChangedEventType.Any, -1, -1);
-      transactionDepth++;
-    }
-
-    public void EndTransaction() {
-      transactionDepth--;
-      if (transactionDepth < 0)
-        throw new InvalidOperationException("There is no open transaction that can be ended.");
-      if (transactionDepth == 0)
-        OnChanged(DataPreprocessingChangedEventType.Any, -1, -1);
     }
 
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/SearchLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/SearchLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/SearchLogic.cs	(revision 10586)
@@ -26,7 +26,7 @@
 namespace HeuristicLab.DataPreprocessing {
   public class SearchLogic : ISearchLogic {
-    private readonly IPreprocessingData preprocessingData;
+    private readonly ITransactionalPreprocessingData preprocessingData;
 
-    public SearchLogic(IPreprocessingData thePreprocessingData) {
+    public SearchLogic(ITransactionalPreprocessingData thePreprocessingData) {
       preprocessingData = thePreprocessingData;
     }
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/StatisticsLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/StatisticsLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/StatisticsLogic.cs	(revision 10586)
@@ -29,8 +29,8 @@
   public class StatisticsLogic : IStatisticsLogic {
 
-    private readonly IPreprocessingData preprocessingData;
+    private readonly ITransactionalPreprocessingData preprocessingData;
     private readonly ISearchLogic searchLogic;
 
-    public StatisticsLogic(IPreprocessingData thePreprocessingData, ISearchLogic theSearchLogic) {
+    public StatisticsLogic(ITransactionalPreprocessingData thePreprocessingData, ISearchLogic theSearchLogic) {
       preprocessingData = thePreprocessingData;
       searchLogic = theSearchLogic;
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransactionalPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransactionalPreprocessingData.cs	(revision 10586)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransactionalPreprocessingData.cs	(revision 10586)
@@ -0,0 +1,175 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  internal class PDSnapshot {
+    public IDictionary<int, IList> VariableValues { get; set; }
+
+    public IList<string> VariableNames { get; set; }
+
+    public double TrainingToTestRatio { get; set; }
+
+    public DataPreprocessingChangedEventType ChangedType { get; set; }
+
+    public int ChangedColumn { get; set; }
+
+    public int ChangedRow { get; set; }
+  }
+
+  [Item("PreprocessingData", "Represents data used for preprocessing.")]
+  public class TransactionalPreprocessingData : PreprocessingData, ITransactionalPreprocessingData {
+
+    private const int MAX_UNDO_DEPTH = 5;
+
+    private IList<PDSnapshot> undoHistory;
+
+    private int transactionDepth = 0;
+
+    private TransactionalPreprocessingData(TransactionalPreprocessingData original, Cloner cloner)
+      : base(original, cloner) {
+      undoHistory = new List<PDSnapshot>();
+    }
+
+    public TransactionalPreprocessingData(IDataAnalysisProblemData problemData)
+      : base(problemData) {
+      undoHistory = new List<PDSnapshot>();
+    }
+
+    private void SaveSnapshot(DataPreprocessingChangedEventType changedType, int column, int row) {
+      if (transactionDepth > 0) return;
+
+      PDSnapshot currentSnapshot = new PDSnapshot();
+      currentSnapshot.VariableValues = CopyVariableValues(variableValues);
+      currentSnapshot.VariableNames = new List<string>(variableNames);
+      currentSnapshot.TrainingToTestRatio = trainingToTestRatio;
+      currentSnapshot.ChangedType = changedType;
+      currentSnapshot.ChangedColumn = column;
+      currentSnapshot.ChangedRow = row;
+
+      if (undoHistory.Count >= MAX_UNDO_DEPTH)
+        undoHistory.RemoveAt(0);
+
+      undoHistory.Add(currentSnapshot);
+    }
+
+    #region NamedItem abstract Member Implementations
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TransactionalPreprocessingData(this, cloner);
+    }
+
+    #endregion
+
+    #region Overridden IPreprocessingData Members
+
+    public override void SetCell<T>(int columnIndex, int rowIndex, T value) {
+      SaveSnapshot(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
+      base.SetCell<T>(columnIndex, rowIndex, value);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
+    }
+
+    public override void SetValues<T>(int columnIndex, IList<T> values) {
+      SaveSnapshot(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
+      base.SetValues<T>(columnIndex, values);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
+    }
+
+    public override void InsertRow(int rowIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
+      base.InsertRow(rowIndex);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
+    }
+
+    public override void DeleteRow(int rowIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
+      base.DeleteRow(rowIndex);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
+    }
+
+    public override void InsertColumn<T>(string variableName, int columnIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
+      base.InsertColumn<T>(variableName, columnIndex);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
+    }
+
+    public override void DeleteColumn(int columnIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
+      base.DeleteColumn(columnIndex);
+      if (transactionDepth <= 0)
+        OnChanged(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
+    }
+
+    #endregion
+
+    #region TransactionalPreprocessingData members
+
+    public event DataPreprocessingChangedEventHandler Changed;
+    protected virtual void OnChanged(DataPreprocessingChangedEventType type, int column, int row) {
+      var listeners = Changed;
+      if (listeners != null) listeners(this, new DataPreprocessingChangedEventArgs(type, column, row));
+    }
+
+    public bool IsUndoAvailable {
+      get { return undoHistory.Count > 0; }
+    }
+
+    public void Undo() {
+      if (IsUndoAvailable) {
+        PDSnapshot previousSnapshot = undoHistory[undoHistory.Count - 1];
+        variableValues = previousSnapshot.VariableValues;
+        variableNames = previousSnapshot.VariableNames;
+        trainingToTestRatio = previousSnapshot.TrainingToTestRatio;
+        undoHistory.Remove(previousSnapshot);
+        OnChanged(previousSnapshot.ChangedType,
+          previousSnapshot.ChangedColumn,
+          previousSnapshot.ChangedRow);
+      }
+    }
+
+    public void BeginTransaction() {
+      SaveSnapshot(DataPreprocessingChangedEventType.Any, -1, -1);
+      transactionDepth++;
+    }
+
+    public void EndTransaction() {
+      transactionDepth--;
+      if (transactionDepth < 0)
+        throw new InvalidOperationException("There is no open transaction that can be ended.");
+      if (transactionDepth == 0)
+        OnChanged(DataPreprocessingChangedEventType.Any, -1, -1);
+    }
+
+    #endregion
+  }
+}
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransformationLogic.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransformationLogic.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Implementations/TransformationLogic.cs	(revision 10586)
@@ -26,9 +26,9 @@
   public class TransformationLogic : ITransformationLogic {
 
-    private readonly IPreprocessingData preprocessingData;
+    private readonly ITransactionalPreprocessingData preprocessingData;
     private readonly ISearchLogic searchLogic;
     private readonly IStatisticsLogic statisticsLogic;
 
-    public TransformationLogic(IPreprocessingData thePreprocessingData, ISearchLogic theSearchLogic, IStatisticsLogic theStatisticsLogic) {
+    public TransformationLogic(ITransactionalPreprocessingData thePreprocessingData, ISearchLogic theSearchLogic, IStatisticsLogic theStatisticsLogic) {
       preprocessingData = thePreprocessingData;
       searchLogic = theSearchLogic;
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingContext.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingContext.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingContext.cs	(revision 10586)
@@ -29,5 +29,5 @@
     : IItem {
 
-    IPreprocessingData Data { get; }
+    ITransactionalPreprocessingData Data { get; }
 
     [Obsolete]
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingData.cs	(revision 10585)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/IPreprocessingData.cs	(revision 10586)
@@ -61,11 +61,4 @@
 
     Dataset ExportToDataset();
-
-    event DataPreprocessingChangedEventHandler Changed;
-
-    bool IsUndoAvailable { get; }
-    void Undo();
-    void BeginTransaction();
-    void EndTransaction();
   }
 }
Index: /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/ITransactionalPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/ITransactionalPreprocessingData.cs	(revision 10586)
+++ /branches/DataPreprocessing/HeuristicLab.DataPreprocessing/3.3/Interfaces/ITransactionalPreprocessingData.cs	(revision 10586)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.DataPreprocessing {
+
+  public interface ITransactionalPreprocessingData : IPreprocessingData {
+
+    event DataPreprocessingChangedEventHandler Changed;
+
+    bool IsUndoAvailable { get; }
+    void Undo();
+    void BeginTransaction();
+    void EndTransaction();
+  }
+}
