Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/IExampleParser.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/IExampleParser.cs	(revision 14744)
+++ 	(revision )
@@ -1,7 +1,0 @@
-﻿namespace HeuristicLab.BenchmarkSuite {
-  using HeuristicLab.BenchmarkSuite.Problems;
-
-  public interface IExampleParser {
-    Example ParseExample(string[] input, string[] output);
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Data.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Data.cs	(revision 14744)
+++ 	(revision )
@@ -1,56 +1,0 @@
-﻿namespace HeuristicLab.BenchmarkSuite.Problems {
-  using System.Linq;
-
-  using Common;
-  using Core;
-  using Persistence.Default.CompositeSerializers.Storable;
-
-  [StorableClass]
-  public class Data : NamedItem {
-    public Data(double bestResult, double worstResult, int testCount, int trainingCount,
-      int inputArgumentCount, int outputArgumentCount, Example[] exmaples, IExampleParser exampleParser) {
-      WorstResult = worstResult;
-      BestResult = bestResult;
-      OriginalTrainingCount = trainingCount;
-      OriginalTestCount = testCount;
-      InputArgumentCount = inputArgumentCount;
-      OutputArgumentCount = outputArgumentCount;
-      Examples = exmaples;
-      ExampleParser = exampleParser;
-
-      Description = "Examples";
-    }
-
-    [StorableConstructor]
-    public Data(bool deserializing) : base(deserializing) { }
-
-    public Data(Data origin, Cloner cloner) : base(origin, cloner) {
-      this.BestResult = origin.BestResult;
-      this.WorstResult = origin.WorstResult;
-      this.OriginalTestCount = origin.OriginalTestCount;
-      this.OriginalTrainingCount = origin.OriginalTrainingCount;
-      this.Examples = origin.Examples.Select(cloner.Clone).ToArray();
-    }
-
-    [Storable]
-    public readonly IExampleParser ExampleParser;
-    [Storable]
-    public readonly Example[] Examples;
-    [Storable]
-    public readonly int OriginalTestCount;
-    [Storable]
-    public readonly int OriginalTrainingCount;
-    [Storable]
-    public readonly double WorstResult;
-    [Storable]
-    public readonly double BestResult;
-    [Storable]
-    public readonly int InputArgumentCount;
-    [Storable]
-    public readonly int OutputArgumentCount;
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new Data(this, cloner);
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj	(revision 14745)
@@ -138,6 +138,7 @@
     <Compile Include="Push\Expressions\NameExpressions.cs" />
     <Compile Include="Push\Expressions\PopExpressions.cs" />
+    <Compile Include="Push\Expressions\PushProgram.bk.cs" />
+    <Compile Include="Push\Expressions\PushExpressions.cs" />
     <Compile Include="Push\Expressions\PushProgram.cs" />
-    <Compile Include="Push\Expressions\PushExpressions.cs" />
     <Compile Include="Push\Expressions\PushResultExpression.cs" />
     <Compile Include="Push\Expressions\RandExpressions.cs" />
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IReadonlyPushGpConfiguration.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IReadonlyPushGpConfiguration.cs	(revision 14744)
+++ 	(revision )
@@ -1,25 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Configuration {
-  using System.Collections.Generic;
-
-  public interface IReadonlyPushGpConfiguration {
-    bool IsBooleanStackEnabled { get; }
-    bool IsIntegerStackEnabled { get; }
-    bool IsFloatStackEnabled { get; }
-    bool IsCodeStackEnabled { get; }
-    bool IsNameStackEnabled { get; }
-    double ErcProbability { get; }
-    int EvalPushLimit { get; }
-    int MaxDepth { get; }
-    int MaxPointsInProgram { get; }
-    int MaxPointsInRandomExpression { get; }
-    bool TopLevelPushCode { get; }
-    bool TopLevelPopCode { get; }
-    int MinRandomInteger { get; }
-    int MaxRandomInteger { get; }
-    double MinRandomFloat { get; }
-    double MaxRandomFloat { get; }
-    double NewErcNameProbability { get; }
-
-    IReadOnlyList<string> EnabledExpressions { get; }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushGpConfiguration.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushGpConfiguration.cs	(revision 14744)
+++ 	(revision )
@@ -1,357 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Configuration {
-  using System;
-  using System.Collections.Generic;
-  using System.Linq;
-
-  using HeuristicLab.Common;
-  using HeuristicLab.Core;
-  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
-
-  [StorableClass]
-  public class PushGpConfiguration : NamedItem, IReadonlyPushGpConfiguration, IEnabledExpressionsConfiguration {
-    private static readonly string itemName = "PushGP Configuration";
-
-    public PushGpConfiguration() {
-      this.EvalPushLimit = 4096;
-      this.MaxPointsInProgram = 128;
-      this.MaxPointsInRandomExpression = 64;
-
-      this.TopLevelPushCode = true;
-      this.TopLevelPopCode = false;
-
-      this.MinRandomInteger = -128;
-      this.MaxRandomInteger = 128;
-      this.MinRandomFloat = -128D;
-      this.MaxRandomFloat = 128D;
-      this.NewErcNameProbability = 0.5;
-      this.ErcProbability = 0.2;
-
-      this.EnabledExpressions = ExpressionTable.ExpressionNames.ToList();
-    }
-
-    [StorableConstructor]
-    public PushGpConfiguration(bool deserializing) : base(deserializing) { }
-
-    public PushGpConfiguration(PushGpConfiguration origin, Cloner cloner) : base(origin, cloner) {
-      this.EnabledExpressions = origin.EnabledExpressions.ToList();
-
-      this.EvalPushLimit = origin.EvalPushLimit;
-      this.MaxPointsInProgram = origin.MaxPointsInProgram;
-      this.MaxPointsInRandomExpression = origin.MaxPointsInRandomExpression;
-
-      this.TopLevelPushCode = origin.TopLevelPushCode;
-      this.TopLevelPopCode = origin.TopLevelPopCode;
-
-      this.MinRandomInteger = origin.MinRandomInteger;
-      this.MaxRandomInteger = origin.MaxRandomInteger;
-      this.MinRandomFloat = origin.MinRandomFloat;
-      this.MaxRandomFloat = origin.MaxRandomFloat;
-      this.NewErcNameProbability = origin.NewErcNameProbability;
-      this.ErcProbability = origin.ErcProbability;
-
-      this.isBooleanStackEnabled = origin.IsBooleanStackEnabled;
-      this.isIntegerStackEnabled = origin.IsIntegerStackEnabled;
-      this.isFloatStackEnabled = origin.IsFloatStackEnabled;
-      this.isNameStackEnabled = origin.IsNameStackEnabled;
-      this.isCodeStackEnabled = origin.IsCodeStackEnabled;
-      this.isExecStackEnabled = origin.IsExecStackEnable;
-    }
-
-    public event EventHandler<EnabledExpressionsChangedEventArgs> EnabledExpressionsChanged;
-
-    [Storable]
-    public IList<string> EnabledExpressions { get; private set; }
-
-    IReadOnlyList<string> IReadonlyPushGpConfiguration.EnabledExpressions { get { return this.EnabledExpressions as IReadOnlyList<string>; } }
-
-    [Storable]
-    private bool isBooleanStackEnabled = true;
-
-    public bool IsBooleanStackEnabled
-    {
-      get
-      {
-        return this.isBooleanStackEnabled;
-      }
-
-      set
-      {
-        if (this.isBooleanStackEnabled == value) return;
-
-        this.isBooleanStackEnabled = value;
-
-        if (this.isBooleanStackEnabled) EnableExpressionOfStack(StackType.Boolean);
-        else DisableExpressionOfStack(StackType.Boolean);
-      }
-    }
-
-    [Storable]
-    private bool isIntegerStackEnabled = true;
-
-    public bool IsIntegerStackEnabled
-    {
-      get
-      {
-        return this.isIntegerStackEnabled;
-      }
-
-      set
-      {
-        if (this.isIntegerStackEnabled == value) return;
-
-        this.isIntegerStackEnabled = value;
-
-        if (this.isIntegerStackEnabled) EnableExpressionOfStack(StackType.Integer);
-        else DisableExpressionOfStack(StackType.Integer);
-      }
-    }
-
-    [Storable]
-    private bool isFloatStackEnabled = true;
-
-    public bool IsFloatStackEnabled
-    {
-      get
-      {
-        return this.isFloatStackEnabled;
-      }
-
-      set
-      {
-        if (this.isFloatStackEnabled == value) return;
-
-        this.isFloatStackEnabled = value;
-
-        if (this.isFloatStackEnabled) EnableExpressionOfStack(StackType.Float);
-        else DisableExpressionOfStack(StackType.Float);
-      }
-    }
-
-    [Storable]
-    private bool isCodeStackEnabled = true;
-
-    public bool IsCodeStackEnabled
-    {
-      get
-      {
-        return this.isCodeStackEnabled;
-      }
-
-      set
-      {
-        if (this.isCodeStackEnabled == value) return;
-
-        this.isCodeStackEnabled = value;
-
-        if (this.isCodeStackEnabled) EnableExpressionOfStack(StackType.Code);
-        else DisableExpressionOfStack(StackType.Code);
-      }
-    }
-
-    [Storable]
-    private bool isExecStackEnabled = true;
-
-    public bool IsExecStackEnable
-    {
-      get
-      {
-        return this.isExecStackEnabled;
-      }
-
-      set
-      {
-        if (this.isExecStackEnabled == value) return;
-
-        this.isExecStackEnabled = value;
-
-        if (this.isExecStackEnabled) EnableExpressionOfStack(StackType.Exec);
-        else DisableExpressionOfStack(StackType.Exec);
-      }
-    }
-
-    [Storable]
-    private bool isNameStackEnabled = true;
-
-    public bool IsNameStackEnabled
-    {
-      get
-      {
-        return this.isNameStackEnabled;
-      }
-
-      set
-      {
-        if (this.isNameStackEnabled == value) return;
-
-        this.isNameStackEnabled = value;
-
-        if (this.isNameStackEnabled) EnableExpressionOfStack(StackType.Name);
-        else DisableExpressionOfStack(StackType.Name);
-      }
-    }
-
-    [Storable]
-    public double ErcProbability { get; set; }
-
-    /// <summary>
-    ///     This is the maximum allowed number of "executions" in a single top-level call to the interpreter.
-    ///     The execution of a single Push instruction counts as one execution, as does the processing of a single literal,
-    ///     as does the descent into one layer of parentheses (that is, the processing of the "(" counts as one execution).
-    ///     When this limit is exceeded the interpreter aborts immediately, leaving its stacks in the states they were in prior
-    ///     to the abort (so they may still be examined by a calling program). Whether or not this counts as an "abnormal"
-    ///     termination
-    ///     is up to the calling program.
-    /// </summary>
-    [Storable]
-    public int EvalPushLimit { get; set; }
-
-    /// <summary>
-    /// This is the maximum of depth a push program can have. Expressions, which lead to exceed this limit are interpreted as NOOP.
-    /// </summary>
-    [Storable]
-    public int MaxDepth { get; set; }
-
-    /// <summary>
-    ///     This is the maximum size of an item on the CODE stack, expressed as a number of points.
-    ///     A point is an instruction, a literal, or a pair of parentheses. Any instruction that would cause this limit to be
-    ///     exceeded
-    ///     should instead act as a NOOP, leaving all stacks in the states that they were in before the execution of the
-    ///     instruction.
-    /// </summary>
-    [Storable]
-    public int MaxPointsInProgram { get; set; }
-
-    /// <summary>
-    ///     The maximum number of points in an expression produced by the CODE.RAND instruction.
-    /// </summary>
-    [Storable]
-    public int MaxPointsInRandomExpression { get; set; }
-
-    /// <summary>
-    ///     When TRUE (which is the default), code passed to the top level of the interpreter
-    ///     will be pushed onto the CODE stack prior to execution.
-    /// </summary>
-    [Storable]
-    public bool TopLevelPushCode { get; set; }
-
-    /// <summary>
-    ///     When TRUE, the CODE stack will be popped at the end of top level calls to the interpreter. The default is FALSE.
-    /// </summary>
-    [Storable]
-    public bool TopLevelPopCode { get; set; }
-
-    /// <summary>
-    ///     The minimum INTEGER that will be produced as an ephemeral random INTEGER constant or from a call to INTEGER.RAND.
-    /// </summary>
-    [Storable]
-    public int MinRandomInteger { get; set; }
-
-    /// <summary>
-    ///     The maximum INTEGER that will be produced as an ephemeral random INTEGER constant or from a call to INTEGER.RAND.
-    /// </summary>
-    [Storable]
-    public int MaxRandomInteger { get; set; }
-
-    /// <summary>
-    ///     The minimum FLOAT that will be produced as an ephemeral random FLOAT constant or from a call to FLOAT.RAND.
-    /// </summary>
-    [Storable]
-    public double MinRandomFloat { get; set; }
-
-    /// <summary>
-    ///     The maximum FLOAT that will be produced as an ephemeral random FLOAT constant or from a call to FLOAT.RAND.
-    /// </summary>
-    [Storable]
-    public double MaxRandomFloat { get; set; }
-
-    /// <summary>
-    ///     The probability that the selection of the ephemeral
-    ///     random NAME constant for inclusion in randomly generated code will produce a new name
-    ///     (rather than a name that was previously generated).
-    /// </summary>
-    [Storable]
-    public double NewErcNameProbability { get; set; }
-
-    public void EnableExpressionOfStack(StackType type) {
-      foreach (var name in ExpressionTable.StackTypeToNamesTable[type]) {
-        EnableExpression(name);
-      }
-    }
-
-    public void DisableExpressionOfStack(StackType type) {
-      foreach (var name in ExpressionTable.StackTypeToNamesTable[type]) {
-        DisableExpression(name);
-      }
-    }
-
-    public void EnableExpression(string name) {
-      if (EnabledExpressions.Contains(name)) return;
-
-      EnabledExpressions.Add(name);
-
-      if (EnabledExpressionsChanged != null) {
-        EnabledExpressionsChanged.Invoke(this, new EnabledExpressionsChangedEventArgs(
-          new[] { name },
-          new string[0]));
-      }
-    }
-
-    public void DisableExpression(string name) {
-      if (!EnabledExpressions.Contains(name)) return;
-
-      EnabledExpressions.Remove(name);
-
-      if (EnabledExpressionsChanged != null) {
-        EnabledExpressionsChanged.Invoke(this, new EnabledExpressionsChangedEventArgs(
-          new string[0],
-          new[] { name }));
-      }
-    }
-
-    public void EnableExpression<T>() where T : Expression {
-      var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(PushExpressionAttribute));
-      EnableExpression(attribute.ExpressionName);
-    }
-
-    public void DisableExpression<T>() where T : Expression {
-      var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(PushExpressionAttribute));
-      DisableExpression(attribute.ExpressionName);
-    }
-
-    public void EnableStack(StackType type) {
-      SetStack(type, true);
-    }
-
-    public void DisableStack(StackType type) {
-      SetStack(type, false);
-    }
-
-    private void SetStack(StackType type, bool value) {
-      switch (type) {
-        case StackType.Boolean:
-          IsBooleanStackEnabled = value;
-          break;
-        case StackType.Integer:
-          IsIntegerStackEnabled = value;
-          break;
-        case StackType.Float:
-          IsFloatStackEnabled = value;
-          break;
-        case StackType.Name:
-          IsNameStackEnabled = value;
-          break;
-        case StackType.Code:
-          IsCodeStackEnabled = value;
-          break;
-        default: throw new InvalidOperationException("Stacktype unkown");
-      }
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PushGpConfiguration(this, cloner);
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs	(revision 14745)
@@ -114,9 +114,9 @@
 
       if (isFirstList) {
-        var expand1 = first as ExecExpandExpression;
+        var expand1 = first as PushProgram;
 
         if (isSecondList) {
-          var expand2 = second as ExecExpandExpression;
-          var size = expand2.State.Expressions.Count + expand1.State.Expressions.Count;
+          var expand2 = second as PushProgram;
+          var size = expand2.State.Length + expand1.State.Length;
 
           // if size > maxPointsInProgram this expressions results in a NOOP
@@ -125,13 +125,13 @@
           result = new Expression[size];
 
-          Array.Copy(expand2.State.Expressions as Expression[], result, expand2.State.Expressions.Count);
+          Array.Copy(expand2.State, result, expand2.State.Length);
           Array.Copy(
-              expand1.State.Expressions as Expression[],
+              expand1.State,
               0,
               result,
-              expand2.State.Expressions.Count,
-              expand1.State.Expressions.Count);
+              expand2.State.Length,
+              expand1.State.Length);
         } else {
-          var size = expand1.State.Expressions.Count + 1;
+          var size = expand1.State.Length + 1;
 
           // if size > maxPointsInProgram this expressions results in a NOOP
@@ -141,10 +141,10 @@
           result[0] = second;
 
-          Array.Copy(expand1.State.Expressions as Expression[], 0, result, 1, expand1.State.Expressions.Count);
+          Array.Copy(expand1.State, 0, result, 1, expand1.State.Length);
         }
       } else if (isSecondList) {
-        var expand2 = second as ExecExpandExpression;
-
-        var size = expand2.State.Expressions.Count + 1;
+        var expand2 = second as PushProgram;
+
+        var size = expand2.State.Length + 1;
 
         // if size > maxPointsInProgram this expressions results in a NOOP
@@ -154,10 +154,10 @@
         result[0] = first;
 
-        Array.Copy(expand2.State.Expressions as Expression[], 0, result, 1, expand2.State.Expressions.Count);
+        Array.Copy(expand2.State as Expression[], 0, result, 1, expand2.State.Length);
       } else {
         result = new[] { second, first };
       }
 
-      var expression = new ExecExpandExpression(result);
+      var expression = new PushProgram(result);
 
       interpreter.CodeStack.SetTop(expression);
@@ -194,10 +194,10 @@
     public override bool Eval(IPushInterpreter interpreter) {
       if ((interpreter.CodeStack.Count == 0) ||
-          (interpreter.CodeStack.Top.GetType() != typeof(ExecExpandExpression))) return false;
-
-      var expand = interpreter.CodeStack.Top as ExecExpandExpression;
-
-      if (expand.State.IsEmpty) return false;
-      var first = expand.State.Expressions[expand.State.Expressions.Count - 1];
+          (interpreter.CodeStack.Top.GetType() != typeof(PushProgram))) return false;
+
+      var expand = interpreter.CodeStack.Top as PushProgram;
+
+      if (expand.IsEmpty) return false;
+      var first = expand.State[expand.State.Length - 1];
 
       interpreter.CodeStack.SetTop(first);
@@ -217,19 +217,19 @@
       if (interpreter.CodeStack.Count == 0) return false;
 
-      ExecExpandExpression expandExpression;
+      PushProgram expandExpression;
       var top = interpreter.CodeStack.Top;
 
       if (top.CanExpand) {
-        var expand = (ExecExpandExpression)top;
-
-        if (expand.State.IsEmpty) return false;
-        var length = expand.State.Expressions.Count - 1;
+        var expand = (PushProgram)top;
+
+        if (expand.IsEmpty) return false;
+        var length = expand.State.Length - 1;
         var newExpressions = new Expression[length];
 
-        Array.Copy((Expression[])expand.State.Expressions, 0, newExpressions, 0, length);
-
-        expandExpression = new ExecExpandExpression(newExpressions);
+        Array.Copy((Expression[])expand.State, 0, newExpressions, 0, length);
+
+        expandExpression = new PushProgram(newExpressions);
       } else {
-        expandExpression = ExecExpandExpression.Empty;
+        expandExpression = PushProgram.Empty;
       }
 
@@ -250,9 +250,9 @@
         return false;
 
-      ExecExpandExpression result;
+      PushProgram result;
 
       if (interpreter.CodeStack.Top.CanExpand) {
-        var first = (ExecExpandExpression)interpreter.CodeStack.Pop();
-        var size = first.State.Expressions.Count + 1;
+        var first = (PushProgram)interpreter.CodeStack.Pop();
+        var size = first.State.Length + 1;
 
         if (size > interpreter.Configuration.MaxPointsInProgram) return false;
@@ -260,10 +260,10 @@
         var expressions = new Expression[size];
 
-        expressions[first.State.Expressions.Count] = interpreter.CodeStack.Top;
-        Array.Copy(first.State.Expressions as Expression[], expressions, first.State.Expressions.Count);
-
-        result = new ExecExpandExpression(expressions);
+        expressions[first.State.Length] = interpreter.CodeStack.Top;
+        Array.Copy(first.State as Expression[], expressions, first.State.Length);
+
+        result = new PushProgram(expressions);
       } else {
-        result = new ExecExpandExpression(interpreter.CodeStack.Pop(), interpreter.CodeStack.Top);
+        result = new PushProgram(interpreter.CodeStack.Pop(), interpreter.CodeStack.Top);
       }
 
@@ -286,11 +286,11 @@
       if ((interpreter.CodeStack.Count < 2) ||
           (interpreter.CodeStack[interpreter.CodeStack.Count - 2].GetType() !=
-           typeof(ExecExpandExpression))) return false;
+           typeof(PushProgram))) return false;
 
       var target = interpreter.CodeStack.Pop();
       var source = interpreter.CodeStack.Top;
 
-      var container = GetContainer(source as ExecExpandExpression, target);
-      var result = container ?? ExecExpandExpression.Empty;
+      var container = GetContainer(source as PushProgram, target);
+      var result = container ?? PushProgram.Empty;
 
       interpreter.CodeStack.SetTop(result);
@@ -298,17 +298,17 @@
     }
 
-    private static ExecExpandExpression GetContainer(ExecExpandExpression current, Expression target) {
+    private static PushProgram GetContainer(PushProgram current, Expression target) {
       if (current == target)
         return null;
 
       var subContainer =
-          current.State.Expressions.Where(e => e.CanExpand)
-              .Select(e => GetContainer(e as ExecExpandExpression, target))
+          current.State.Where(e => e.CanExpand)
+              .Select(e => GetContainer(e as PushProgram, target))
               .Where(e => e != null);
 
-      var execExpandExpressions = subContainer as IList<ExecExpandExpression> ?? subContainer.ToList();
+      var execExpandExpressions = subContainer as IList<PushProgram> ?? subContainer.ToList();
       return execExpandExpressions.Any()
-          ? execExpandExpressions.OrderBy(c => c.State.Expressions.Count).LastOrDefault()
-          : current.State.Expressions.Contains(target)
+          ? execExpandExpressions.OrderBy(c => c.State.Length).LastOrDefault()
+          : current.State.Contains(target)
               ? current
               : null;
@@ -328,6 +328,6 @@
 
       var values = interpreter.CodeStack.Pop(2);
-      var second = (ExecExpandExpression)values[0];
-      var contains = second.State.Expressions.Contains(values[1]);
+      var second = (PushProgram)values[0];
+      var contains = second.State.Contains(values[1]);
 
       interpreter.BooleanStack.Push(contains);
@@ -414,7 +414,7 @@
     private void DetermineUniqueItems(Expression source, IDictionary<int, int> items) {
       if (source.CanExpand) {
-        var expand = source as ExecExpandExpression;
-
-        foreach (var e in expand.State.Expressions) {
+        var expand = source as PushProgram;
+
+        foreach (var e in expand.State) {
           var id = e.GetHashCode();
           if (!items.ContainsKey(id)) items.Add(id, 1);
@@ -445,6 +445,6 @@
         return false;
 
-      var expression = (ExecExpandExpression)interpreter.CodeStack.Top;
-      var index = (int)Math.Abs(interpreter.IntegerStack.Pop() % expression.State.TotalCount);
+      var expression = (PushProgram)interpreter.CodeStack.Top;
+      var index = (int)Math.Abs(interpreter.IntegerStack.Pop() % expression.TotalCount);
       var result = expression.GetFromTree(index);
 
@@ -536,14 +536,14 @@
 
       var source = interpreter.CodeStack[interpreter.CodeStack.Count - 2];
-      var target = (ExecExpandExpression)interpreter.CodeStack.Pop();
+      var target = (PushProgram)interpreter.CodeStack.Pop();
       var index = (int)interpreter.IntegerStack.Pop();
 
       Expression[] newExpressions;
-      if (target.State.Expressions.Count > 0) {
-        index = target.State.Expressions.Count - 1 - Math.Abs(index % target.State.Expressions.Count);
-
-        newExpressions = target.State.CopyExpressions();
+      if (target.State.Length > 0) {
+        index = target.State.Length - 1 - Math.Abs(index % target.State.Length);
+
+        newExpressions = target.CopyExpressions();
         newExpressions[index] = source.CanExpand
-            ? ((ExecExpandExpression)source).Copy()
+            ? ((PushProgram)source).Copy()
             : source;
       } else {
@@ -551,5 +551,5 @@
       }
 
-      var result = new ExecExpandExpression(newExpressions);
+      var result = new PushProgram(newExpressions);
       interpreter.CodeStack.SetTop(result);
 
@@ -573,5 +573,5 @@
 
       if (expression.CanExpand)
-        count = ((ExecExpandExpression)expression).State.Expressions.Count;
+        count = ((PushProgram)expression).State.Length;
 
       interpreter.IntegerStack.Push(count);
@@ -591,5 +591,5 @@
       var first = interpreter.CodeStack.Pop();
       var second = interpreter.CodeStack.Top;
-      var expandExpression = new ExecExpandExpression(second, first);
+      var expandExpression = new PushProgram(second, first);
 
       interpreter.CodeStack.SetTop(expandExpression);
@@ -611,5 +611,5 @@
 
       var contains = expressions[1].CanExpand
-          ? ((ExecExpandExpression)expressions[1]).State.Expressions.Contains(expressions[0])
+          ? ((PushProgram)expressions[1]).State.Contains(expressions[0])
           : expressions[1].Equals(expressions[0]);
 
@@ -636,13 +636,13 @@
 
       if (expression.CanExpand) {
-        var subExpression = (ExecExpandExpression)expression;
-
-        if (subExpression.State.IsEmpty) {
-          nthExpression = ExecExpandExpression.Empty;
+        var subExpression = (PushProgram)expression;
+
+        if (subExpression.IsEmpty) {
+          nthExpression = PushProgram.Empty;
         } else {
-          var index = (int)(subExpression.State.Expressions.Count - 1 -
-                             Math.Abs(n % subExpression.State.Expressions.Count));
-
-          nthExpression = subExpression.State.Expressions[index];
+          var index = (int)(subExpression.State.Length - 1 -
+                             Math.Abs(n % subExpression.State.Length));
+
+          nthExpression = subExpression.State[index];
         }
       } else {
@@ -672,13 +672,13 @@
       var expression = interpreter.CodeStack.Top;
 
-      Expression nthExpression = null;
+      Expression nthExpression;
 
       if (expression.CanExpand) {
-        var subExpressions = ((ExecExpandExpression)expression).State.Expressions;
-
-        if (subExpressions.Count < 2) {
-          nthExpression = ExecExpandExpression.Empty;
+        var subExpressions = ((PushProgram)expression).State;
+
+        if (subExpressions.Length < 2) {
+          nthExpression = PushProgram.Empty;
         } else {
-          var index = (int)(subExpressions.Count - 2 - Math.Abs(n % (subExpressions.Count - 1)));
+          var index = (int)(subExpressions.Length - 2 - Math.Abs(n % (subExpressions.Length - 1)));
 
           nthExpression = subExpressions[index];
@@ -702,5 +702,5 @@
       if (interpreter.CodeStack.Count == 0) return false;
 
-      var result = interpreter.CodeStack.Pop().Equals(ExecExpandExpression.Empty);
+      var result = interpreter.CodeStack.Pop().Equals(PushProgram.Empty);
       interpreter.BooleanStack.Push(result);
 
@@ -724,7 +724,7 @@
       var position = -1;
       if (first.CanExpand) {
-        var expand = (ExecExpandExpression)first;
-        position = expand.State.Expressions.Count - 1
-                   - Array.FindIndex((Expression[])expand.State.Expressions, e => e.Equals(second));
+        var expand = (PushProgram)first;
+        position = expand.State.Length - 1
+                   - Array.FindIndex((Expression[])expand.State, e => e.Equals(second));
       } else if (first.Equals(second)) {
         position = 0;
@@ -748,5 +748,5 @@
       var expression = interpreter.CodeStack.Pop();
       var points = expression.CanExpand
-          ? ((ExecExpandExpression)expression).State.Expressions.Count
+          ? ((PushProgram)expression).State.Length
           : 1;
 
@@ -767,19 +767,19 @@
     public override bool Eval(IPushInterpreter interpreter) {
       if ((interpreter.CodeStack.Count < 3) || (interpreter.CodeStack.Top.GetType() !=
-                                                typeof(ExecExpandExpression))) return false;
+                                                typeof(PushProgram))) return false;
 
       var expressions = interpreter.CodeStack.Pop(2);
       var third = interpreter.CodeStack.Top;
       var second = expressions[0];
-      var first = expressions[1] as ExecExpandExpression;
-      var newExpressions = new Expression[first.State.Expressions.Count];
-
-      for (var i = 0; i < first.State.Expressions.Count; i++)
-        newExpressions[i] = first.State.Expressions[i].Equals(third)
+      var first = expressions[1] as PushProgram;
+      var newExpressions = new Expression[first.State.Length];
+
+      for (var i = 0; i < first.State.Length; i++)
+        newExpressions[i] = first.State[i].Equals(third)
             ? second
             /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
-            : first.State.Expressions[i];
-
-      var result = new ExecExpandExpression(newExpressions);
+            : first.State[i];
+
+      var result = new PushProgram(newExpressions);
 
       interpreter.CodeStack.SetTop(result);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs	(revision 14745)
@@ -1,6 +1,3 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
-  using System;
-  using System.Collections.Generic;
-  using System.Linq;
 
   using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
@@ -8,69 +5,4 @@
 
   using Interpreter;
-
-  public class ExecExpandExpression : StatefulExpression<PushProgram> {
-    public static readonly ExecExpandExpression Empty = new ExecExpandExpression(PushProgram.Empty);
-
-    public ExecExpandExpression(PushProgram program)
-      : base(program) {
-    }
-
-    public ExecExpandExpression(params Expression[] state) : this(new PushProgram(state)) {
-    }
-
-    public ExecExpandExpression(IEnumerable<Expression> state) : this(state.ToArray()) {
-      // TODO: lazy evaluation of ToArray()
-    }
-
-    public override string StringRepresentation { get { return this.State.ToString(); } }
-
-    public ExecExpandExpression Copy() {
-      // as the empty list is a static stateless expression, no copy required
-      return ReferenceEquals(this, Empty) || this.State.IsEmpty
-        ? Empty
-        : new ExecExpandExpression(this.State.Copy());
-    }
-
-    public override bool Eval(IPushInterpreter interpreter) {
-      interpreter.ExecStack.Push(this.State.Expressions);
-      return true;
-    }
-
-    /// <summary>
-    ///     Returns the element with the given index whereby the tree is indexed in depth first manner
-    /// </summary>
-    /// <param name="index">The index of the required element</param>
-    /// <returns>The required element</returns>
-    public Expression GetFromTree(int index) {
-      return GetFromTree(index, (root, parent, child, childIndex, parentIndex) => child);
-    }
-
-    /// <returns>The required element</returns>
-    public T GetFromTree<T>(int index,
-        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
-      return GetFromTree(index, 0, null, resolver);
-    }
-
-    private T GetFromTree<T>(int index, int parentIndex, ExecExpandExpression parent,
-        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
-      if (index == 0) return resolver(parent, parent, this, 0, parentIndex);
-
-      var min = State.Expressions.Count - 1;
-      var max = 0;
-      var mid = (min + max) / 2;
-
-      while ((max <= min) && (this.State.TreeIndex[mid] != index)) {
-        if (this.State.TreeIndex[mid] > index) max = mid + 1;
-        else min = mid - 1;
-
-        mid = (min + max) / 2;
-      }
-
-      return this.State.TreeIndex[mid] == index
-          ? resolver(parent, this, State.Expressions[mid], mid, parentIndex)
-          : (State.Expressions[mid + 1] as ExecExpandExpression).GetFromTree(index - this.State.TreeIndex[mid + 1], mid + 1,
-              this, resolver);
-    }
-  }
 
   /// <summary>
@@ -110,5 +42,5 @@
       var execYExpression = ExpressionTable.GetStatelessExpression<ExecYExpression>();
 
-      var result = new ExecExpandExpression(top, execYExpression);
+      var result = new PushProgram(top, execYExpression);
 
       interpreter.ExecStack.SetTop(result);
@@ -149,5 +81,5 @@
       var c = interpreter.ExecStack.Top;
 
-      var newTop = new ExecExpandExpression(c, b);
+      var newTop = new PushProgram(c, b);
 
       interpreter.ExecStack.SetTop(newTop);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs	(revision 14745)
@@ -8,5 +8,5 @@
 
   public abstract class Expression {
-    public bool CanExpand { get { return this.GetType() == typeof(ExecExpandExpression); } }
+    public bool CanExpand { get { return this.GetType() == typeof(PushProgram); } }
 
     public static readonly IReadOnlyCollection<Expression> EmptyContainer = new Expression[0];
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs	(revision 14745)
@@ -123,5 +123,5 @@
     }
 
-    public static ExecExpandExpression GetProgram(int[] index) {
+    public static PushProgram GetProgram(int[] index) {
       var expressions = new Expression[index.Length];
 
@@ -130,6 +130,5 @@
       }
 
-      var program = new PushProgram(expressions);
-      return new ExecExpandExpression(program);
+      return new PushProgram(expressions);
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.bk.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.bk.cs	(revision 14745)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.bk.cs	(revision 14745)
@@ -0,0 +1,202 @@
+﻿//using System.Collections.Generic;
+
+//namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+//  using System.Diagnostics;
+//  using System.Linq;
+
+//  public class PushProgram {
+
+//    private const string Prefix = "(";
+//    private const string PrefixReduced = "[";
+//    private const string Postfix = ")";
+//    private const string PostfixReduced = "]";
+//    private const string Delimiter = " ";
+
+//    public static readonly PushProgram Empty = new PushProgram(new Expression[0]);
+
+//    public readonly IReadOnlyList<Expression> Expressions;
+//    public bool IsEmpty { get; private set; }
+
+//    public PushProgram(Expression[] expressions) {
+//      this.Expressions = expressions;
+//      this.IsEmpty = expressions.Length == 0;
+//    }
+
+//    private string stringRepresentation;
+//    private string StringRepresentation
+//    {
+//      get
+//      {
+//        if (string.IsNullOrEmpty(stringRepresentation))
+//          stringRepresentation = BuildString();
+//        return stringRepresentation;
+//      }
+//    }
+
+//    private int depth = -1;
+//    private int Depth
+//    {
+//      get
+//      {
+//        if (depth == -1) depth = CalcDepth();
+//        return depth;
+//      }
+//    }
+
+//    private int[] treeIndex = null;
+//    public int[] TreeIndex
+//    {
+//      get
+//      {
+//        return this.treeIndex ?? (this.treeIndex = this.BuildTreeIndex());
+//      }
+//    }
+
+//    private int hashCode;
+//    private int HashCode
+//    {
+//      get
+//      {
+//        if (hashCode == default(int)) hashCode = HashExpressions();
+//        return hashCode;
+//      }
+//    }
+
+//    public override int GetHashCode() {
+//      return HashCode;
+//    }
+
+//    public override string ToString() {
+//      return this.StringRepresentation;
+//    }
+
+//    /// <summary>
+//    /// Returns the amount of elements in the whole tree
+//    /// </summary>
+//    /// <returns></returns>
+//    public int TotalCount
+//    {
+//      get
+//      {
+//        return this.IsEmpty
+//            ? 1
+//            // + 1 because "this" is also counted
+//            : TreeIndex[0] + 1;
+//      }
+//    }
+
+//    public IEnumerable<Expression> DepthFirst() {
+//      foreach (var expr in this.Expressions) {
+//        if (expr.CanExpand) {
+//          var expandExpr = (PushProgram)expr;
+
+//          foreach (var sub in expandExpr.State.DepthFirst())
+//            yield return sub;
+//        } else yield return expr;
+//      }
+//    }
+
+//    public PushProgram Copy() {
+//      return IsEmpty ? this : new PushProgram((Expression[])Expressions) {
+//        stringRepresentation = this.stringRepresentation,
+//        hashCode = this.hashCode,
+//        depth = this.depth,
+//        treeIndex = this.treeIndex
+//      };
+//    }
+
+//    public Expression[] CopyExpressions() {
+//      var copy = new Expression[this.Expressions.Count];
+//      ((Expression[])this.Expressions).CopyTo(copy, Expressions.Count);
+
+//      return copy;
+//    }
+
+//    private int CalcDepth() {
+//      //var subExpressions = Expressions.Where(e => e.CanExpand);
+//      //var depth = subExpressions.Any()
+//      //    ? subExpressions.Select(e => e as PushProgram).Max(e => e.State.Depth) + 1
+//      //    : 1;
+
+//      ////return depth;
+
+//      var maxDepth = 1;
+//      for (var i = 0; i < Expressions.Count; i++) {
+//        var expression = Expressions[i];
+//        if (!expression.CanExpand) continue;
+//        var expandExpression = (PushProgram)expression;
+
+//        if (expandExpression.State.Depth > maxDepth)
+//          maxDepth = expandExpression.State.Depth;
+//      }
+
+//      return maxDepth + 1;
+//    }
+
+//    private string BuildString() {
+//      // prevent too big string
+//      return this.TotalCount > 50
+//        ? PrefixReduced + this.Expressions.Count + PostfixReduced
+//        : Prefix + string.Join(Delimiter, this.Expressions.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
+//    }
+
+//    private int[] BuildTreeIndex() {
+//      var local_treeIndex = new int[this.Expressions.Count];
+
+//      var next = 1;
+
+//      for (var i = this.Expressions.Count - 1; i >= 0; i--) {
+//        var subExpression = this.Expressions[i];
+
+//        local_treeIndex[i] = next;
+
+//        if (subExpression.CanExpand) {
+//          next += ((PushProgram)subExpression).State.TotalCount;
+//        } else {
+//          next++;
+//        }
+//      }
+
+//      return local_treeIndex;
+//    }
+
+//    private int HashExpressions() {
+//      var hash = 19 * 31 + this.GetType().FullName.GetHashCode();
+
+//      for (var i = 0; i < this.Expressions.Count; i++) {
+//        hash = hash * 31 + this.Expressions[i].GetHashCode();
+//      }
+
+//      return hash;
+//    }
+
+//    private static void CheckIfNested(int level, PushProgram target, PushProgram current,
+//        IList<PushProgram> visited) {
+//      if (visited.Any(x => ReferenceEquals(x, current)))
+//        Debugger.Break();
+
+//      visited.Add(current);
+//      if (level <= 0) {
+//        // hirarchy depth > level
+//        Debugger.Break();
+//        return;
+//      }
+
+//      for (var i = 0; i < current.State.Expressions.Count; i++) {
+//        if (current.State.Expressions[i].CanExpand)
+//          continue;
+
+//        var subExpression = current.State.Expressions[i] as PushProgram;
+
+//        if (ReferenceEquals(target, subExpression)) {
+//          // Endless recursion dedected
+//          Debugger.Break();
+//        }
+
+//        CheckIfNested(level - 1, target, subExpression, visited);
+//      }
+
+//      visited.RemoveAt(visited.Count - 1);
+//    }
+//  }
+//}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs	(revision 14745)
@@ -1,9 +1,13 @@
-﻿using System.Collections.Generic;
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
   using System.Diagnostics;
-  using System.Linq;
-
-  public class PushProgram {
+
+  using Interpreter;
+
+  public class PushProgram : StatefulExpression<Expression[]> {
+    public static readonly PushProgram Empty = new PushProgram();
 
     private const string Prefix = "(";
@@ -13,16 +17,16 @@
     private const string Delimiter = " ";
 
-    public static readonly PushProgram Empty = new PushProgram(new Expression[0]);
-
-    public readonly IReadOnlyList<Expression> Expressions;
-    public bool IsEmpty { get; private set; }
-
-    public PushProgram(Expression[] expressions) {
-      this.Expressions = expressions;
-      this.IsEmpty = expressions.Length == 0;
+    public readonly bool IsEmpty;
+
+    public PushProgram(params Expression[] state) : base(state) {
+      IsEmpty = state.Length == 0;
+    }
+
+    public PushProgram(IEnumerable<Expression> state) : this(state.ToArray()) {
+      // TODO: lazy evaluation of ToArray()
     }
 
     private string stringRepresentation;
-    private string StringRepresentation
+    public override string StringRepresentation
     {
       get
@@ -35,5 +39,5 @@
 
     private int depth = -1;
-    private int Depth
+    public int Depth
     {
       get
@@ -44,10 +48,10 @@
     }
 
-    private int[] treeIndex = null;
-    public int[] TreeIndex
-    {
-      get
-      {
-        return this.treeIndex ?? (this.treeIndex = this.BuildTreeIndex());
+    private int[] treeIndex;
+    private int[] TreeIndex
+    {
+      get
+      {
+        return treeIndex ?? (treeIndex = BuildTreeIndex());
       }
     }
@@ -61,4 +65,16 @@
         return hashCode;
       }
+    }
+
+    //public PushProgram Copy() {
+    //  // as the empty list is a static stateless expression, no copy required
+    //  return ReferenceEquals(this, Empty) || this.State.IsEmpty
+    //    ? Empty
+    //    : new PushProgram(this.State.Copy());
+    //}
+
+    public override bool Eval(IPushInterpreter interpreter) {
+      interpreter.ExecStack.Push(this.State);
+      return true;
     }
 
@@ -87,9 +103,9 @@
 
     public IEnumerable<Expression> DepthFirst() {
-      foreach (var expr in this.Expressions) {
+      foreach (var expr in this.State) {
         if (expr.CanExpand) {
-          var expandExpr = (ExecExpandExpression)expr;
-
-          foreach (var sub in expandExpr.State.DepthFirst())
+          var expandExpr = (PushProgram)expr;
+
+          foreach (var sub in expandExpr.DepthFirst())
             yield return sub;
         } else yield return expr;
@@ -98,5 +114,5 @@
 
     public PushProgram Copy() {
-      return IsEmpty ? this : new PushProgram((Expression[])Expressions) {
+      return IsEmpty ? this : new PushProgram(State) {
         stringRepresentation = this.stringRepresentation,
         hashCode = this.hashCode,
@@ -106,7 +122,10 @@
     }
 
-    public Expression[] CopyExpressions() {
-      var copy = new Expression[this.Expressions.Count];
-      ((Expression[])this.Expressions).CopyTo(copy, Expressions.Count);
+    public Expression[] CopyExpressions()
+    {
+      if (IsEmpty) return Empty.State;
+
+      var copy = new Expression[State.Length];
+      State.CopyTo(copy, 0);
 
       return copy;
@@ -114,19 +133,12 @@
 
     private int CalcDepth() {
-      //var subExpressions = Expressions.Where(e => e.CanExpand);
-      //var depth = subExpressions.Any()
-      //    ? subExpressions.Select(e => e as ExecExpandExpression).Max(e => e.State.Depth) + 1
-      //    : 1;
-
-      ////return depth;
-
       var maxDepth = 1;
-      for (var i = 0; i < Expressions.Count; i++) {
-        var expression = Expressions[i];
+      for (var i = 0; i < State.Length; i++) {
+        var expression = State[i];
         if (!expression.CanExpand) continue;
-        var expandExpression = (ExecExpandExpression)expression;
-
-        if (expandExpression.State.Depth > maxDepth)
-          maxDepth = expandExpression.State.Depth;
+        var expandExpression = (PushProgram)expression;
+
+        if (expandExpression.Depth > maxDepth)
+          maxDepth = expandExpression.Depth;
       }
 
@@ -137,20 +149,20 @@
       // prevent too big string
       return this.TotalCount > 50
-        ? PrefixReduced + this.Expressions.Count + PostfixReduced
-        : Prefix + string.Join(Delimiter, this.Expressions.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
+        ? PrefixReduced + this.State.Length + PostfixReduced
+        : Prefix + string.Join(Delimiter, this.State.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
     }
 
     private int[] BuildTreeIndex() {
-      var local_treeIndex = new int[this.Expressions.Count];
+      var local_treeIndex = new int[State.Length];
 
       var next = 1;
 
-      for (var i = this.Expressions.Count - 1; i >= 0; i--) {
-        var subExpression = this.Expressions[i];
+      for (var i = State.Length - 1; i >= 0; i--) {
+        var subExpression = State[i];
 
         local_treeIndex[i] = next;
 
         if (subExpression.CanExpand) {
-          next += ((ExecExpandExpression)subExpression).State.TotalCount;
+          next += ((PushProgram)subExpression).TotalCount;
         } else {
           next++;
@@ -164,6 +176,6 @@
       var hash = 19 * 31 + this.GetType().FullName.GetHashCode();
 
-      for (var i = 0; i < this.Expressions.Count; i++) {
-        hash = hash * 31 + this.Expressions[i].GetHashCode();
+      for (var i = 0; i < State.Length; i++) {
+        hash = hash * 31 + State[i].GetHashCode();
       }
 
@@ -171,6 +183,6 @@
     }
 
-    private static void CheckIfNested(int level, ExecExpandExpression target, ExecExpandExpression current,
-        IList<ExecExpandExpression> visited) {
+    private static void CheckIfNested(int level, PushProgram target, PushProgram current,
+        IList<PushProgram> visited) {
       if (visited.Any(x => ReferenceEquals(x, current)))
         Debugger.Break();
@@ -183,9 +195,9 @@
       }
 
-      for (var i = 0; i < current.State.Expressions.Count; i++) {
-        if (current.State.Expressions[i].CanExpand)
+      for (var i = 0; i < current.State.Length; i++) {
+        if (current.State[i].CanExpand)
           continue;
 
-        var subExpression = current.State.Expressions[i] as ExecExpandExpression;
+        var subExpression = current.State[i] as PushProgram;
 
         if (ReferenceEquals(target, subExpression)) {
@@ -199,4 +211,40 @@
       visited.RemoveAt(visited.Count - 1);
     }
+
+    /// <summary>
+    ///     Returns the element with the given index whereby the tree is indexed in depth first manner
+    /// </summary>
+    /// <param name="index">The index of the required element</param>
+    /// <returns>The required element</returns>
+    public Expression GetFromTree(int index) {
+      return GetFromTree(index, (root, parent, child, childIndex, parentIndex) => child);
+    }
+
+    /// <returns>The required element</returns>
+    public T GetFromTree<T>(int index,
+        Func<PushProgram, PushProgram, Expression, int, int, T> resolver) {
+      return GetFromTree(index, 0, null, resolver);
+    }
+
+    private T GetFromTree<T>(int index, int parentIndex, PushProgram parent,
+        Func<PushProgram, PushProgram, Expression, int, int, T> resolver) {
+      if (index == 0) return resolver(parent, parent, this, 0, parentIndex);
+
+      var min = State.Length - 1;
+      var max = 0;
+      var mid = (min + max) / 2;
+
+      while ((max <= min) && (TreeIndex[mid] != index)) {
+        if (TreeIndex[mid] > index) max = mid + 1;
+        else min = mid - 1;
+
+        mid = (min + max) / 2;
+      }
+
+      return TreeIndex[mid] == index
+          ? resolver(parent, this, State[mid], mid, parentIndex)
+          : (State[mid + 1] as PushProgram).GetFromTree(index - TreeIndex[mid + 1], mid + 1,
+              this, resolver);
+    }
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs	(revision 14745)
@@ -1,7 +1,4 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
-
-  public abstract class StatefulExpression<T> : Expression
-  {
+  public abstract class StatefulExpression<T> : Expression {
     public readonly T State;
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefullExpression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefullExpression.cs	(revision 14744)
+++ 	(revision )
@@ -1,40 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
-
-  public abstract class StatefullExpression<T> : Expression {
-
-    public readonly T State;
-
-    private int hashCode;
-    private int HashCode {
-      get {
-        if (hashCode == default(int)) hashCode = CalcHashCode();
-        return hashCode;
-      }
-    }
-
-    protected StatefullExpression(T state) {
-      this.State = state;
-    }
-
-    protected virtual int CalcHashCode() {
-      return this.State.GetHashCode();
-    }
-
-    public override bool Equals(object obj) {
-      if (ReferenceEquals(this, obj))
-        return true;
-
-      if (this.GetType() != obj.GetType())
-        return false;
-
-      var other = (StatefullExpression<T>)obj;
-
-      return ReferenceEquals(this.State, other.State) ||
-             this.GetHashCode() == other.GetHashCode();
-    }
-
-    public override int GetHashCode() {
-      return HashCode;
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs	(revision 14745)
@@ -24,8 +24,8 @@
     }
 
-    public static ExecExpandExpression RandomExpandExpression(int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+    public static PushProgram RandomExpandExpression(int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
       var program = RandomProgram(maxPoints, random, pushGpConfiguration, customExpressions);
 
-      return new ExecExpandExpression(program);
+      return new PushProgram(program);
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushGpInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushGpInterpreter.cs	(revision 14744)
+++ 	(revision )
@@ -1,44 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
-  using System.Collections.Generic;
-  using System.Threading;
-  using System.Threading.Tasks;
-  using Core;
-  using Expressions;
-
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-
-  using Stack;
-
-  public interface IPushGpInterpreter {
-    IRandom Random { get; set; }
-
-    IStack<Expression> CodeStack { get; }
-    IStack<Expression> ExecStack { get; }
-    IStack<string> NameStack { get; }
-    IStack<bool> BooleanStack { get; }
-    IStack<long> IntegerStack { get; }
-    IStack<double> FloatStack { get; }
-
-    IDictionary<string, Expression> CustomExpressions { get; }
-
-    IReadonlyPushGpConfiguration Configuration { get; }
-
-    bool IsNameQuoteFlagSet { get; set; }
-
-    void Clear();
-    void Run(string code, bool stepwise = false);
-    void Run(Expression program, bool stepwise = false);
-    void Run(PushProgram program, bool stepwise = false);
-    Task RunAsync(PushProgram program, bool paused = false, CancellationToken token = default(CancellationToken));
-    Task RunAsync(Expression program, bool paused = false, CancellationToken token = default(CancellationToken));
-    Task RunAsync(string code, bool paused = false, CancellationToken token = default(CancellationToken));
-    Task AbortAndResetAsync();
-    Task AbortAsync();
-    Task PauseAsync();
-    void Resume();
-    Task ResumeAsync();
-
-    void Step();
-    void PrintStacks();
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs	(revision 14745)
@@ -28,8 +28,8 @@
     void Clear();
     void Run(string code, bool stepwise = false);
-    void Run(Expression program, bool stepwise = false);
-    void Run(PushProgram program, bool stepwise = false);
-    Task RunAsync(PushProgram program, bool paused = false, CancellationToken token = default(CancellationToken));
-    Task RunAsync(Expression program, bool paused = false, CancellationToken token = default(CancellationToken));
+    void Run(Expression expression, bool stepwise = false);
+    //void Run(PushProgram program, bool stepwise = false);
+    //Task RunAsync(PushProgram program, bool paused = false, CancellationToken token = default(CancellationToken));
+    Task RunAsync(Expression expression, bool paused = false, CancellationToken token = default(CancellationToken));
     Task RunAsync(string code, bool paused = false, CancellationToken token = default(CancellationToken));
     Task AbortAndResetAsync();
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PooledPushGpInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PooledPushGpInterpreter.cs	(revision 14744)
+++ 	(revision )
@@ -1,22 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
-  using System;
-
-  using HeuristicLab.Core;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-
-  public class PooledPushGpInterpreter : PushGpInterpreter, IDisposable {
-
-    private readonly PushGpInterpreterPool pool;
-
-    public PooledPushGpInterpreter(PushGpInterpreterPool pool, PushGpConfiguration config, IRandom random = null)
-      : base(config, random) {
-      this.pool = pool;
-    }
-
-    public void Dispose() {
-      this.Reset();
-      this.Configuration = this.Configuration;
-      this.pool.Free(this);
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushGPInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushGPInterpreter.cs	(revision 14744)
+++ 	(revision )
@@ -1,279 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
-  using System;
-  using System.Collections.Generic;
-  using System.Runtime.CompilerServices;
-  using System.Threading;
-  using System.Threading.Tasks;
-  using HeuristicLab.Core;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
-  using HeuristicLab.Random;
-
-  public class PushGpInterpreter : IPushGpInterpreter {
-    private Task currentTask;
-
-    public PushGpInterpreter(IReadonlyPushGpConfiguration config = null, IRandom random = null) {
-      Random = random ?? new FastRandom();
-
-      Configuration = config ?? new PushGpConfiguration();
-
-      // setting the capacity of the stacks to max points ensures that there will be enough memory at runtime
-      ExecStack = new PushGPStack<Expression>(Configuration.EvalPushLimit);
-
-      CodeStack = new PushGPStack<Expression>(Configuration.EvalPushLimit) {
-        IsEnabled = config.IsCodeStackEnabled
-      };
-
-      NameStack = new PushGPStack<string> {
-        IsEnabled = config.IsNameStackEnabled
-      };
-      BooleanStack = new PushGPStack<bool> {
-        IsEnabled = config.IsBooleanStackEnabled
-      };
-      IntegerStack = new PushGPStack<long> {
-        IsEnabled = config.IsIntegerStackEnabled
-      };
-      FloatStack = new PushGPStack<double> {
-        IsEnabled = config.IsFloatStackEnabled
-      };
-
-      CustomExpressions = new Dictionary<string, Expression>();
-    }
-
-    public PushGpInterpreter(int seed, PushGpConfiguration config = null)
-      : this(config, new FastRandom(seed)) {
-    }
-
-    public IRandom Random { get; set; }
-
-    public int ExecCounter { get; private set; }
-
-    public bool IsPaused { get; private set; }
-
-    public bool IsAborted { get; private set; }
-
-    public bool IsRunning
-    {
-      get
-      {
-        return !ExecStack.IsEmpty &&
-               !IsPaused &&
-               !IsAborted &&
-               (ExecCounter < Configuration.EvalPushLimit);
-      }
-    }
-
-    public bool IsCompleted
-    {
-      get
-      {
-        return ExecStack.Count == 0;
-      }
-    }
-
-    public bool CanStep
-    {
-      get
-      {
-        return !IsCompleted && !IsAborted && IsPaused;
-      }
-    }
-
-    public IReadonlyPushGpConfiguration Configuration { get; protected set; }
-
-    public IStack<Expression> CodeStack { get; private set; }
-
-    public IStack<Expression> ExecStack { get; private set; }
-
-    public IStack<string> NameStack { get; private set; }
-
-    public IStack<bool> BooleanStack { get; private set; }
-
-    public IStack<long> IntegerStack { get; private set; }
-
-    public IStack<double> FloatStack { get; private set; }
-
-    public IDictionary<string, Expression> CustomExpressions { get; private set; }
-
-    public bool IsNameQuoteFlagSet { get; set; }
-
-    public void Run(string code, bool stepwise = false) {
-      var program = PushGPParser.Parse(code);
-      Run(program, stepwise);
-    }
-
-    public Task RunAsync(string code, bool stepwise = false, CancellationToken token = default(CancellationToken)) {
-      var program = PushGPParser.Parse(code);
-
-      currentTask = RunAsync(program, stepwise, token);
-
-      return currentTask;
-    }
-
-    public async Task RunAsync(
-      PushProgram program,
-      bool stepwise = false,
-      CancellationToken token = default(CancellationToken)) {
-      var expression = new ExecExpandExpression(program);
-
-      await RunAsync(expression, stepwise, token);
-    }
-
-    public async Task RunAsync(
-      Expression program,
-      bool stepwise = false,
-      CancellationToken token = default(CancellationToken)) {
-      await Task.Run(() => Run(program, stepwise), token);
-    }
-
-    public void Run(PushProgram program, bool stepwise = false) {
-      var expression = new ExecExpandExpression(program);
-
-      Run(expression, stepwise);
-    }
-
-    public void Run(Expression program, bool stepwise = false) {
-      IsPaused = stepwise;
-
-      /* Push top expression so the loop is able to enter
-       * If the top expression is a single statement then the loop has nothing to do
-       * Otherwise the expand expression will be evaluated and pushes code onto the EXEC stack */
-      ExecStack.Push(program);
-
-      if (Configuration.TopLevelPushCode) CodeStack.Insert(0, program);
-
-      // run top expression
-      DoStep();
-
-      Interpret();
-    }
-
-    public async Task AbortAsync() {
-      if (IsAborted || IsCompleted) return;
-
-      IsAborted = true;
-
-      if (currentTask != null) await currentTask;
-    }
-
-    public async Task AbortAndResetAsync() {
-      await AbortAsync();
-      Reset();
-    }
-
-    public async Task PauseAsync() {
-      if (IsPaused || IsCompleted) return;
-
-      IsPaused = true;
-
-      if (currentTask != null) await currentTask;
-    }
-
-    public async Task ResumeAsync() {
-      if (IsPaused || !IsAborted) {
-        IsPaused = false;
-        await InterpretAsync();
-      } else await currentTask;
-    }
-
-    public void Resume() {
-      if (!IsPaused && IsAborted)
-        return;
-
-      IsPaused = false;
-      Interpret();
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Step() {
-      if (!CanStep) return;
-      DoStep();
-      Finally();
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    public void Step(int count) {
-      for (var i = 0; i < count; i++) Step();
-    }
-
-    public void PrintStacks() {
-      PrintStack("EXEC", ExecStack);
-      PrintStack("CODE", CodeStack);
-      PrintStack("NAME", NameStack);
-      PrintStack("BOOLEAN", BooleanStack);
-      PrintStack("FLOAT", FloatStack);
-      PrintStack("INTEGER", IntegerStack);
-
-      if (CustomExpressions.Count == 0) return;
-      Console.WriteLine("--------- Custom Expressions ---------");
-      foreach (var ce in CustomExpressions) {
-        Console.WriteLine("{0}: {1}", ce.Key, ce.Value);
-      }
-    }
-
-    /// <summary>
-    /// Clears stacks and
-    /// </summary>
-    public void Reset() {
-      IsAborted = false;
-      IsPaused = false;
-      currentTask = null;
-
-      Clear();
-    }
-
-    /// <summary>
-    /// Clears stacks
-    /// </summary>
-    public void Clear() {
-      ExecCounter = 0;
-
-      ExecStack.Clear();
-      CodeStack.Clear();
-
-      NameStack.Clear();
-      BooleanStack.Clear();
-      IntegerStack.Clear();
-      FloatStack.Clear();
-
-      CustomExpressions.Clear();
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private void Interpret() {
-      while (IsRunning) {
-        DoStep();
-        ExecCounter++;
-      }
-
-      Finally();
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private void Finally() {
-      if (!IsCompleted)
-        return;
-
-      if (Configuration.TopLevelPopCode && (CodeStack.Count > 0))
-        CodeStack.Pop();
-    }
-
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
-    private void DoStep() {
-      ExecStack.Pop().Eval(this);
-    }
-
-    private Task InterpretAsync() {
-      currentTask = Task.Run(() => Interpret());
-
-      return currentTask;
-    }
-
-    private void PrintStack<T>(string name, IStack<T> stack) {
-      if (stack.IsEmpty) return;
-      Console.WriteLine("--------- {0} ---------\n{1}\n", name, stack);
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushGpInterpreterPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushGpInterpreterPool.cs	(revision 14744)
+++ 	(revision )
@@ -1,35 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
-  using System;
-
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
-  using HeuristicLab.Core;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Random;
-
-  public class PushGpInterpreterPool {
-    private readonly ObjectPool<PooledPushGpInterpreter> pool;
-
-    public PushGpInterpreterPool(PushGpConfiguration config = null)
-      : this(Environment.ProcessorCount * 2, config) {
-    }
-
-    public PushGpInterpreterPool(int size, PushGpConfiguration config = null) {
-      this.PushGpConfiguration = config ?? new PushGpConfiguration();
-
-      this.pool = new ObjectPool<PooledPushGpInterpreter>(() => new PooledPushGpInterpreter(this, this.PushGpConfiguration), size);
-    }
-
-    public PushGpConfiguration PushGpConfiguration { get; private set; }
-
-    public PooledPushGpInterpreter GetInstance(IRandom random = null) {
-      var interpreter = this.pool.Allocate();
-      interpreter.Random = random ?? new FastRandom();
-
-      return interpreter;
-    }
-
-    public void Free(PooledPushGpInterpreter interpreter) {
-      this.pool.Free(interpreter);
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs	(revision 14745)
@@ -7,5 +7,4 @@
   using HeuristicLab.Core;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
@@ -101,4 +100,18 @@
     public bool IsNameQuoteFlagSet { get; set; }
 
+    public Task RunAsync(string code, bool stepwise = false, CancellationToken token = default(CancellationToken)) {
+      var program = PushParser.Parse(code);
+
+      currentTask = RunAsync(program, stepwise, token);
+
+      return currentTask;
+    }
+    public async Task RunAsync(
+      Expression expression,
+      bool stepwise = false,
+      CancellationToken token = default(CancellationToken)) {
+      await Task.Run(() => Run(expression, stepwise), token);
+    }
+
     public void Run(string code, bool stepwise = false) {
       var program = PushParser.Parse(code);
@@ -106,33 +119,4 @@
     }
 
-    public Task RunAsync(string code, bool stepwise = false, CancellationToken token = default(CancellationToken)) {
-      var program = PushParser.Parse(code);
-
-      currentTask = RunAsync(program, stepwise, token);
-
-      return currentTask;
-    }
-
-    public async Task RunAsync(
-      PushProgram program,
-      bool stepwise = false,
-      CancellationToken token = default(CancellationToken)) {
-      var expression = new ExecExpandExpression(program);
-
-      await RunAsync(expression, stepwise, token);
-    }
-
-    public async Task RunAsync(
-      Expression program,
-      bool stepwise = false,
-      CancellationToken token = default(CancellationToken)) {
-      await Task.Run(() => Run(program, stepwise), token);
-    }
-
-    public void Run(PushProgram program, bool stepwise = false) {
-      var expression = new ExecExpandExpression(program);
-
-      Run(expression, stepwise);
-    }
 
     public void Run(Expression program, bool stepwise = false) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushGPParser.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushGPParser.cs	(revision 14744)
+++ 	(revision )
@@ -1,92 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Parser {
-  using System.Collections.Generic;
-  using System.Globalization;
-
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-
-  public static class PushGPParser {
-    private const string openBrace = "(";
-
-    private const string closeBrace = ")";
-
-    private const char delimiter = ' ';
-
-    private static readonly CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture("en-US");
-
-    private static readonly char[] symbolTrim = { '\r', '\n' };
-
-    public static Expression Parse(string source, int startIndex = 0) {
-      var symbols = source.Split(delimiter);
-
-      int endIndex;
-      return Parse(symbols, 0, out endIndex);
-    }
-
-    private static Expression Parse(string[] symbols, int startIndex, out int endIndex) {
-      var expressions = new List<Expression>();
-
-      for (var i = startIndex; i < symbols.Length; i++) {
-        var symbol = symbols[i].TrimEnd(symbolTrim);
-
-        if (string.IsNullOrWhiteSpace(symbol)) continue;
-
-        switch (symbol) {
-          case openBrace:
-            var subExpression = Parse(symbols, i + 1, out endIndex);
-            expressions.Insert(0, subExpression);
-            i = endIndex;
-            continue;
-          case closeBrace:
-            endIndex = i;
-            return new ExecExpandExpression(expressions.ToArray());
-        }
-
-        // literal
-        Expression expression;
-        if (TryParseLiteral(symbol, out expression)) {
-          expressions.Insert(0, expression);
-          continue;
-        }
-
-        // expression
-        if (ExpressionTable.TryGetStatelessExpression(symbol, out expression)
-            || ExpressionTable.TryGetStatefullExpression(symbol, out expression)) {
-          expressions.Insert(0, expression);
-          continue;
-        }
-
-        // identifier - custom expression or named literals
-        expressions.Insert(0, new NameDefineXExecExpression(symbol));
-      }
-
-      endIndex = symbols.Length - 1;
-
-      return expressions.Count == 1
-        ? expressions[0]
-        : new ExecExpandExpression(expressions.ToArray());
-    }
-
-    private static bool TryParseLiteral(string word, out Expression expression) {
-      long longValue;
-      if (long.TryParse(word, out longValue)) {
-        expression = new IntegerPushExpression(longValue);
-        return true;
-      }
-
-      double floatValue;
-      if (double.TryParse(word, NumberStyles.Float, cultureInfo, out floatValue)) {
-        expression = new FloatPushExpression(floatValue);
-        return true;
-      }
-
-      bool booleanValue;
-      if (bool.TryParse(word, out booleanValue)) {
-        expression = new BooleanPushExpression(booleanValue);
-        return true;
-      }
-
-      expression = null;
-      return false;
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs	(revision 14745)
@@ -16,5 +16,5 @@
     private static readonly char[] symbolTrim = { '\r', '\n' };
 
-    public static Expression Parse(string source, int startIndex = 0) {
+    public static PushProgram Parse(string source, int startIndex = 0) {
       var symbols = source.Split(delimiter);
 
@@ -23,5 +23,5 @@
     }
 
-    private static Expression Parse(string[] symbols, int startIndex, out int endIndex) {
+    private static PushProgram Parse(string[] symbols, int startIndex, out int endIndex) {
       var expressions = new List<Expression>();
 
@@ -39,5 +39,5 @@
           case closeBrace:
             endIndex = i;
-            return new ExecExpandExpression(expressions.ToArray());
+            return new PushProgram(expressions.ToArray());
         }
 
@@ -62,7 +62,5 @@
       endIndex = symbols.Length - 1;
 
-      return expressions.Count == 1
-        ? expressions[0]
-        : new ExecExpandExpression(expressions.ToArray());
+      return new PushProgram(expressions.ToArray());
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs	(revision 14745)
@@ -406,5 +406,5 @@
 
       var program = individual.PushProgram(config.EnabledExpressions as IReadOnlyList<string>);
-      var expandExpression = new ExecExpandExpression(program);
+      var expandExpression = new PushProgram(program);
       var results = new List<double>();
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/ISimplifier.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/ISimplifier.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/ISimplifier.cs	(revision 14745)
@@ -6,5 +6,5 @@
 
   public interface ISimplifier {
-    ExecExpandExpression Simplify(ExecExpandExpression program, IRandom random, Predicate<ExecExpandExpression> isBetter);
+    PushProgram Simplify(PushProgram program, IRandom random, Predicate<PushProgram> isBetter);
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/RandomSimplifier.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/RandomSimplifier.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/RandomSimplifier.cs	(revision 14745)
@@ -7,16 +7,16 @@
     public int Trys { get; set; }
 
-    public ExecExpandExpression Simplify(ExecExpandExpression program, IRandom random, Predicate<ExecExpandExpression> isBetter) {
+    public PushProgram Simplify(PushProgram program, IRandom random, Predicate<PushProgram> isBetter) {
 
-      if (program.State.TotalCount == 1) {
-        return isBetter(ExecExpandExpression.Empty) ? ExecExpandExpression.Empty : program;
+      if (program.TotalCount == 1) {
+        return isBetter(PushProgram.Empty) ? PushProgram.Empty : program;
       }
 
       var copy = program.Copy();
-      var maxTries = Math.Min(Trys, program.State.TotalCount - 2);
+      var maxTries = Math.Min(Trys, program.TotalCount - 2);
       var successfulRemoves = 0;
 
       for (var i = 0; i < maxTries; i++) {
-        var rndIndex = random.Next(1, program.State.TotalCount - 1 - successfulRemoves);
+        var rndIndex = random.Next(1, program.TotalCount - 1 - successfulRemoves);
         var node = copy.GetFromTree(
           rndIndex,
@@ -28,9 +28,9 @@
           });
 
-        var oldParentExpressions = node.Parent.State.Expressions as Expression[];
+        var oldParentExpressions = node.Parent.State;
         var newParentExpressions = RemoveAt(oldParentExpressions, node.ChildIndex);
-        var newParent = new ExecExpandExpression(newParentExpressions);
+        var newParent = new PushProgram(newParentExpressions);
 
-        var superExpressions = (node.Super == null ? copy.State.Expressions : node.Super.State.Expressions) as Expression[];
+        var superExpressions = node.Super == null ? copy.State : node.Super.State;
         superExpressions[node.ParentIndex] = newParent;
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushGPStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushGPStack.cs	(revision 14744)
+++ 	(revision )
@@ -1,280 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
-  using System;
-  using System.Collections;
-  using System.Collections.Generic;
-  using System.Linq;
-
-  /// <summary>
-  ///     While Push's stacks are generally treated as genuine stacks---that is, inclassions take their arguments from the
-  ///     tops of
-  ///     the stacks and push their results onto the tops of the stacks---a few inclassions (like YANK and SHOVE) do allow
-  ///     direct access
-  ///     to "deep" stack elements by means of integer indices. To this extent the stacks can be used as general, random
-  ///     access memory
-  ///     classures. This is one of the features that ensures the Turing-completeness of Push (another being the arbitrary
-  ///     name/value
-  ///     bindings supported by the NAME data type and DEFINE methods; see below).
-  /// </summary>
-  /// <typeparam name="T">The item type of the collection.</typeparam>
-  public class PushGPStack<T> : IStack<T> {
-    private const string Delimiter = " ";
-
-    private readonly List<T> data;
-
-    public PushGPStack(int capacity = 0) {
-      data = new List<T>(capacity);
-      IsEnabled = true;
-    }
-
-    public bool IsEnabled { get; set; }
-
-    public int Capacity
-    {
-      get
-      {
-        return this.data.Capacity;
-      }
-    }
-
-    public T Top
-    {
-      get
-      {
-        return this.data[this.Count - 1];
-      }
-    }
-
-    public T TopOrDefault
-    {
-      get
-      {
-        return this.Count > 0 ? this.data[this.Count - 1] : default(T);
-      }
-    }
-
-    public T Bottom
-    {
-      get
-      {
-        return this.data[0];
-      }
-    }
-
-    public T BottomOrDefault
-    {
-      get
-      {
-        return this.Count > 0 ? this.data[0] : default(T);
-      }
-    }
-
-    public int Count
-    {
-      get
-      {
-        return this.data.Count;
-      }
-    }
-
-    public bool IsEmpty
-    {
-      get
-      {
-        return this.Count == 0;
-      }
-    }
-
-    public bool IsReadOnly
-    {
-      get
-      {
-        return false;
-      }
-    }
-
-    public void Add(T item) {
-      this.Push(item);
-    }
-
-    public void Clear() {
-      this.data.Clear();
-    }
-
-    public bool Contains(T item) {
-      return this.data.Contains(item);
-    }
-
-    public void CopyTo(T[] array, int arrayIndex) {
-      this.data.CopyTo(array, arrayIndex);
-    }
-
-    public IEnumerator<T> GetEnumerator() {
-      return this.data.GetEnumerator();
-    }
-
-    public T ElementAt(int index) {
-      return this.data[index];
-    }
-
-    public T ReverseElementAt(int offset) {
-      return this.data[this.data.Count - 1 - offset];
-    }
-
-    public void SetTop(T value) {
-      this.data[this.Count - 1] = value;
-    }
-
-    public T this[int key]
-    {
-      get
-      {
-        return this.data[key];
-      }
-      set
-      {
-        this.data[key] = value;
-      }
-    }
-
-    public void Swap(int count) {
-      var top = this.Top;
-      var bottomIndex = this.Count - count;
-
-      for (var i = this.Count - 1; i > bottomIndex; i--) this.data[i] = this.data[i - 1];
-
-      this.data[bottomIndex] = top;
-    }
-
-    public void Yank(int index) {
-      if (index == this.Count - 1) return;
-
-      var item = this.ElementAt(index);
-      this.data.RemoveAt(index);
-      this.data.Add(item);
-    }
-
-    public T Pop() {
-      var value = this.data[this.Count - 1];
-      this.data.RemoveAt(this.Count - 1);
-
-      return value;
-    }
-
-    public T[] Pop(int count) {
-      var items = Peek(count);
-      this.Remove(count);
-
-      return items;
-    }
-
-    public T Peek() {
-      return Top;
-    }
-
-    public T[] Peek(int count) {
-      var startIndex = this.Count - count;
-
-      var items = new T[count];
-      this.data.CopyTo(startIndex, items, 0, count);
-
-      return items;
-    }
-
-    public void Push(T item) {
-      if (!IsEnabled) return;
-
-      this.data.Add(item);
-    }
-
-    public void PushResult(int count, Func<T[], T> templateFunc) {
-      if (!IsEnabled) return;
-
-      var startIndex = this.Count - count;
-      var items = new T[count];
-
-      this.data.CopyTo(startIndex, items, 0, count);
-      this.Remove(count - 1);
-
-      this.data[this.Count - 1] = templateFunc(items);
-    }
-
-    public void Push(params T[] items) {
-      if (!IsEnabled) return;
-
-      for (var i = 0; i < items.Length; i++) this.data.Add(items[i]);
-      //this.data.AddRange(items);
-    }
-
-    public void ReversePush(params T[] items) {
-      for (var i = items.Length - 1; i >= 0; i--) this.data.Add(items[i]);
-    }
-
-    public void Push(IReadOnlyList<T> items) {
-      if (!IsEnabled) return;
-
-      for (var i = 0; i < items.Count; i++) this.data.Add(items[i]);
-      //this.data.AddRange(items);
-    }
-
-    public void Insert(int index, T item) {
-      if (!IsEnabled) return;
-
-      this.data.Insert(index, item);
-    }
-
-    public void Insert(int index, params T[] items) {
-      if (!IsEnabled) return;
-
-      this.data.InsertRange(index, items);
-    }
-
-    public void Insert(int index, IEnumerable<T> items) {
-      if (!IsEnabled) return;
-
-      this.data.InsertRange(index, items);
-    }
-
-    public bool Remove(T item) {
-      var index = this.Count - 1;
-      if ((this.Count > 0) && this.data[index].Equals(item)) {
-        this.data.RemoveAt(index);
-        return true;
-      }
-      return false;
-    }
-
-    public void RemoveTop() {
-      this.data.RemoveAt(this.Count - 1);
-    }
-
-    public void Remove(int count) {
-      for (var i = 0; i < count; i++) this.data.RemoveAt(this.Count - 1);
-    }
-
-    public void RemoveAt(int index) {
-      this.data.RemoveAt(index);
-    }
-
-    public void RemoveAt(int index, int count) {
-      this.data.RemoveRange(index, count);
-    }
-
-    public bool TryPop(out T item) {
-      if (this.Count > 0) {
-        item = this.Pop();
-        return true;
-      }
-      item = default(T);
-      return false;
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() {
-      return (this.data as IEnumerable).GetEnumerator();
-    }
-
-    public override string ToString() {
-      var data = this.data as IEnumerable<T>;
-      return string.Join(Delimiter, data.Reverse());
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Interpreter/Expressions/StandardTests.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Interpreter/Expressions/StandardTests.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Interpreter/Expressions/StandardTests.cs	(revision 14745)
@@ -51,5 +51,5 @@
                           };
 
-      var list = new ExecExpandExpression(expressions);
+      var list = new PushProgram(expressions);
       var clone = list.Copy();
 
@@ -68,13 +68,13 @@
                           };
 
-      var list = new ExecExpandExpression(expressions.ToArray());
+      var list = new PushProgram(expressions.ToArray());
 
       expressions.Add(list);
 
-      var list2 = new ExecExpandExpression(expressions.ToArray());
+      var list2 = new PushProgram(expressions.ToArray());
       var clone = list2.Copy();
 
-      Assert.AreSame(list, clone.State.Expressions.Last());
-      Assert.AreEqual(list, clone.State.Expressions.Last());
+      Assert.AreSame(list, clone.State.Last());
+      Assert.AreEqual(list, clone.State.Last());
 
       Assert.AreNotSame(list2, clone);
@@ -92,9 +92,9 @@
                           };
 
-      var list = new ExecExpandExpression(expressions.ToArray());
+      var list = new PushProgram(expressions.ToArray());
 
       expressions.Add(list);
-      var list2 = new ExecExpandExpression(expressions.ToArray());
-      var list3 = new ExecExpandExpression(expressions.ToArray());
+      var list2 = new PushProgram(expressions.ToArray());
+      var list3 = new PushProgram(expressions.ToArray());
 
       Assert.AreEqual(list2.GetHashCode(), list3.GetHashCode());
Index: branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs	(revision 14745)
@@ -107,5 +107,5 @@
     static void PerformanceParallelTestInterpreter() {
       var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )");
-      //var program = new ExecExpandExpression(new Expression[]
+      //var program = new PushProgram(new Expression[]
       //{
       //  new IntegerPushExpression(5),
@@ -231,5 +231,5 @@
     static void TestSimplifier() {
       var interpreter = new PushInterpreter();
-      var program = PushParser.Parse("( 5 INTEGER.DUP FLOAT.+ INTEGER.+ )") as ExecExpandExpression;
+      var program = PushParser.Parse("( 5 INTEGER.DUP FLOAT.+ INTEGER.+ )") as PushProgram;
       var simplifier = new RandomSimplifier { Trys = 10 };
       var random = new FastRandom(1337);
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/IManagedPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/IManagedPool.cs	(revision 14745)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/IManagedPool.cs	(revision 14745)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestPooling.Pool
+{
+    public interface IManagedPool<T> : IDisposable
+    where T: class
+    {
+      T Get();
+    }
+}
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool.cs	(revision 14745)
@@ -17,4 +17,6 @@
 
     private int entryIndex = 0;
+
+    public static int InstanceCount { get { return Pool.Sum(p => p.Count); } }
 
     public ManagedPool(int partitionSize, Func<T> factory) {
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool2.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool2.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPool2.cs	(revision 14745)
@@ -1,75 +1,59 @@
-﻿using System.Collections.Generic;
+﻿//using System.Collections.Generic;
 
-namespace TestPooling.Pool {
-  using System;
-  using System.Collections.Concurrent;
-  using System.IO;
-  using System.Linq;
-  using System.Runtime.Serialization.Formatters.Binary;
+//namespace TestPooling.Pool {
+//  using System;
+//  using System.Collections.Concurrent;
+//  using System.IO;
+//  using System.Linq;
+//  using System.Runtime.Serialization.Formatters.Binary;
 
-  public class ManagedPool2<T> : IDisposable where T : class {
+//  public class ManagedPool2<T> : IDisposable where T : class {
 
-    private static readonly ConcurrentStack<T[]> Pool = new ConcurrentStack<T[]>();
+//    private static readonly ConcurrentStack<T[]> Pool = new ConcurrentStack<T[]>();
 
-    private readonly T[] DummyPartition;
-    private readonly Func<T> Factory;
-    public readonly int PartitionSize;
+//    private readonly T[] DummyPartition;
+//    public readonly int PartitionSize;
 
-    private readonly IList<T[]> partitions = new List<T[]>();
-    private T[] currentPartition;
-    private int entryIndex;
+//    private readonly IList<T[]> partitions = new List<T[]>();
+//    private T[] currentPartition;
+//    private int entryIndex;
 
-    public ManagedPool2(int partitionSize, T[] dummyPartition, Func<T> factory) {
-      PartitionSize = partitionSize;
-      Factory = factory;
-      entryIndex = partitionSize;
+//    public ManagedPool2(int partitionSize, T[] dummyPartition) {
+//      PartitionSize = partitionSize;
+//      entryIndex = partitionSize;
 
-      DummyPartition = dummyPartition;
-    }
+//      DummyPartition = dummyPartition;
+//    }
 
-    public T Get() {
-      if (entryIndex == PartitionSize) {
-        currentPartition = GetPartition();
-        partitions.Add(currentPartition);
-        entryIndex = 0;
-      }
+//    public T Get() {
+//      if (entryIndex == PartitionSize) {
+//        currentPartition = GetPartition();
+//        partitions.Add(currentPartition);
+//        entryIndex = 0;
+//      }
 
-      return currentPartition[entryIndex++];
-    }
+//      return currentPartition[entryIndex++];
+//    }
 
-    private T[] GetPartition() {
-      //T[] partition;
+//    private T[] GetPartition() {
+//      T[] partition;
+//      return (Pool.TryPop(out partition)) ? partition : DeepArrayCopy(DummyPartition);
+//    }
 
-      //partition = Pool.TryPop(out partition) ? partition : new T[PartitionSize];
+//    private static T[] DeepArrayCopy(object objectToCopy) {
+//      using (var memoryStream = new MemoryStream()) {
+//        var binaryFormatter = new BinaryFormatter();
 
-      //for (var i = 0; i < PartitionSize; i++) {
-      //  partition[i] = Factory();
-      //}
+//        binaryFormatter.Serialize(memoryStream, objectToCopy);
+//        memoryStream.Seek(0, SeekOrigin.Begin);
 
-      //return partition;
+//        return (T[])binaryFormatter.Deserialize(memoryStream);
+//      }
+//    }
 
-      T[] partition;
-      if (Pool.TryPop(out partition)) return partition;
-
-      //partition = new T[PartitionSize];
-      //DummyPartition.CopyTo(partition, 0);
-
-      return DeepArrayCopy(DummyPartition);
-    }
-
-    private static T[] DeepArrayCopy(object objectToCopy) {
-      using (var memoryStream = new MemoryStream()) {
-        var binaryFormatter = new BinaryFormatter();
-
-        binaryFormatter.Serialize(memoryStream, objectToCopy);
-        memoryStream.Seek(0, SeekOrigin.Begin);
-
-        return (T[])binaryFormatter.Deserialize(memoryStream);
-      }
-    }
-
-    public void Dispose() {
-      Pool.PushRange(partitions.ToArray());
-    }
-  }
-}
+//    public void Dispose() {
+//      Pool.PushRange(partitions.ToArray());
+//      partitions.Clear();
+//    }
+//  }
+//}
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPoolProvider.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPoolProvider.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/Pool/ManagedPoolProvider.cs	(revision 14745)
@@ -1,45 +1,82 @@
-﻿//using System;
+﻿using System;
 
-//namespace TestPooling.Pool {
-//  using System.Collections.Concurrent;
-//  using System.Threading.Tasks;
+namespace TestPooling.Pool {
+  using System.Collections.Concurrent;
+  using System.Collections.Generic;
+  using System.IO;
+  using System.Linq;
+  using System.Runtime.Serialization.Formatters.Binary;
 
-//  public class ManagedPoolProvider<T> where T : class {
-//    private static readonly volatile ConcurrentStack<T[]> partitions = new ConcurrentStack<T[]>();
-//    private readonly Func<T> Factory;
-//    public readonly int PartitionSize;
+  public class ManagedPoolProvider<T> where T : class {
+    private readonly ConcurrentStack<T[]> partitions = new ConcurrentStack<T[]>();
+    private readonly ObjectPool<IManagedPool<T>> managedPools;
+    private T[] DummyPartition;
+    public readonly int PartitionSize;
 
-//    public ManagedPoolProvider(int partitionSize, Func<T> factory) {
-//      PartitionSize = partitionSize;
-//      Factory = factory;
-//    }
+    public int InstanceCount { get { return partitions.Count * PartitionSize; } }
 
-//    public T[] GetPartition() {
-//      T[] partition;
+    public ManagedPoolProvider(int partitionSize) {
+      PartitionSize = partitionSize;
+      managedPools = new ObjectPool<IManagedPool<T>>(() => new ManagedPool2<T>(this));
+    }
+    public void InitDummyPartition(Func<T> factory) {
+      DummyPartition = new T[PartitionSize];
 
-//      return partitions.TryPop(out partition) ? partition : CreatePartition();
-//    }
+      for (var i = 0; i < PartitionSize; i++) {
+        DummyPartition[i] = factory();
+      }
+    }
 
-//    public void ReleasePartitions(params T[][] partition) {
-//      partitions.PushRange(partition);
-//    }
+    public void ReleasePartitions(params T[][] partition) {
+      if (partition.Length > 0) partitions.PushRange(partition);
+    }
 
-//    public T CreateEntry() {
-//      return Factory();
-//    }
+    private T[] GetPartition() {
+      T[] partition;
+      return partitions.TryPop(out partition) ? partition : DeepArrayCopy(DummyPartition);
+    }
 
-//    private T[] CreatePartition() {
-//      //return new T[PartitionSize];
+    private static T[] DeepArrayCopy(object objectToCopy) {
+      using (var memoryStream = new MemoryStream()) {
+        var binaryFormatter = new BinaryFormatter();
 
-//      var partition = new T[PartitionSize];
+        binaryFormatter.Serialize(memoryStream, objectToCopy);
+        memoryStream.Seek(0, SeekOrigin.Begin);
 
-//      Parallel.For(0, PartitionSize, i => partition[i] = Factory());
+        return (T[])binaryFormatter.Deserialize(memoryStream);
+      }
+    }
 
-//      return partition;
-//    }
+    public IManagedPool<T> CreatePool() {
+      return managedPools.Allocate();
+    }
 
-//    public ManagedPool<T> CreatePool() {
-//      return new ManagedPool<T>(this);
-//    }
-//  }
-//}
+    private class ManagedPool2<T> : IManagedPool<T> where T : class {
+      private readonly ManagedPoolProvider<T> provider;
+      private readonly IList<T[]> partitions = new List<T[]>();
+      private T[] currentPartition;
+      private int entryIndex;
+
+      public ManagedPool2(ManagedPoolProvider<T> provider) {
+        this.provider = provider;
+        entryIndex = provider.PartitionSize;
+      }
+
+      public T Get() {
+        if (entryIndex == provider.PartitionSize) {
+          currentPartition = provider.GetPartition();
+          partitions.Add(currentPartition);
+          entryIndex = 0;
+        }
+
+        return currentPartition[entryIndex++];
+      }
+
+      public void Dispose() {
+        provider.ReleasePartitions(partitions.ToArray());
+        partitions.Clear();
+        provider.managedPools.Free(this);
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/Program.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/Program.cs	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/Program.cs	(revision 14745)
@@ -4,9 +4,17 @@
   using System;
   using System.Diagnostics;
+  using System.Threading;
 
   using TestPooling.Pool;
 
   class Program {
-    private const int Count = 3000;
+    private const int PartitionSize = 512;
+    private const int ExampleCount = 200;
+    private const int InstanceCount = 1024;
+    private const int PopulationCount = 100;
+
+    private static int TotalInstanceCount => PopulationCount * InstanceCount * ExampleCount;
+
+
     static void Main(string[] args) {
       Test1();
@@ -19,18 +27,18 @@
 
       sw.Start();
-      //Parallel.For(0, 3, k => {
-      Parallel.For(0, 10000, i => {
-        using (var pool = new ManagedPool<Person>(Count, () => new Person())) {
-          for (var j = 0; j < 3000; j++) {
-            var person = pool.Get();
-            person.Age = i + j;
-            person.Name = string.Format("{0} - {1}", i, j);
+      Parallel.For(0, PopulationCount, pc => {
+        for (var e = 0; e < ExampleCount; e++) {
+          using (var pool = new ManagedPool<Person>(PartitionSize, () => new Person())) {
+            for (var i = 0; i < InstanceCount; i++) {
+              var person = pool.Get();
+              person.Age = pc + e + i;
+              person.Name = string.Format("{0} - {1} - {2}", pc, e, i);
+            }
           }
         }
       });
-      //});
       sw.Stop();
 
-      Console.WriteLine("1 - Duration: {0} - {1}", sw.ElapsedTicks, sw.Elapsed.TotalSeconds);
+      Console.WriteLine("1 - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, ManagedPool<Person>.InstanceCount, TotalInstanceCount);
     }
 
@@ -39,48 +47,21 @@
       sw.Start();
 
-      var dummyPartition = new Person[Count];
+      var provider = new ManagedPoolProvider<Person>(PartitionSize);
+      provider.InitDummyPartition(() => new Person());
 
-      for (var i = 0; i < Count; i++) {
-        dummyPartition[i] = new Person();
-      }
-
-      //Parallel.For(0, 3, k => {
-      Parallel.For(0, 10000, i => {
-        using (var pool = new ManagedPool2<Person>(Count, dummyPartition, () => new Person())) {
-          for (var j = 0; j < 3000; j++) {
-            var person = pool.Get();
-            person.Age = i + j;
-            person.Name = string.Format("{0} - {1}", i, j);
+      Parallel.For(0, PopulationCount, pc => {
+        for (var e = 0; e < ExampleCount; e++) {
+          using (var pool = provider.CreatePool()) {
+            for (var i = 0; i < InstanceCount; i++) {
+              var person = pool.Get();
+              person.Age = pc + e + i;
+              person.Name = string.Format("{0} - {1} - {2}", pc, e, i);
+            }
           }
         }
       });
-      //});
       sw.Stop();
 
-      //var p1 = new ManagedPool2<Person>(Count, dummyPartition, () => new TestPooling.Person());
-      //var p2 = new ManagedPool2<Person>(Count, dummyPartition, () => new TestPooling.Person());
-      //var pa1 = p1.Get();
-      //var pa2 = p2.Get();
-
-      Console.WriteLine("1_2 - Duration: {0} - {1}", sw.ElapsedTicks, sw.Elapsed.TotalSeconds);
-    }
-
-    private static void Test4() {
-      var sw = new Stopwatch();
-
-      sw.Start(); ;
-      var pool = new ManagedPool<Person>(512, () => new Person());
-
-      Parallel.For(0, 10000, i => {
-        for (var j = 0; j < 3000; j++) {
-          var person = pool.Get();
-          person.Age = i + j;
-          person.Name = string.Format("{0} - {1}", i, j);
-        }
-        pool.Dispose();
-      });
-      sw.Stop();
-
-      Console.WriteLine("1 - Duration: {0}", sw.ElapsedTicks);
+      Console.WriteLine("1_2 - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, provider.InstanceCount, TotalInstanceCount);
     }
 
@@ -90,17 +71,21 @@
 
       sw.Start();
-      Parallel.For(0, 10000, i => {
-        var list = new Person[3000];
+      Parallel.For(0, PopulationCount, pc => {
+        for (var e = 0; e < ExampleCount; e++) {
+          var list = new Person[InstanceCount];
+          for (var i = 0; i < InstanceCount; i++) {
+            list[i] = new Person {
+              Age = pc + e + i,
+              Name = string.Format("{0} - {1} - {2}", pc, e, i)
+            };
+          }
 
-        for (var j = 0; j < 3000; j++) {
-          list[j] = new Person { Age = i + j, Name = string.Format("{0} - {1}", i, j) };
+          Interlocked.Add(ref count, list.Length);
         }
-
-        count += list.Length;
       });
       sw.Stop();
 
       Console.WriteLine("3 - Duration: {0} - {1}", sw.ElapsedTicks, sw.Elapsed.TotalSeconds);
-      Console.WriteLine("Count: {0}", count);
+      Console.WriteLine("PartitionSize: {0}", count);
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/TestPooling/TestPooling.csproj
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/TestPooling/TestPooling.csproj	(revision 14744)
+++ branches/PushGP/HeuristicLab.PushGP/TestPooling/TestPooling.csproj	(revision 14745)
@@ -44,4 +44,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Pool\IManagedPool.cs" />
     <Compile Include="Pool\ManagedPool.cs" />
     <Compile Include="Pool\ManagedPool2.cs" />
