Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/App.config
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/App.config	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/App.config	(revision 14777)
@@ -0,0 +1,6 @@
+﻿<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
+    </startup>
+</configuration>
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/DirtyList.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/DirtyList.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/DirtyList.cs	(revision 14777)
@@ -0,0 +1,163 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace TestPooling.DirtyList {
+  using System.Collections;
+
+  [Serializable]
+  public class DirtyList<T> : IList<T>, IReadOnlyList<T> {
+    private readonly List<T> data;
+    private int topIndex;
+
+    public DirtyList(int capacity = 0) {
+      data = new List<T>(capacity);
+    }
+
+    public IEnumerator<T> GetEnumerator() {
+      return data.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    public void Add(T item) {
+      if (topIndex == data.Count) {
+        data.Add(item);
+      } else {
+        data[topIndex] = item;
+      }
+
+      topIndex++;
+    }
+
+    public void AddRange(IEnumerable<T> items) {
+      foreach (var item in items) {
+        Add(item);
+      }
+    }
+
+    public void RemoveRange(IEnumerable<T> items) {
+      foreach (var item in items) {
+        Remove(item);
+      }
+    }
+
+    public void Clear() {
+      topIndex = 0;
+    }
+
+    public bool Contains(T item) {
+      if (item == null) {
+        for (int i = 0; i < topIndex; i++)
+          if (data[i] == null)
+            return true;
+        return false;
+      } else {
+        var c = EqualityComparer<T>.Default;
+
+        for (int i = 0; i < topIndex; i++) {
+          if (c.Equals(data[i], item)) return true;
+        }
+        return false;
+      }
+    }
+
+    public void CopyTo(T[] array, int arrayIndex) {
+      data.CopyTo(0, array, arrayIndex, topIndex);
+    }
+
+    public bool Remove(T item) {
+      int index = IndexOf(item);
+      if (index >= 0) {
+        RemoveAt(index);
+        topIndex--;
+        return true;
+      }
+
+      return false;
+    }
+
+    int ICollection<T>.Count
+    {
+      get
+      {
+        return topIndex == 0 ? 0 : topIndex - 1;
+      }
+    }
+
+    public bool IsReadOnly
+    {
+      get
+      {
+        return ((ICollection<T>)data).IsReadOnly;
+      }
+    }
+
+    public int IndexOf(T item) {
+      for (var i = 0; i < topIndex; i++) {
+        if (data.Equals(data[i])) return i;
+      }
+
+      return -1;
+    }
+
+    public void Insert(int index, T item) {
+      // Note that insertions at the end are legal.
+      if ((uint)index > (uint)topIndex) {
+        throw new ArgumentOutOfRangeException("index");
+      }
+
+      data.Insert(index, item);
+    }
+
+    public void RemoveAt(int index) {
+      if ((uint)index > (uint)topIndex) {
+        throw new ArgumentOutOfRangeException("index");
+      }
+
+      data.RemoveAt(index);
+      topIndex--;
+    }
+
+    T IList<T>.this[int index]
+    {
+      get
+      {
+        if ((uint)index > (uint)topIndex) {
+          throw new ArgumentOutOfRangeException("index");
+        }
+
+        return data[index];
+      }
+      set
+      {
+        if ((uint)index > (uint)topIndex) {
+          throw new ArgumentOutOfRangeException("index");
+        }
+
+        data[index] = value;
+      }
+    }
+
+    int IReadOnlyCollection<T>.Count
+    {
+      get
+      {
+        return topIndex < 0 ? 0 : topIndex;
+      }
+    }
+
+    T IReadOnlyList<T>.this[int index]
+    {
+      get
+      {
+        if ((uint)index > (uint)topIndex) {
+          throw new ArgumentOutOfRangeException("index");
+        }
+
+        return data[index];
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushList.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushList.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushList.cs	(revision 14777)
@@ -0,0 +1,41 @@
+﻿using System.Collections.Generic;
+
+namespace TestPooling.DirtyList {
+  public class PushStack2<T> {
+    private readonly List<List<T>> items = new List<List<T>>();
+    private bool IsEnabled { get; set; }
+
+    public PushStack2() {
+      IsEnabled = true;
+    }
+
+    public void Push(T item) {
+      if (!IsEnabled) return;
+
+      this.items[items.Count - 1].Add(item);
+    }
+
+    public void PushRange(IEnumerable<T> items) {
+      if (!IsEnabled) return;
+
+      this.items.Add(new List<T>(items));
+    }
+
+    public T Pop() {
+      var container = items[items.Count - 1];
+
+      if (container.Count == 1) {
+        items.RemoveAt(items.Count - 1);
+      }
+
+      var item = container[container.Count - 1];
+      container.RemoveAt(container.Count - 1);
+
+      return item;
+    }
+
+    public void Clear() {
+      this.items.Clear();
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack.cs	(revision 14777)
@@ -0,0 +1,287 @@
+﻿namespace TestPooling.DirtyList {
+  using System;
+  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 PushStack<T> {
+    private const string Delimiter = " ";
+
+    private readonly List<T> data;
+
+    public PushStack(int capacity = 0) {
+      this.data = new List<T>(capacity);
+      this.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 = this.Peek(count);
+      this.Remove(count);
+
+      return items;
+    }
+
+    public T Peek() {
+      return this.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 (!this.IsEnabled) return;
+
+      this.data.Add(item);
+    }
+
+    public void Push(T item1, T item2) {
+      if (!this.IsEnabled) return;
+
+      this.data.Add(item1);
+      this.data.Add(item2);
+    }
+
+    public void Push(T item1, T item2, T item3) {
+      if (!this.IsEnabled) return;
+
+      this.data.Add(item1);
+      this.data.Add(item2);
+      this.data.Add(item3);
+    }
+
+    public void Push(T item1, T item2, T item3, T item4) {
+      if (!this.IsEnabled) return;
+
+      this.data.Add(item1);
+      this.data.Add(item2);
+      this.data.Add(item3);
+      this.data.Add(item4);
+    }
+
+    public void PushResult(int count, Func<T[], T> templateFunc) {
+      if (!this.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(IReadOnlyList<T> items) {
+      if (!this.IsEnabled) return;
+
+      for (var i = 0; i < items.Count; i++) this.data.Add(items[i]);
+    }
+
+    public void Insert(int index, T item) {
+      if (!this.IsEnabled) return;
+
+      this.data.Insert(index, item);
+    }
+
+    public void Insert(int index, params T[] items) {
+      if (!this.IsEnabled) return;
+
+      this.data.InsertRange(index, items);
+    }
+
+    public void Insert(int index, IEnumerable<T> items) {
+      if (!this.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;
+    }
+
+    public override string ToString() {
+      var data = this.data as IEnumerable<T>;
+      return string.Join(Delimiter, data.Reverse());
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack3.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack3.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/DirtyList/PushStack3.cs	(revision 14777)
@@ -0,0 +1,286 @@
+﻿namespace TestPooling.DirtyList {
+  using System;
+  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 PushStack3<T> {
+    private const string Delimiter = " ";
+
+    private readonly LinkedList<T> data;
+
+    public PushStack3() {
+      this.data = new LinkedList<T>();
+      this.IsEnabled = true;
+    }
+
+    public bool IsEnabled { get; set; }
+
+    public T Top
+    {
+      get
+      {
+        return this.data.Last.Value;
+      }
+    }
+
+    public T TopOrDefault
+    {
+      get
+      {
+        return this.Count > 0 ? Top : default(T);
+      }
+    }
+
+    public T Bottom
+    {
+      get
+      {
+        return this.data.First.Value;
+      }
+    }
+
+    public T BottomOrDefault
+    {
+      get
+      {
+        return this.Count > 0 ? Bottom : 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.ElementAt(index);
+    }
+
+    public T ReverseElementAt(int offset) {
+      return ElementAt(Count - 1 - offset);
+    }
+
+    public void SetTop(T value) {
+      this.data.Last.Value = value;
+    }
+
+    private LinkedListNode<T> GetByIndex(int index) {
+      var current = data.First;
+      for (var i = 0; i <= index; i++) {
+        current = current.Next;
+      }
+
+      return current;
+    }
+
+    public T this[int key]
+    {
+      get
+      {
+        return ElementAt(key);
+      }
+      set
+      {
+        GetByIndex(key).Value = value;
+      }
+    }
+
+    public void Swap(int count) {
+      var topValue = this.Top;
+      var current = this.data.Last;
+      var bottomIndex = this.Count - count;
+
+
+      for (var i = this.Count - 1; i > bottomIndex; i--) {
+        current.Value = current.Previous.Value;
+        current = current.Previous;
+      }
+
+      this.data.Last.Value = topValue;
+    }
+
+    public void Yank(int index) {
+      if (index == this.Count - 1) return;
+
+      var item = this.GetByIndex(index);
+      this.data.Remove(item);
+      this.data.AddLast(item);
+    }
+
+    public T Pop() {
+      var value = Top;
+      this.data.RemoveLast();
+
+      return value;
+    }
+
+    public T[] Pop(int count) {
+      var items = new T[count];
+
+      for (var i = 0; i < count; i++) {
+        items[count - i] = Top;
+        data.RemoveLast();
+      }
+
+      return items;
+    }
+
+    public T Peek() {
+      return this.Top;
+    }
+
+    public T[] Peek(int count) {
+      var items = new T[count];
+      var current = this.data.Last;
+
+      for (var i = 0; i < count; i++) {
+        items[count - i] = current.Value;
+        current = current.Previous;
+      }
+
+      return items;
+    }
+
+    public void Push(T item) {
+      if (!this.IsEnabled) return;
+
+      this.data.AddLast(item);
+    }
+
+    public void Push(T item1, T item2) {
+      if (!this.IsEnabled) return;
+
+      this.data.AddLast(item1);
+      this.data.AddLast(item2);
+    }
+
+    public void Push(T item1, T item2, T item3) {
+      if (!this.IsEnabled) return;
+
+      this.data.AddLast(item1);
+      this.data.AddLast(item2);
+      this.data.AddLast(item3);
+    }
+
+    public void Push(T item1, T item2, T item3, T item4) {
+      if (!this.IsEnabled) return;
+
+      this.data.AddLast(item1);
+      this.data.AddLast(item2);
+      this.data.AddLast(item3);
+      this.data.AddLast(item4);
+    }
+
+    public void PushResult(int count, Func<T[], T> templateFunc) {
+      if (!this.IsEnabled) return;
+
+      Push(templateFunc(Pop(count)));
+    }
+
+    public void PushRange(IReadOnlyList<T> items) {
+      if (!this.IsEnabled) return;
+
+      for (var i = 0; i < items.Count; i++) this.data.AddLast(items[i]);
+    }
+
+    public void Insert(int index, T value) {
+      if (!this.IsEnabled) return;
+
+      var node = GetByIndex(index);
+      this.data.AddBefore(node, value);
+    }
+
+    public bool Remove(T item) {
+      return this.data.Remove(item);
+    }
+
+    public void RemoveTop() {
+      this.data.RemoveLast();
+    }
+
+    public void Remove(int count) {
+      for (var i = 0; i < count; i++) this.data.RemoveLast();
+    }
+
+    public void RemoveAt(int index) {
+      var node = GetByIndex(index);
+
+      this.data.Remove(node);
+    }
+
+    public void RemoveAt(int index, int count) {
+
+      var node = GetByIndex(index);
+
+      for (var i = 0; i < count; i++) {
+        data.Remove(node);
+        node = node.Next;
+      }
+    }
+
+    public bool TryPop(out T item) {
+      if (this.Count > 0) {
+        item = this.Pop();
+        return true;
+      }
+      item = default(T);
+      return false;
+    }
+
+    public override string ToString() {
+      var data = this.data as IEnumerable<T>;
+      return string.Join(Delimiter, data.Reverse());
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/FeatureTests.csproj
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/FeatureTests.csproj	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/FeatureTests.csproj	(revision 14777)
@@ -0,0 +1,84 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{B184A849-1403-4F5F-96F8-952C6599A7C0}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>TestPooling</RootNamespace>
+    <AssemblyName>TestPooling</AssemblyName>
+    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DirtyList\DirtyList.cs" />
+    <Compile Include="DirtyList\PushList.cs" />
+    <Compile Include="DirtyList\PushStack3.cs" />
+    <Compile Include="DirtyList\PushStack.cs" />
+    <Compile Include="Pool\IPooledObject.cs" />
+    <Compile Include="Pool\ManagedPool.cs" />
+    <Compile Include="Pool\ManagedPoolProvider.cs" />
+    <Compile Include="Pool\ObjectPool.cs" />
+    <Compile Include="Pool\PooledList.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Problems.ProgramSynthesis\HeuristicLab.Problems.ProgramSynthesis.csproj">
+      <Project>{5C93448C-47E3-4C3F-B1D0-EE62A48C3204}</Project>
+      <Name>HeuristicLab.Problems.ProgramSynthesis</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/IPooledObject.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/IPooledObject.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/IPooledObject.cs	(revision 14777)
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestPooling.Pool
+{
+    public interface IPooledObject
+    {
+      void Reset();
+    }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPool.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPool.cs	(revision 14777)
@@ -0,0 +1,61 @@
+﻿using System.Collections.Generic;
+
+namespace TestPooling.Pool {
+  using System;
+  using System.Collections.Concurrent;
+  using System.Linq;
+
+  public class ManagedPool<T> : IDisposable where T : class, IPooledObject {
+
+    private static readonly ConcurrentStack<LinkedList<T>> Pool = new ConcurrentStack<LinkedList<T>>();
+    private readonly Func<T> Factory;
+    public readonly int PartitionSize;
+
+    private readonly IList<LinkedList<T>> partitions = new List<LinkedList<T>>();
+    private LinkedList<T> currentPartition;
+    private LinkedListNode<T> currentNode;
+
+    private int entryIndex = 0;
+
+    public static int InstanceCount { get { return Pool.Sum(p => p.Count); } }
+
+    public ManagedPool(int partitionSize, Func<T> factory) {
+      PartitionSize = partitionSize;
+      Factory = factory;
+    }
+
+    public T Get() {
+      if (currentPartition == null || entryIndex == PartitionSize) {
+        currentPartition = GetPartition();
+        currentNode = currentPartition.First;
+        entryIndex = 0;
+
+        partitions.Add(currentPartition);
+      }
+
+      T entry;
+      if (currentNode == null) {
+        entry = Factory();
+        currentPartition.AddLast(entry);
+      } else {
+        entry = currentNode.Value;
+        currentNode = currentNode.Next;
+      }
+
+      entryIndex++;
+      entry.Reset();
+
+      return entry;
+    }
+
+    private LinkedList<T> GetPartition() {
+      LinkedList<T> partition;
+
+      return Pool.TryPop(out partition) ? partition : new LinkedList<T>();
+    }
+
+    public void Dispose() {
+      Pool.PushRange(partitions.ToArray());
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPoolProvider.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPoolProvider.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPoolProvider.cs	(revision 14777)
@@ -0,0 +1,102 @@
+﻿namespace TestPooling.Pool {
+  using System;
+  using System.Collections.Concurrent;
+  using System.Collections.Generic;
+  using System.IO;
+  using System.Linq;
+  using System.Runtime.Serialization.Formatters.Binary;
+
+  public interface IManagedPool<T> : IDisposable where T : class, IPooledObject {
+    T Get();
+  }
+
+  public class ManagedPoolProvider<T> where T : class, IPooledObject {
+    private readonly ConcurrentStack<T[]> partitions = new ConcurrentStack<T[]>();
+    private readonly ObjectPool<IManagedPool<T>> managedPools;
+    private readonly BinaryFormatter binaryFormatter = new BinaryFormatter();
+    private byte[] dummyPartition;
+
+    public readonly int PartitionSize;
+    public readonly int MaxParitionCount;
+    public const int DefaultMaxInstanceCount = 65536;
+
+    public ManagedPoolProvider(int partitionSize, Func<T> factory, int? maxPartitionCount = null) {
+      PartitionSize = partitionSize;
+      MaxParitionCount = maxPartitionCount ?? DefaultMaxInstanceCount / PartitionSize;
+
+      managedPools = new ObjectPool<IManagedPool<T>>(() => new ManagedPool<T>(this));
+
+      InitDummyPartition(factory);
+    }
+
+    private void InitDummyPartition(Func<T> factory) {
+      var temp = new T[PartitionSize];
+
+      for (var i = 0; i < PartitionSize; i++) {
+        temp[i] = factory();
+      }
+
+      using (var memoryStream = new MemoryStream()) {
+        binaryFormatter.Serialize(memoryStream, temp);
+        dummyPartition = memoryStream.ToArray();
+      }
+    }
+
+    public int InstanceCount { get { return partitions.Count * PartitionSize; } }
+
+    public void ReleasePartitions(params T[][] partition) {
+      if (partitions.Count <= MaxParitionCount && partition.Length > 0)
+        partitions.PushRange(partition);
+    }
+
+    private T[] GetPartition() {
+      T[] partition;
+      return partitions.TryPop(out partition) ? partition : CloneDummyPartition();
+    }
+
+    private T[] CloneDummyPartition() {
+      using (var memoryStream = new MemoryStream(dummyPartition)) {
+        memoryStream.Seek(0, SeekOrigin.Begin);
+
+        return (T[])binaryFormatter.Deserialize(memoryStream);
+      }
+    }
+
+    public IManagedPool<T> CreatePool() {
+      return managedPools.Allocate();
+    }
+
+    private class ManagedPool<T> : IManagedPool<T> where T : class, IPooledObject {
+      private readonly ManagedPoolProvider<T> provider;
+      private readonly IList<T[]> partitions = new List<T[]>();
+      private T[] currentPartition;
+      private int entryIndex;
+
+      public ManagedPool(ManagedPoolProvider<T> provider) {
+        this.provider = provider;
+        entryIndex = provider.PartitionSize;
+      }
+
+      public T Get() {
+        if (entryIndex == provider.PartitionSize) {
+          currentPartition = provider.GetPartition();
+          partitions.Add(currentPartition);
+          entryIndex = 0;
+        }
+
+        var entry = currentPartition[entryIndex++];
+
+        entry.Reset();
+
+        return entry;
+      }
+
+      public void Dispose() {
+        provider.ReleasePartitions(partitions.ToArray());
+        partitions.Clear();
+        entryIndex = provider.PartitionSize;
+        provider.managedPools.Free(this);
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ObjectPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ObjectPool.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ObjectPool.cs	(revision 14777)
@@ -0,0 +1,105 @@
+﻿// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace TestPooling.Pool {
+  using System.Threading;
+
+  /// <summary>
+  /// Generic implementation of object pooling pattern with predefined pool size limit. The main
+  /// purpose is that limited number of frequently used objects can be kept in the pool for
+  /// further recycling.
+  ///
+  /// Notes:
+  /// 1) it is not the goal to keep all returned objects. Pool is not meant for storage. If there
+  ///    is no space in the pool, extra returned objects will be dropped.
+  ///
+  /// 2) it is implied that if object was obtained from a pool, the caller will return it back in
+  ///    a relatively short time. Keeping checked out objects for long durations is ok, but
+  ///    reduces usefulness of pooling. Just new up your own.
+  ///
+  /// Not returning objects to the pool in not detrimental to the pool's work, but is a bad practice.
+  /// Rationale:
+  ///    If there is no intent for reusing the object, do not use pool - just use "new".
+  /// </summary>
+  public sealed class ObjectPool<T> where T : class {
+    private struct Element {
+      internal T Value;
+    }
+
+    // storage for the pool objects.
+    private readonly Element[] _items;
+
+    // factory is stored for the lifetime of the pool. We will call this only when pool needs to
+    // expand. compared to "new T()", Func gives more flexibility to implementers and faster
+    // than "new T()".
+    private readonly Func<T> _factory;
+
+
+    internal ObjectPool(Func<T> factory)
+        : this(factory, Environment.ProcessorCount * 2) { }
+
+    internal ObjectPool(Func<T> factory, int size) {
+      _factory = factory;
+      _items = new Element[size];
+    }
+
+    private T CreateInstance() {
+      var inst = _factory();
+      return inst;
+    }
+
+    /// <summary>
+    /// Produces an instance.
+    /// </summary>
+    /// <remarks>
+    /// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
+    /// Note that Free will try to store recycled objects close to the start thus statistically
+    /// reducing how far we will typically search.
+    /// </remarks>
+    internal T Allocate() {
+      var items = _items;
+      T inst;
+
+      for (int i = 0; i < items.Length; i++) {
+        // Note that the read is optimistically not synchronized. That is intentional.
+        // We will interlock only when we have a candidate. in a worst case we may miss some
+        // recently returned objects. Not a big deal.
+        inst = items[i].Value;
+        if (inst != null) {
+          if (inst == Interlocked.CompareExchange(ref items[i].Value, null, inst)) {
+            goto gotInstance;
+          }
+        }
+      }
+
+      inst = CreateInstance();
+      gotInstance:
+
+      return inst;
+    }
+
+    /// <summary>
+    /// Returns objects to the pool.
+    /// </summary>
+    /// <remarks>
+    /// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
+    /// Note that Free will try to store recycled objects close to the start thus statistically
+    /// reducing how far we will typically search in Allocate.
+    /// </remarks>
+    internal void Free(T obj) {
+      var items = _items;
+      for (int i = 0; i < items.Length; i++) {
+        if (items[i].Value == null) {
+          // Intentionally not using interlocked here.
+          // In a worst case scenario two objects may be stored into same slot.
+          // It is very unlikely to happen and will only mean that one of the objects will get collected.
+          items[i].Value = obj;
+          break;
+        }
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/PooledList.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/PooledList.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/PooledList.cs	(revision 14777)
@@ -0,0 +1,12 @@
+﻿using System.Collections.Generic;
+
+namespace TestPooling.Pool {
+  using System;
+
+  [Serializable]
+  public class PooledList<T> : List<T>, IPooledObject {
+    public void Reset() {
+      this.Clear();
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Program.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Program.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Program.cs	(revision 14777)
@@ -0,0 +1,529 @@
+﻿using System.Threading.Tasks;
+
+namespace TestPooling {
+  using System;
+  using System.Collections.Generic;
+  using System.Diagnostics;
+  using System.Linq;
+  using System.Threading;
+  using DirtyList;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Generators;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
+  using HeuristicLab.Random;
+
+  using TestPooling.Pool;
+
+  class Program {
+    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();
+      //Test1_2();
+      //Test3();
+
+      //TestCollectionPooling();
+
+      //DirtyListTest();
+
+      //TestAddRangeNConcat();
+
+      //TestStacks();
+
+      //SimpleTest();
+      //Stepwise().Wait();
+      //PerformanceTestInterpreter();
+      //PerformanceParallelTestInterpreter();
+      //PerformanceTestLinearCodeGenerator();
+      TestRobustness();
+      //TestPool();
+      //TestPoolPerformance();
+      //TestSimplifier();
+      //FlagsTest();
+      //TestExpressionDependencies();
+
+      Console.WriteLine("\nPress any key to continue...");
+      Console.ReadKey(false);
+    }
+
+    private static void TestExpressionDependencies() {
+      var enabledExpressions = ExpressionTable.GetEnabledExpressionsByStackTypes(StackTypes.Boolean | StackTypes.Integer);
+    }
+
+    private static void FlagsTest() {
+      var types = StackTypes.Boolean | StackTypes.Char | StackTypes.Integer;
+
+      StackTypes test1 = (StackTypes)(StackTypes.Boolean - types);
+      StackTypes test2 = (StackTypes)((StackTypes.Boolean | StackTypes.Float) - types);
+      StackTypes test3 = ((StackTypes.Boolean | StackTypes.Float) & types);
+      StackTypes test4 = ((StackTypes.Boolean | StackTypes.Float) ^ types);
+      StackTypes test5 = ((StackTypes.Boolean | StackTypes.Float) | types);
+      StackTypes test6 = (StackTypes.Boolean | StackTypes.Float) & ~types;
+      StackTypes test7 = StackTypes.Boolean & ~types;
+    }
+
+    private static void TestStacks() {
+      var sw = new Stopwatch();
+      var stack = new DirtyList.PushStack<int>();
+      var stack2 = new PushStack2<int>();
+      var stack3 = new PushStack3<int>();
+      var listC = new List<int>(1000);
+      var count = 200000;
+      var repeats = 10;
+
+      for (var i = 0; i < 100; i++) {
+        listC.Add(i);
+      }
+
+      sw.Start();
+      for (var j = 0; j < repeats; j++) {
+        stack.Clear();
+
+        for (int i = 0; i < count; i++) {
+          stack.Push(listC);
+        }
+      }
+      sw.Stop();
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats);
+
+      sw.Restart();
+      for (var j = 0; j < repeats; j++) {
+        stack2.Clear();
+
+        for (int i = 0; i < count; i++) {
+          stack2.PushRange(listC);
+        }
+      }
+      sw.Stop();
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats);
+
+      sw.Restart();
+      for (var j = 0; j < repeats; j++) {
+        stack3.Clear();
+
+        for (int i = 0; i < count; i++) {
+          stack3.PushRange(listC);
+        }
+      }
+      sw.Stop();
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats);
+
+      sw.Restart();
+      for (int i = 0; i < count * listC.Count; i++) {
+        stack.Pop();
+      }
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds);
+
+      sw.Restart();
+      for (int i = 0; i < count * listC.Count; i++) {
+        stack2.Pop();
+      }
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds);
+
+
+    }
+
+    private static void TestAddRangeNConcat() {
+      var sw = new Stopwatch();
+      var count = 10000;
+      var listA = new List<int>();
+      var listB = new List<int>();
+      var listC = new List<int>(1000);
+
+      for (var i = 0; i < 1000; i++) {
+        listC.Add(i);
+      }
+
+      sw.Start();
+      for (int i = 0; i < count; i++) {
+        listA.AddRange(listC);
+      }
+      sw.Stop();
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds);
+
+      sw.Restart();
+      for (int i = 0; i < count; i++) {
+        listB = listB.Concat(listC).ToList();
+      }
+      sw.Stop();
+
+      Console.WriteLine("{0}", sw.ElapsedMilliseconds);
+
+    }
+
+    private static void DirtyListTest() {
+      var sw = new Stopwatch();
+      var provider = new ManagedPoolProvider<Person>(100, () => new Person());
+      var provider2 = new ManagedPoolProvider<Person>(100, () => new Person());
+      var dl = new DirtyList<Person>();
+      var l = new List<Person>();
+
+      sw.Start();
+      for (var i = 0; i < 30000000; i++) {
+        using (var pool = provider.CreatePool()) {
+          for (var j = 0; j < 2; j++) {
+            var person = pool.Get();
+            person.Age = i + j;
+            person.Name = (i + j).ToString();
+
+            dl.Add(person);
+          }
+        }
+
+        dl.Clear();
+      }
+      sw.Stop();
+
+      Console.WriteLine("DirtyList: {0}", sw.Elapsed.TotalSeconds);
+
+      sw.Restart();
+      for (var i = 0; i < 30000000; i++) {
+        using (var pool = provider2.CreatePool()) {
+          for (var j = 0; j < 2; j++) {
+            var person = pool.Get();
+            person.Age = i + j;
+            person.Name = (i + j).ToString();
+
+            l.Add(person);
+          }
+        }
+
+        l.Clear();
+      }
+      sw.Stop();
+
+      Console.WriteLine("List: {0}", sw.Elapsed.TotalSeconds);
+    }
+
+    private static void TestCollectionPooling() {
+      var sw = new Stopwatch();
+      sw.Start();
+
+      var provider = new ManagedPoolProvider<PooledList<Person>>(PartitionSize, () => new PooledList<Person>());
+
+      Parallel.For(0, PopulationCount, pc => {
+        for (var e = 0; e < ExampleCount; e++) {
+          using (var pool = provider.CreatePool()) {
+            var list = pool.Get();
+
+            for (var i = 0; i < InstanceCount; i++)
+              list.Add(new Person {
+                Age = pc + e + i,
+                Name = string.Format("{0} - {1} - {2}", pc, e, i)
+              });
+          }
+        }
+      });
+      sw.Stop();
+
+      Console.WriteLine("Collection Pooling - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, provider.InstanceCount, TotalInstanceCount);
+    }
+
+
+    private static void Test1() {
+      var sw = new Stopwatch();
+
+      sw.Start();
+      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} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, ManagedPool<Person>.InstanceCount, TotalInstanceCount);
+    }
+
+    private static void Test1_2() {
+      var sw = new Stopwatch();
+      sw.Start();
+
+      var provider = new ManagedPoolProvider<Person>(PartitionSize, () => new Person());
+
+      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();
+
+      Console.WriteLine("1_2 - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, provider.InstanceCount, TotalInstanceCount);
+    }
+
+    private static void Test3() {
+      var count = 0;
+      var sw = new Stopwatch();
+
+      sw.Start();
+      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)
+            };
+          }
+
+          Interlocked.Add(ref count, list.Length);
+        }
+      });
+      sw.Stop();
+
+      Console.WriteLine("3 - Duration: {0} - {1}", sw.ElapsedTicks, sw.Elapsed.TotalSeconds);
+      Console.WriteLine("PartitionSize: {0}", count);
+    }
+
+    private static void Test2() {
+      var pool = new ObjectPool<Person>(() => new Person(), 2048);
+
+      Parallel.For(0, 10000, i => {
+        for (var j = 0; j < 3000; j++) {
+          var person = pool.Allocate();
+          person.Age = i + j;
+          person.Name = string.Format("{0} - {1}", i, j);
+        }
+
+        //pool.Free()
+      });
+    }
+
+    static void SimpleTest() {
+      var interpreter = new PushInterpreter();
+
+      interpreter.Run("5 INTEGER.DUP INTEGER.+");
+
+      interpreter.PrintStacks();
+    }
+
+    static async Task Stepwise() {
+      var interpreter = new PushInterpreter();
+
+      interpreter.RunAsync("( 0 2 CODE.QUOTE ( 1 INTEGER.+ 0 3 CODE.QUOTE ( 1 INTEGER.+ INTEGER.* ) CODE.DO*RANGE INTEGER.+ ) CODE.DO*RANGE )", true).Wait();
+
+      while (!interpreter.IsCompleted) {
+        Console.Clear();
+        interpreter.PrintStacks();
+        interpreter.Step();
+
+        var input = Console.ReadKey();
+        if (input.Key == ConsoleKey.Escape) {
+          break;
+        } else if (input.Key == ConsoleKey.Spacebar) {
+          await interpreter.ResumeAsync();
+        }
+      }
+
+      Console.Clear();
+      interpreter.PrintStacks();
+    }
+
+    static void PerformanceTestInterpreter() {
+      var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )");
+
+      var interpreter = new PushInterpreter();
+      var sw = new Stopwatch();
+
+      sw.Start();
+      for (var i = 0; i < 60000000; i++) {
+        interpreter.Run(program);
+        interpreter.Clear();
+      }
+      sw.Stop();
+
+      Console.WriteLine(sw.Elapsed);
+    }
+
+    static void PerformanceParallelTestInterpreter() {
+      var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )");
+
+      var sw = new Stopwatch();
+      var iterations = 100;
+      var amount = 600000;
+      var pool = new PushInterpreterPool(iterations, 1024);
+
+      sw.Start();
+      Parallel.For(0, iterations, i => {
+        using (var interpreter = pool.Create()) {
+          for (var j = 0; j < amount; j++) {
+            interpreter.Run(program);
+            interpreter.Clear();
+          }
+        }
+      });
+      sw.Stop();
+
+      Console.WriteLine(sw.Elapsed);
+    }
+
+    static void PerformanceTestRecursiveCodeGenerator() {
+      var sw = new Stopwatch();
+      var random = new FastRandom(1337);
+
+      sw.Start();
+      var expressions = RecursiveCodeGenerator.RandomCode(60000000, random).ToList();
+      sw.Stop();
+
+      Console.WriteLine("Generated {0} in {1}", expressions.Count, sw.Elapsed);
+    }
+
+    static void PerformanceTestLinearCodeGenerator() {
+      var sw = new Stopwatch();
+      var random = new FastRandom(1337);
+      var poolProvider = new ManagedPoolProvider<PooledList<Expression>>(65636, () => new PooledList<Expression>());
+
+      sw.Start();
+      var expressions = LinearCodeGenerator.RandomCode(60000000, null, random).ToList();
+      sw.Stop();
+
+      Console.WriteLine("Generated {0} in {1}", expressions.Count, sw.Elapsed);
+    }
+
+    static void TestRobustness() {
+      var sw = new Stopwatch();
+      var parallelism = Environment.ProcessorCount;
+      var maxProgramSizeLimit = 1024;
+      var partitionSize = 100000;
+      var execCounters = new int[parallelism];
+
+      var config = new PushConfiguration {
+        EvalPushLimit = 1024,
+        MaxPointsInProgram = 1024,
+        IsCodeStackEnabled = false,
+        IsExecStackEnabled = false,
+        IsBooleanStackEnabled = false,
+        IsFloatStackEnabled = false,
+        IsIntegerStackEnabled = false,
+        IsNameStackEnabled = false,
+      };
+
+      config.DisableExpression<ExecYExpression>();
+
+      var pool = new PushInterpreterPool(config);
+
+      sw.Start();
+      Parallel.For(0, parallelism, i => {
+        var random = new FastRandom(1337);
+
+        using (var interpreter = pool.Create(random)) {
+          for (var j = 0; j < partitionSize; j++) {
+            var program = LinearCodeGenerator.RandomProgram(maxProgramSizeLimit, random, config);
+            interpreter.Run(program);
+
+            execCounters[i] += interpreter.ExecCounter;
+            interpreter.Clear();
+          }
+        }
+      });
+      sw.Stop();
+
+      Console.WriteLine("ExecCount: {0}", execCounters.Sum());
+      Console.WriteLine("Duration: {0}", sw.Elapsed);
+    }
+
+    static void TestPool() {
+      var pool = new PushInterpreterPool();
+      var normal = new PushInterpreter();
+      int id;
+
+      using (var interpreter = pool.Create()) {
+        interpreter.Run("( 1 2 INTEGER.+ )");
+
+        id = interpreter.GetHashCode();
+        if (id == normal.GetHashCode()) Console.WriteLine("equal 1");
+      }
+
+      using (var interpreter = pool.Create())
+      using (var interpreter2 = pool.Create()) {
+        interpreter.Run("( 1 2 INTEGER.+ )");
+        if (id == interpreter.GetHashCode()) Console.WriteLine("equal 2");
+        if (id == interpreter2.GetHashCode()) Console.WriteLine("equal 3");
+      }
+    }
+
+    static void TestPoolPerformance() {
+      var sw = new Stopwatch();
+      var iterations = 100000000;
+
+      sw.Start();
+      for (var i = 0; i < iterations; i++) {
+        var interpreter = new PushInterpreter();
+        interpreter.Clear();
+      }
+      sw.Stop();
+
+      Console.WriteLine(sw.Elapsed);
+
+      var pool = new PushInterpreterPool();
+      sw.Restart();
+      for (var i = 0; i < iterations; i++) {
+        using (var interpreter = pool.Create()) {
+          interpreter.Clear();
+        }
+      }
+      sw.Stop();
+
+      Console.WriteLine(sw.Elapsed);
+    }
+
+    static void TestSimplifier() {
+      var program = PushParser.ParseProgram("( 5 ( INTEGER.DUP FLOAT.+ FLOAT.- ) ( EXEC.DO ( EXEC.IF ) EXEC.Y ) INTEGER.+ )");
+      var pool = new PushInterpreterPool();
+      var random = new FastRandom(1337);
+
+      var randomProg = LinearCodeGenerator.RandomProgram(4096 * 4, random);    // 53
+
+      Func<PushProgram, double> evaluator = prog => {
+        using (var interpreter = pool.Create(random)) {
+          interpreter.Run(prog);
+          return interpreter.IntegerStack.IsEmpty
+            ? double.MaxValue
+            : Math.Abs(interpreter.IntegerStack.Top - 10);
+        }
+      };
+
+      var simplerProgram = Simplifier.Simplify(program, evaluator);
+
+      Console.WriteLine(simplerProgram);
+    }
+  }
+
+  [Serializable]
+  class Person : IPooledObject {
+    public string Name { get; set; }
+    public int Age { get; set; }
+
+    public void Reset() {
+      Age = default(int);
+      Name = null;
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Properties/AssemblyInfo.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/FeatureTests/Properties/AssemblyInfo.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/FeatureTests/Properties/AssemblyInfo.cs	(revision 14777)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestPooling")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestPooling")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b184a849-1403-4f5f-96f8-952c6599a7c0")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteDataDescriptor.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteDataDescriptor.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteDataDescriptor.cs	(revision 14777)
@@ -1,4 +1,3 @@
 ﻿namespace HeuristicLab.BenchmarkSuite {
-  using System;
   using System.Collections.Generic;
   using System.IO;
@@ -8,28 +7,15 @@
   using System.Text.RegularExpressions;
 
+  using HeuristicLab.BenchmarkSuite.ERC;
   using HeuristicLab.BenchmarkSuite.Problems;
-  using HeuristicLab.Common;
-  using HeuristicLab.Core;
-  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
   using Microsoft.VisualBasic.FileIO;
 
 
-  [StorableClass]
-  public abstract class BenchmarkSuiteDataDescriptor : NamedItem, IBenchmarkSuiteDataDescriptor {
+  public abstract class BenchmarkSuiteDataDescriptor : IBenchmarkSuiteDataDescriptor {
     private const string InstanceArchiveName = "HeuristicLab.BenchmarkSuite.Data.BenchmarkExamples.zip";
     private const string ResourcePath = @".*\.Data\.";
     private const string ExampleSeparator = ",";
 
-    private const char ArrayValueSeparator = ' ';
-    private static readonly char[] ArraySymbolTrim = { '[', ']' };
-
-    protected BenchmarkSuiteDataDescriptor() { }
-
-    [StorableConstructor]
-    protected BenchmarkSuiteDataDescriptor(bool deserializing) : base(deserializing) { }
-
-
-    [Storable]
     private Example[] examples;
     public Example[] Examples
@@ -41,14 +27,39 @@
     }
 
-    public new abstract string Name { get; }
+    public Data CreateProblemData() {
+      return new Data {
+        Name = Name,
+        Description = Description,
+        Examples = Examples.ToArray(),
+        BestResult = BestResult,
+        WorstResult = WorstResult,
+        InputArgumentTypes = InputArgumentTypes,
+        OutputArgumentTypes = OutputArgumentTypes,
+        OriginalTestCount = OriginalTestCount,
+        OriginalTrainingCount = OriginalTrainingCount,
+        EnabledDataTypes = EnabledDataTypes,
+        EvalLimit = EvalLimit,
+        MaxGenerations = MaxGenerations,
+        MaxSize = MaxSize,
+        ProgEvalBudget = ProgEvalBudget,
+        ProblemErcOptions = ProblemErcOptions,
+      };
+    }
+
+    public abstract string Name { get; }
+    public abstract string Description { get; }
     protected abstract string FileName { get; }
-    public new abstract string Description { get; }
     public abstract int OriginalTrainingCount { get; }
     public abstract int OriginalTestCount { get; }
     public abstract int BestResult { get; }
     public abstract int WorstResult { get; }
-    public abstract int InputArgumentCount { get; }
-    public abstract int OutputArgumentCount { get; }
-    public int TotalArgumentCount { get { return InputArgumentCount + OutputArgumentCount; } }
+    public abstract ExampleArgumentType[] InputArgumentTypes { get; }
+    public abstract ExampleArgumentType[] OutputArgumentTypes { get; }
+    public abstract ProblemErcOptions ProblemErcOptions { get; }
+    public abstract DataTypes EnabledDataTypes { get; }
+    public abstract int MaxSize { get; }
+    public abstract int EvalLimit { get; }
+    public abstract int MaxGenerations { get; }
+    public abstract int ProgEvalBudget { get; }
 
     public abstract Example ParseExample(string[] input, string[] output);
@@ -68,9 +79,9 @@
             var fields = parser.ReadFields();
 
-            if (fields.Length != TotalArgumentCount)
+            if (fields.Length != InputArgumentTypes.Length + OutputArgumentTypes.Length)
               throw new InvalidDataException("Number of values do not fit");
 
-            var input = fields.Take(InputArgumentCount).ToArray();
-            var output = fields.Skip(InputArgumentCount).ToArray();
+            var input = fields.Take(InputArgumentTypes.Length).ToArray();
+            var output = fields.Skip(OutputArgumentTypes.Length).ToArray();
 
             yield return ParseExample(input, output);
@@ -86,49 +97,4 @@
           .SingleOrDefault(x => Regex.Match(x, ResourcePath + fileName).Success);
     }
-
-    protected static double[] ConvertDoubles(string input) {
-      return ConvertMultiple(input, double.Parse);
-    }
-
-    protected static double ConvertDouble(string input) {
-      return double.Parse(input);
-    }
-
-    protected static long[] ConvertIntegers(string input) {
-      return ConvertMultiple(input, long.Parse);
-    }
-
-    protected static long ConvertInteger(string input) {
-
-      return string.IsNullOrEmpty(input) ? default(long) : long.Parse(input);
-    }
-
-    protected static T[] ConvertMultiple<T>(string input, Func<string, T> converter) {
-      return input
-       .Trim(ArraySymbolTrim)
-       .Split(ArrayValueSeparator)
-       .Where(s => !string.IsNullOrWhiteSpace(s))
-       .Select(converter)
-       .ToArray();
-    }
-
-    protected static IEnumerable<string> SplitByNewLine(string input) {
-      return input.Split(new[] { Environment.NewLine, "\n", "\r\n" }, StringSplitOptions.None);
-    }
-
-    private static string[] trueFormats = new[] { "true", "t", "1" };
-    private static string[] falseFormats = new[] { "false", "f", "0" };
-
-    protected static bool ConvertBool(string input) {
-      var str = input.ToLower();
-
-      if (trueFormats.Contains(str)) return true;
-      if (falseFormats.Contains(str)) return false;
-      throw new InvalidDataException(string.Format("Unable to parse {0} as boolean", str));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return this;
-    }
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteInstanceProvider.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteInstanceProvider.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/BenchmarkSuiteInstanceProvider.cs	(revision 14777)
@@ -7,5 +7,5 @@
   using HeuristicLab.Problems.Instances;
 
-  public class BenchmarkSuiteInstanceProvider : ProblemInstanceProvider<IBenchmarkSuiteDataDescriptor> {
+  public class BenchmarkSuiteInstanceProvider : ProblemInstanceProvider<Data> {
     private const string name = "General Program Synthesis Benchmark Suite";
     private const string referencePublication =
@@ -36,5 +36,5 @@
       yield return new CountOdds();
       //yield return new CollatzNumbers();
-      yield return new Checksum();
+      //yield return new Checksum();
       //yield return new CompareStringLengths();
       //yield return new Digits();
@@ -52,6 +52,8 @@
     }
 
-    public override IBenchmarkSuiteDataDescriptor LoadData(IDataDescriptor descriptor) {
-      return (IBenchmarkSuiteDataDescriptor)descriptor;
+    public override Data LoadData(IDataDescriptor descriptor) {
+      var benchmarkSuiteDataDescriptor = (IBenchmarkSuiteDataDescriptor)descriptor;
+
+      return benchmarkSuiteDataDescriptor.CreateProblemData();
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/DataTypes.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/DataTypes.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/DataTypes.cs	(revision 14777)
@@ -0,0 +1,21 @@
+﻿namespace HeuristicLab.BenchmarkSuite {
+  using System;
+
+  [Flags]
+  public enum DataTypes : ushort {
+    None = 0x00, // Required to specify expression dependencies
+    Integer = 0x02,
+    Float = 0x04,
+    Char = 0x08,
+    String = 0x10,
+    Boolean = 0x20,
+    Name = 0x40,
+    Code = 0x80,
+    Exec = 0x100,
+    IntegerVector = 0x200,
+    FloatVector = 0x400,
+    StringVector = 0x800,
+    Print = 0x1000,
+    FileInput = 0x2000,
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/BooleanErcOptions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/BooleanErcOptions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/BooleanErcOptions.cs	(revision 14777)
@@ -0,0 +1,26 @@
+﻿namespace HeuristicLab.BenchmarkSuite.ERC {
+  using HeuristicLab.Common;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class BooleanErcOptions : ErcOption<bool> {
+    public BooleanErcOptions() { }
+
+    [StorableConstructor]
+    public BooleanErcOptions(bool deserializing) : base(deserializing) { }
+
+    public BooleanErcOptions(BooleanErcOptions origin, Cloner cloner) : base(origin, cloner) {
+      AllowFalse = origin.AllowFalse;
+      AllowTrue = origin.AllowTrue;
+    }
+
+    [Storable]
+    public bool AllowFalse { get; set; }
+    [Storable]
+    public bool AllowTrue { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BooleanErcOptions(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOption.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOption.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOption.cs	(revision 14777)
@@ -0,0 +1,35 @@
+﻿namespace HeuristicLab.BenchmarkSuite.ERC {
+  using System.Linq;
+
+  using HeuristicLab.Common;
+  using HeuristicLab.Core;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class ErcOption<T> : NamedItem {
+
+    public ErcOption() {
+      Constants = new T[0];
+    }
+
+    public ErcOption(params T[] constants) {
+      Constants = constants;
+    }
+
+    [StorableConstructor]
+    public ErcOption(bool deserializing)
+      : base(deserializing) {
+      Constants = new T[0];
+    }
+
+    public ErcOption(ErcOption<T> origin, Cloner cloner) : base(origin, cloner) {
+      this.Constants = origin.Constants.ToArray();
+    }
+
+    public T[] Constants { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ErcOption<T>(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOptionRange.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOptionRange.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ErcOptionRange.cs	(revision 14777)
@@ -0,0 +1,28 @@
+﻿namespace HeuristicLab.BenchmarkSuite.ERC {
+  using HeuristicLab.Common;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class ErcOptionRange<T> : ErcOption<T>
+    where T : class, IDeepCloneable {
+    public ErcOptionRange(T start, T end, params T[] constants) : base(constants) {
+      Start = start;
+      End = end;
+    }
+
+    [StorableConstructor]
+    public ErcOptionRange(bool deserializing) : base(deserializing) { }
+
+    public ErcOptionRange(ErcOptionRange<T> origin, Cloner cloner) : base(origin, cloner) {
+      Start = cloner.Clone(origin.Start);
+      End = cloner.Clone(origin.End);
+    }
+
+    public T Start { get; set; }
+    public T End { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ErcOptionRange<T>(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ProblemErcOptions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ProblemErcOptions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/ProblemErcOptions.cs	(revision 14777)
@@ -0,0 +1,44 @@
+﻿namespace HeuristicLab.BenchmarkSuite.ERC {
+  using HeuristicLab.Common;
+  using HeuristicLab.Core;
+  using HeuristicLab.Data;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class ProblemErcOptions : NamedItem {
+    public ProblemErcOptions() { }
+
+    [StorableConstructor]
+    public ProblemErcOptions(bool deserializing) : base(deserializing) { }
+
+    public ProblemErcOptions(ProblemErcOptions origin, Cloner cloner) : base(origin, cloner) {
+      this.IntegerErcRange = cloner.Clone(origin.IntegerErcRange);
+      this.FloatErcRange = cloner.Clone(origin.FloatErcRange);
+      this.CharERCRange = cloner.Clone(origin.CharERCRange);
+      this.StringERCOptions = cloner.Clone(origin.StringERCOptions);
+      this.BooleanErcOptions = cloner.Clone(origin.BooleanErcOptions);
+    }
+
+    [Storable]
+    public double ErcProbability { get; set; }
+    [Storable]
+    public ErcOptionRange<IntValue> IntegerErcRange { get; set; }
+    [Storable]
+    public ErcOptionRange<DoubleValue> FloatErcRange { get; set; }
+    [Storable]
+    public BooleanErcOptions BooleanErcOptions { get; set; }
+
+    /// <summary>
+    /// Integer represents ASCII value
+    /// </summary>
+    [Storable]
+    public ErcOptionRange<IntValue> CharERCRange { get; set; }
+
+    [Storable]
+    public StringErcOptions StringERCOptions { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ProblemErcOptions(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/StringErcOptions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/StringErcOptions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ERC/StringErcOptions.cs	(revision 14777)
@@ -0,0 +1,33 @@
+﻿namespace HeuristicLab.BenchmarkSuite.ERC {
+  using HeuristicLab.Common;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class StringErcOptions : ErcOption<string> {
+
+    public StringErcOptions() { }
+
+    [StorableConstructor]
+    public StringErcOptions(bool deserializing) : base(deserializing) { }
+
+    public StringErcOptions(StringErcOptions origin, Cloner cloner) : base(origin, cloner) {
+      AllowLowercaseLetters = origin.AllowLowercaseLetters;
+      AllowUppercaseLetters = origin.AllowUppercaseLetters;
+      AllowSpace = origin.AllowSpace;
+      SpacePropability = origin.SpacePropability;
+    }
+
+    [Storable]
+    public bool AllowLowercaseLetters { get; set; }
+    [Storable]
+    public bool AllowUppercaseLetters { get; set; }
+    [Storable]
+    public bool AllowSpace { get; set; }
+    [Storable]
+    public double SpacePropability { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringErcOptions(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Example.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Example.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Example.cs	(revision 14777)
@@ -1,9 +1,69 @@
-﻿namespace HeuristicLab.BenchmarkSuite
-{
-  public class Example
-  {
-    public string Input { get; set; }
+﻿namespace HeuristicLab.BenchmarkSuite {
+  using System.Linq;
 
-    public string Output { get; set; }
+  using HeuristicLab.Common;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class Example : DeepCloneable {
+    public Example() {
+      this.InputInt = new long[0];
+      this.InputFloat = new double[0];
+      this.InputBoolean = new bool[0];
+      this.OutputInt = this.InputInt;
+      this.OutputFloat = this.InputFloat;
+      this.OutputBoolean = this.InputBoolean;
+    }
+
+    public Example(Example origin, Cloner cloner) : base(origin, cloner) {
+      origin.CopyTo(this);
+    }
+
+    [StorableConstructor]
+    public Example(bool deserializing) { }
+
+    public void CopyTo(Example example) {
+      example.InputArgs = InputArgs.ToArray();
+      example.OutputArgs = OutputArgs.ToArray();
+
+      example.InputBoolean = InputBoolean.ToArray();
+      example.InputInt = InputInt.ToArray();
+      example.InputFloat = InputFloat.ToArray();
+
+      example.OutputBoolean = OutputBoolean.ToArray();
+      example.OutputInt = OutputInt.ToArray();
+      example.OutputFloat = OutputFloat.ToArray();
+    }
+
+    [Storable]
+    public string[] InputArgs { get; set; }
+    [Storable]
+    public string[] OutputArgs { get; set; }
+
+    [Storable]
+    public long[] InputInt { get; set; }
+    [Storable]
+    public double[] InputFloat { get; set; }
+    [Storable]
+    public bool[] InputBoolean { get; set; }
+    [Storable]
+    public char[] InputChar { get; set; }
+    [Storable]
+    public string[] InputString { get; set; }
+
+    [Storable]
+    public long[] OutputInt { get; set; }
+    [Storable]
+    public double[] OutputFloat { get; set; }
+    [Storable]
+    public bool[] OutputBoolean { get; set; }
+    [Storable]
+    public char[] OutputChar { get; set; }
+    [Storable]
+    public string[] OutputString { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Example(this, cloner);
+    }
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentConverter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentConverter.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentConverter.cs	(revision 14777)
@@ -0,0 +1,60 @@
+﻿namespace HeuristicLab.BenchmarkSuite {
+  using System;
+  using System.Collections.Generic;
+  using System.IO;
+  using System.Linq;
+
+  public static class ExampleArgumentConverter {
+    private static readonly char[] ArrayValueSeparator = { ' ', ',', ';' };
+    private static readonly char[] ArraySymbolTrim = { '[', ']', '(', ')' };
+    public static double[] ConvertDoubles(string input) {
+      return ConvertMultiple(input, double.Parse);
+    }
+
+    public static double ConvertDouble(string input) {
+      return double.Parse(input);
+    }
+
+    public static long[] ConvertIntegers(string input) {
+      return ConvertMultiple(input, long.Parse);
+    }
+
+    public static long ConvertInteger(string input) {
+
+      return string.IsNullOrEmpty(input) ? default(long) : long.Parse(input);
+    }
+
+    public static T[] ConvertMultiple<T>(string input, Func<string, T> converter) {
+      return input
+       .Trim(ArraySymbolTrim)
+       .Split(ArrayValueSeparator)
+       .Where(s => !string.IsNullOrWhiteSpace(s))
+       .Select(converter)
+       .ToArray();
+    }
+
+    public static IEnumerable<string> SplitByNewLine(string input) {
+      return input.Split(new[] { Environment.NewLine, "\n", "\r\n" }, StringSplitOptions.None);
+    }
+
+    private static string[] trueFormats = new[] { "true", "t", "1" };
+    private static string[] falseFormats = new[] { "false", "f", "0" };
+
+    public static bool ConvertBoolean(string input) {
+      var str = input.ToLower();
+
+      if (trueFormats.Contains(str)) return true;
+      if (falseFormats.Contains(str)) return false;
+      throw new InvalidDataException(string.Format("Unable to parse {0} as boolean", str));
+    }
+
+    public static bool[] ConvertBooleans(string input) {
+      return input
+        .Trim(ArraySymbolTrim)
+        .Split(ArrayValueSeparator)
+        .Where(s => !string.IsNullOrWhiteSpace(s))
+        .Select(ConvertBoolean)
+        .ToArray();
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentType.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentType.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/ExampleArgumentType.cs	(revision 14777)
@@ -0,0 +1,12 @@
+﻿namespace HeuristicLab.BenchmarkSuite {
+  public enum ExampleArgumentType {
+    Integer,
+    IntegerCollection,
+    Float,
+    FloatCollection,
+    Bool,
+    String,
+    StringCollection,
+    Char,
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/HeuristicLab.BenchmarkSuite.csproj
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/HeuristicLab.BenchmarkSuite.csproj	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/HeuristicLab.BenchmarkSuite.csproj	(revision 14777)
@@ -47,4 +47,8 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
@@ -97,7 +101,16 @@
     <Compile Include="BenchmarkSuiteDataDescriptor.cs" />
     <Compile Include="BenchmarkSuiteInstanceProvider.cs" />
+    <Compile Include="DataTypes.cs" />
+    <Compile Include="ERC\BooleanErcOptions.cs" />
+    <Compile Include="ERC\ProblemErcOptions.cs" />
+    <Compile Include="ERC\ErcOption.cs" />
+    <Compile Include="ERC\ErcOptionRange.cs" />
+    <Compile Include="ERC\StringErcOptions.cs" />
+    <Compile Include="ExampleArgumentConverter.cs" />
     <Compile Include="IBenchmarkSuiteDataDescriptor.cs" />
     <Compile Include="Plugin.cs" />
-    <Compile Include="Problems\Example.cs" />
+    <Compile Include="Problems\Data.cs" />
+    <Compile Include="Example.cs" />
+    <Compile Include="ExampleArgumentType.cs" />
     <Compile Include="Problems\ReplaceSpaceWithNewline.cs" />
     <Compile Include="Problems\PigLatin.cs" />
@@ -116,4 +129,5 @@
     <Compile Include="Problems\CountOdds.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Views\ViewHelper.cs" />
     <Compile Include="Views\DataEditorView.cs">
       <SubType>UserControl</SubType>
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/IBenchmarkSuiteDataDescriptor.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/IBenchmarkSuiteDataDescriptor.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/IBenchmarkSuiteDataDescriptor.cs	(revision 14777)
@@ -1,22 +1,8 @@
 ﻿namespace HeuristicLab.BenchmarkSuite {
   using HeuristicLab.BenchmarkSuite.Problems;
-  using HeuristicLab.Core;
   using HeuristicLab.Problems.Instances;
 
-  public interface IBenchmarkSuiteDataDescriptor : IDataDescriptor, INamedItem {
-    //Data CreateData();
-    Example[] Examples { get; }
-
-    string Name { get; }
-    string Description { get; }
-    int OriginalTrainingCount { get; }
-    int OriginalTestCount { get; }
-    int BestResult { get; }
-    int WorstResult { get; }
-    int InputArgumentCount { get; }
-    int OutputArgumentCount { get; }
-    int TotalArgumentCount { get; }
-
-    Example ParseExample(string[] input, string[] output);
+  public interface IBenchmarkSuiteDataDescriptor : IDataDescriptor {
+    Data CreateProblemData();
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Checksum.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Checksum.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Checksum.cs	(revision 14777)
@@ -1,36 +1,31 @@
-﻿namespace HeuristicLab.BenchmarkSuite.Problems {
-  using System;
-  using System.Text;
+﻿//namespace HeuristicLab.BenchmarkSuite.Problems {
+//  using System;
+//  using System.Text;
 
-  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+//  public class Checksum : BenchmarkSuiteDataDescriptor {
+//    private const string name = "Checksum";
+//    private const string fileName = "Checksum.csv";
+//    private const string description = "";
+//    private readonly ExampleArgumentType[] inputArgumentTypes = { ExampleArgumentType.IntegerCollection };
+//    private readonly ExampleArgumentType[] outputArgumentTypes = { ExampleArgumentType.IntegerCollection };
 
-  [StorableClass]
-  public class Checksum : BenchmarkSuiteDataDescriptor {
-    private const string name = "Checksum";
-    private const string fileName = "Checksum.csv";
-    private const string description = "";
-    public Checksum() { }
+//    public override string Name { get { return name; } }
+//    protected override string FileName { get { return fileName; } }
+//    public override string Description { get { return description; } }
+//    public override ExampleArgumentType[] InputArgumentTypes { get { return inputArgumentTypes; } }
+//    public override ExampleArgumentType[] OutputArgumentTypes { get { return outputArgumentTypes; } }
+//    public override int OriginalTrainingCount { get { return 228; } }
+//    public override int OriginalTestCount { get { return 1254; } }
+//    public override int BestResult { get { return 0; } }
+//    public override int WorstResult { get { return byte.MaxValue; } }
 
-    [StorableConstructor]
-    public Checksum(bool deserializing) : base(deserializing) { }
-
-    public override string Name { get { return name; } }
-    protected override string FileName { get { return fileName; } }
-    public override string Description { get { return description; } }
-    public override int InputArgumentCount { get { return 1; } }
-    public override int OutputArgumentCount { get { return 1; } }
-    public override int OriginalTrainingCount { get { return 228; } }
-    public override int OriginalTestCount { get { return 1254; } }
-    public override int BestResult { get { return 0; } }
-    public override int WorstResult { get { return byte.MaxValue; } }
-
-    public override Example ParseExample(string[] input, string[] output) {
-      return new Example {
-        InputArgs = input,
-        OutputArgs = output,
-        InputInt = Array.ConvertAll(Encoding.ASCII.GetBytes(input[0]), c => (long)c),
-        OutputInt = Array.ConvertAll(Encoding.ASCII.GetBytes(output[0]), c => (long)c)
-      };
-    }
-  }
-}
+//    public override Example ParseExample(string[] input, string[] output) {
+//      return new Example {
+//        InputArgs = input,
+//        OutputArgs = output,
+//        InputInt = Array.ConvertAll(Encoding.ASCII.GetBytes(input[0]), c => (long)c),
+//        OutputInt = Array.ConvertAll(Encoding.ASCII.GetBytes(output[0]), c => (long)c)
+//      };
+//    }
+//  }
+//}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/CountOdds.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/CountOdds.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/CountOdds.cs	(revision 14777)
@@ -1,25 +1,38 @@
 ﻿namespace HeuristicLab.BenchmarkSuite.Problems {
-  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+  using HeuristicLab.BenchmarkSuite.ERC;
+  using HeuristicLab.Data;
 
-  [StorableClass]
   public class CountOdds : BenchmarkSuiteDataDescriptor {
     private const string name = "Count Odds";
     private const string fileName = "CountOdds.csv";
     private const string description = "";
+    private readonly ExampleArgumentType[] inputArgumentTypes = { ExampleArgumentType.IntegerCollection };
+    private readonly ExampleArgumentType[] outputArgumentTypes = { ExampleArgumentType.Integer };
 
-    public CountOdds() { }
-
-    [StorableConstructor]
-    public CountOdds(bool deserializing) : base(deserializing) { }
+    private readonly DataTypes enabledDataTypeses = DataTypes.Exec | DataTypes.Integer | DataTypes.Boolean | DataTypes.IntegerVector;
+    private readonly ProblemErcOptions problemErcOptions = new ProblemErcOptions {
+      IntegerErcRange = new ErcOptionRange<IntValue>(
+        new IntValue(-1000),
+        new IntValue(1000),
+        new IntValue(0),
+        new IntValue(1),
+        new IntValue(2))
+    };
 
     public override string Name { get { return name; } }
     public override string Description { get { return description; } }
     protected override string FileName { get { return fileName; } }
-    public override int InputArgumentCount { get { return 1; } }
-    public override int OutputArgumentCount { get { return 1; } }
+    public override ExampleArgumentType[] InputArgumentTypes { get { return inputArgumentTypes; } }
+    public override ExampleArgumentType[] OutputArgumentTypes { get { return outputArgumentTypes; } }
     public override int OriginalTrainingCount { get { return 200; } }
     public override int OriginalTestCount { get { return 2000; } }
     public override int BestResult { get { return 0; } }
     public override int WorstResult { get { return 50; } }
+    public override ProblemErcOptions ProblemErcOptions { get { return this.problemErcOptions; } }
+    public override DataTypes EnabledDataTypes { get { return this.enabledDataTypeses; } }
+    public override int MaxSize { get { return 500; } }
+    public override int EvalLimit { get { return 1500; } }
+    public override int MaxGenerations { get { return 300; } }
+    public override int ProgEvalBudget { get { return 60000000; } }
 
     public override Example ParseExample(string[] input, string[] output) {
@@ -27,6 +40,6 @@
         InputArgs = input,
         OutputArgs = output,
-        InputInt = ConvertIntegers(input[0]),
-        OutputInt = ConvertIntegers(output[0])
+        InputInt = ExampleArgumentConverter.ConvertIntegers(input[0]),
+        OutputInt = ExampleArgumentConverter.ConvertIntegers(output[0])
       };
     }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Data.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Data.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Problems/Data.cs	(revision 14777)
@@ -0,0 +1,85 @@
+﻿namespace HeuristicLab.BenchmarkSuite.Problems {
+  using System.Linq;
+
+  using HeuristicLab.BenchmarkSuite.ERC;
+  using HeuristicLab.Common;
+  using HeuristicLab.Core;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class Data : NamedItem {
+
+    public Data() { }
+
+    [StorableConstructor]
+    protected Data(bool deserializing) : base(deserializing) { }
+
+    public Data(Data origin, Cloner cloner) : base(origin, cloner) {
+      Name = origin.Name;
+      Description = origin.Description;
+      OriginalTrainingCount = origin.OriginalTrainingCount;
+      OriginalTestCount = origin.OriginalTestCount;
+      BestResult = origin.BestResult;
+      WorstResult = origin.WorstResult;
+      InputArgumentTypes = origin.InputArgumentTypes;
+      OutputArgumentTypes = origin.OutputArgumentTypes;
+      Examples = origin.Examples.ToArray();
+      EnabledDataTypes = origin.EnabledDataTypes;
+      this.ProblemErcOptions = cloner.Clone(origin.ProblemErcOptions);
+    }
+
+    [Storable]
+    public string Name { get; set; }
+    [Storable]
+    public string Description { get; set; }
+    [Storable]
+    public int OriginalTrainingCount { get; set; }
+    [Storable]
+    public int OriginalTestCount { get; set; }
+    [Storable]
+    public int BestResult { get; set; }
+    [Storable]
+    public int WorstResult { get; set; }
+    [Storable]
+    public ExampleArgumentType[] InputArgumentTypes { get; set; }
+    [Storable]
+    public ExampleArgumentType[] OutputArgumentTypes { get; set; }
+    public int TotalArgumentCount { get { return InputArgumentTypes.Length + OutputArgumentTypes.Length; } }
+    [Storable]
+    public Example[] Examples { get; set; }
+    [Storable]
+    public ProblemErcOptions ProblemErcOptions { get; set; }
+    [Storable]
+    public DataTypes EnabledDataTypes { get; set; }
+
+    /// <summary>
+    /// Max Size” gives the maximum number of instructions that can appear in an individual’s genome
+    /// </summary>
+    [Storable]
+    public int MaxSize { get; set; }
+
+    /// <summary>
+    /// “Eval Limit” is the number of steps of the Push interpreter that are executed before stopping a
+    /// program’s execution; programs halted in this way may still achieve good results if they print or
+    /// return results before they are stopped
+    /// </summary>
+    [Storable]
+    public int EvalLimit { get; set; }
+
+    /// <summary>
+    /// “Max Gens” gives the maximum number of generations in a single PushGP run.
+    /// </summary>
+    [Storable]
+    public int MaxGenerations { get; set; }
+
+    /// <summary>
+    /// “Prog Eval Budget” is the maximum number of programs that will be evaluated before a run is terminated.
+    /// </summary>
+    [Storable]
+    public int ProgEvalBudget { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Data(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.Designer.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.Designer.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.Designer.cs	(revision 14777)
@@ -33,9 +33,9 @@
       this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
       this.errorProvider.SetIconPadding(this.nameTextBox, 2);
-      this.nameTextBox.Size = new System.Drawing.Size(302, 20);
+      this.nameTextBox.Size = new System.Drawing.Size(758, 20);
       //
       // infoLabel
       //
-      this.infoLabel.Location = new System.Drawing.Point(366, 3);
+      this.infoLabel.Location = new System.Drawing.Point(822, 3);
       //
       // dataGridView
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/DataEditorView.cs	(revision 14777)
@@ -2,10 +2,14 @@
 
 namespace HeuristicLab.BenchmarkSuite.Views {
+
+  using HeuristicLab.BenchmarkSuite.Problems;
   using HeuristicLab.Core.Views;
   using HeuristicLab.MainForm;
 
   [View("Push Expression Selection Editor")]
-  [Content(typeof(IBenchmarkSuiteDataDescriptor), true)]
+  [Content(typeof(Data), true)]
   public partial class DataEditorView : NamedItemView {
+    private const string ValueSeparator = ", ";
+
     public DataEditorView() {
       InitializeComponent();
@@ -20,12 +24,12 @@
       var row = dataGridView.Rows[e.RowIndex];
 
-      var inputArgs = new string[Content.InputArgumentCount];
-      for (var i = 0; i < Content.InputArgumentCount; i++) {
+      var inputArgs = new string[Content.InputArgumentTypes.Length];
+      for (var i = 0; i < Content.InputArgumentTypes.Length; i++) {
         inputArgs[i] = row.Cells[i].Value.ToString();
       }
 
-      var outputArgs = new string[Content.OutputArgumentCount];
-      for (var i = 0; i < Content.OutputArgumentCount; i++) {
-        outputArgs[i] = row.Cells[Content.InputArgumentCount + i].Value.ToString();
+      var outputArgs = new string[Content.OutputArgumentTypes.Length];
+      for (var i = 0; i < Content.OutputArgumentTypes.Length; i++) {
+        outputArgs[i] = row.Cells[Content.InputArgumentTypes.Length + i].Value.ToString();
       }
 
@@ -33,5 +37,5 @@
 
       try {
-        var newExample = Content.ParseExample(inputArgs, outputArgs);
+        var newExample = ParseExample(inputArgs, Content.InputArgumentTypes, outputArgs, Content.OutputArgumentTypes);
         newExample.CopyTo(example);
       }
@@ -40,13 +44,77 @@
 
         // reset entry
-        row.Cells[e.ColumnIndex].Value = e.ColumnIndex < Content.InputArgumentCount
+        row.Cells[e.ColumnIndex].Value = e.ColumnIndex < Content.InputArgumentTypes.Length
           ? example.InputArgs[e.ColumnIndex]
-          : example.OutputArgs[e.ColumnIndex - Content.InputArgumentCount];
+          : example.OutputArgs[e.ColumnIndex - Content.InputArgumentTypes.Length];
       }
     }
 
-    public new IBenchmarkSuiteDataDescriptor Content
+    private Example ParseExample(string[] inputArgs, ExampleArgumentType[] inputArgTypes, string[] outputArgs, ExampleArgumentType[] outputArgTypes) {
+      var example = new Example();
+
+      example.InputArgs = new string[inputArgs.Length];
+      for (var i = 0; i < inputArgs.Length; i++) {
+        var arg = inputArgs[i];
+        var type = inputArgTypes[i];
+
+        switch (type) {
+          case ExampleArgumentType.Bool:
+            example.InputBoolean = new[] { ExampleArgumentConverter.ConvertBoolean(arg) };
+            example.InputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.Integer:
+            example.InputInt = new[] { ExampleArgumentConverter.ConvertInteger(arg) };
+            example.InputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.IntegerCollection:
+            example.InputInt = ExampleArgumentConverter.ConvertIntegers(arg);
+            example.InputArgs[i] = string.Join(ValueSeparator, example.InputInt);
+            break;
+          case ExampleArgumentType.Float:
+            example.InputFloat = new[] { ExampleArgumentConverter.ConvertDouble(arg) };
+            example.InputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.FloatCollection:
+            example.InputFloat = ExampleArgumentConverter.ConvertDoubles(arg);
+            example.InputArgs[i] = string.Join(ValueSeparator, example.InputFloat);
+            break;
+        }
+      }
+
+      example.OutputArgs = new string[outputArgs.Length];
+      for (var i = 0; i < outputArgs.Length; i++) {
+        var arg = outputArgs[i];
+        var type = outputArgTypes[i];
+
+        switch (type) {
+          case ExampleArgumentType.Bool:
+            example.OutputBoolean = new[] { ExampleArgumentConverter.ConvertBoolean(arg) };
+            example.OutputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.Integer:
+            example.OutputInt = new[] { ExampleArgumentConverter.ConvertInteger(arg) };
+            example.OutputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.IntegerCollection:
+            example.OutputInt = ExampleArgumentConverter.ConvertIntegers(arg);
+            example.OutputArgs[i] = string.Join(ValueSeparator, example.OutputInt);
+            break;
+          case ExampleArgumentType.Float:
+            example.OutputFloat = new[] { ExampleArgumentConverter.ConvertDouble(arg) };
+            example.OutputArgs[i] = arg;
+            break;
+          case ExampleArgumentType.FloatCollection:
+            example.OutputFloat = ExampleArgumentConverter.ConvertDoubles(arg);
+            example.OutputArgs[i] = string.Join(ValueSeparator, example.OutputFloat);
+            break;
+        }
+      }
+
+      return example;
+    }
+
+    public new Data Content
     {
-      get { return (IBenchmarkSuiteDataDescriptor)base.Content; }
+      get { return (Data)base.Content; }
       set
       {
@@ -69,9 +137,12 @@
       }
 
+      this.nameTextBox.Text = Content.Name;
+
       var cellTemplate = new DataGridViewTextBoxCell();
 
-      for (var i = 1; i <= Content.InputArgumentCount; i++) {
+      for (var i = 0; i < Content.InputArgumentTypes.Length; i++) {
+        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.InputArgumentTypes[i]);
         var column = new DataGridViewColumn {
-          HeaderText = string.Format("Input {0}", i),
+          HeaderText = string.Format("Input {0} : {1}", i + 1, headerTypeName),
           AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
           CellTemplate = cellTemplate
@@ -81,7 +152,8 @@
       }
 
-      for (var i = 1; i <= Content.OutputArgumentCount; i++) {
+      for (var i = 0; i < Content.OutputArgumentTypes.Length; i++) {
+        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.OutputArgumentTypes[i]);
         var column = new DataGridViewColumn {
-          HeaderText = string.Format("Output {0}", i),
+          HeaderText = string.Format("Output {0} : {1}", i + 1, headerTypeName),
           AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
           CellTemplate = cellTemplate
@@ -97,10 +169,10 @@
         row.CreateCells(dataGridView);
 
-        for (var i = 0; i < Content.InputArgumentCount; i++) {
-          row.Cells[i].Value = example.InputArgs[i];
+        for (var i = 0; i < Content.InputArgumentTypes.Length; i++) {
+          row.Cells[i].Value = ViewHelper.StringifyInput(Content.InputArgumentTypes[i], example, ValueSeparator);
         }
 
-        for (var i = 0; i < Content.OutputArgumentCount; i++) {
-          row.Cells[Content.InputArgumentCount + i].Value = example.OutputArgs[i];
+        for (var i = 0; i < Content.OutputArgumentTypes.Length; i++) {
+          row.Cells[Content.InputArgumentTypes.Length + i].Value = ViewHelper.StringifyOutput(Content.OutputArgumentTypes[i], example, ValueSeparator);
         }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/ViewHelper.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/ViewHelper.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problem.ProgramSynthesis.BenchmarkSuite/Views/ViewHelper.cs	(revision 14777)
@@ -0,0 +1,59 @@
+﻿namespace HeuristicLab.BenchmarkSuite.Views {
+  public static class ViewHelper {
+    public static string StringifyInput(ExampleArgumentType type, Example example, string valueSeparator) {
+      switch (type) {
+        case ExampleArgumentType.Integer:
+        case ExampleArgumentType.IntegerCollection: return string.Join(valueSeparator, example.InputInt);
+
+        case ExampleArgumentType.Float:
+        case ExampleArgumentType.FloatCollection: return string.Join(valueSeparator, example.InputFloat);
+
+        case ExampleArgumentType.Bool: return string.Join(valueSeparator, example.InputBoolean);
+        case ExampleArgumentType.Char: return string.Join(valueSeparator, example.InputChar);
+
+        case ExampleArgumentType.String:
+        case ExampleArgumentType.StringCollection: return string.Join(valueSeparator, example.InputString);
+        default: return string.Empty;
+      }
+    }
+
+    public static string StringifyOutput(ExampleArgumentType type, Example example, string valueSeparator) {
+      switch (type) {
+        case ExampleArgumentType.Integer:
+        case ExampleArgumentType.IntegerCollection: return string.Join(valueSeparator, example.OutputInt);
+
+        case ExampleArgumentType.Float:
+        case ExampleArgumentType.FloatCollection: return string.Join(valueSeparator, example.OutputFloat);
+
+        case ExampleArgumentType.Bool: return string.Join(valueSeparator, example.OutputBoolean);
+        case ExampleArgumentType.Char: return string.Join(valueSeparator, example.OutputChar);
+
+        case ExampleArgumentType.String:
+        case ExampleArgumentType.StringCollection: return string.Join(valueSeparator, example.OutputString);
+        default: return string.Empty;
+      }
+    }
+
+    private const string IntegerColumnHeader = "int";
+    private const string IntegersColumnHeader = "int[]";
+    private const string DoubleColumnHeader = "double";
+    private const string DoublesColumnHeader = "double[]";
+    private const string BooleanColumnHeader = "bool";
+    private const string CharColumnHeader = "char";
+    private const string StringColumnHeader = "string";
+    private const string StringsColumnHeader = "string[]";
+    public static string GetHeaderTypeName(ExampleArgumentType type) {
+      switch (type) {
+        case ExampleArgumentType.Integer: return IntegerColumnHeader;
+        case ExampleArgumentType.Float: return DoubleColumnHeader;
+        case ExampleArgumentType.Bool: return BooleanColumnHeader;
+        case ExampleArgumentType.Char: return CharColumnHeader;
+        case ExampleArgumentType.String: return StringColumnHeader;
+        case ExampleArgumentType.IntegerCollection: return IntegersColumnHeader;
+        case ExampleArgumentType.FloatCollection: return DoublesColumnHeader;
+        case ExampleArgumentType.StringCollection: return StringsColumnHeader;
+        default: return string.Empty;
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj	(revision 14777)
@@ -96,4 +96,5 @@
     </Reference>
     <Reference Include="System" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
     <Reference Include="System.Core" />
     <Reference Include="System.Drawing" />
@@ -117,8 +118,14 @@
     <Compile Include="Push\Creator\PointsBasedPushProgramCreator.cs" />
     <Compile Include="Push\Data\List\SkipList.cs" />
+    <Compile Include="Push\Data\Pool\IPooledObject.cs" />
     <Compile Include="Push\Data\Pool\ManagedPoolProvider.cs" />
     <Compile Include="Push\Data\Pool\ObjectPool.cs" />
+    <Compile Include="Push\Data\Pool\PooledList.cs" />
+    <Compile Include="Push\Data\Tree\Tree.cs" />
+    <Compile Include="Push\Data\Tree\TreeExtensions.cs" />
+    <Compile Include="Push\Data\Tree\TreeNode.cs" />
     <Compile Include="Push\Exporter\Exporter.cs" />
     <Compile Include="Push\Expressions\BooleanExpressions.cs" />
+    <Compile Include="Push\Expressions\CharExpressions.cs" />
     <Compile Include="Push\Expressions\CodeExpressions.cs" />
     <Compile Include="Push\Expressions\DefineExpressions.cs" />
@@ -127,4 +134,5 @@
     <Compile Include="Push\Expressions\DoTimesExpressions.cs" />
     <Compile Include="Push\Expressions\DuplicateExpressions.cs" />
+    <Compile Include="Push\Expressions\EmptyExpresssions.cs" />
     <Compile Include="Push\Expressions\EqualsExpressions.cs" />
     <Compile Include="Push\Expressions\ExecExpressions.cs" />
@@ -137,5 +145,4 @@
     <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" />
@@ -147,9 +154,12 @@
     <Compile Include="Push\Expressions\StatefulExpression.cs" />
     <Compile Include="Push\Expressions\StatelessExpression.cs" />
+    <Compile Include="Push\Expressions\StringExpressions.cs" />
     <Compile Include="Push\Expressions\SwapExpressions.cs" />
     <Compile Include="Push\Expressions\YankDuplicateExpressions.cs" />
     <Compile Include="Push\Expressions\YankExpressions.cs" />
-    <Compile Include="Push\Generators\CodeGenerator.cs" />
+    <Compile Include="Push\Generators\LinearCodeGenerator.cs" />
+    <Compile Include="Push\Generators\RecursiveCodeGenerator.cs" />
     <Compile Include="Push\Generators\NameGenerator.cs" />
+    <Compile Include="Push\Interpreter\InterpreterPoolContainer.cs" />
     <Compile Include="Push\Interpreter\IPushInterpreter.cs" />
     <Compile Include="Push\Configuration\IReadonlyPushConfiguration.cs" />
@@ -160,13 +170,14 @@
     <Compile Include="Push\Parser\PushParser.cs" />
     <Compile Include="Push\Creator\IPushProgramCreator.cs" />
+    <Compile Include="Push\Problem\DataBounds.cs" />
     <Compile Include="Push\Problem\PushEncoding.cs" />
+    <Compile Include="Push\Problem\PushEvaluator.cs" />
     <Compile Include="Push\Problem\PushProblem.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Push\Simplifier\ISimplifier.cs" />
-    <Compile Include="Push\Simplifier\RandomSimplifier.cs" />
     <Compile Include="Push\Problem\PushSolution.cs" />
+    <Compile Include="Push\Simplifier\Simplifier.cs" />
     <Compile Include="Push\Stack\IStack.cs" />
     <Compile Include="Push\Stack\PushStack.cs" />
-    <Compile Include="Push\Stack\StackType.cs" />
+    <Compile Include="Push\Stack\StackTypes.cs" />
     <Compile Include="Push\Views\ExpressionSelectionView.cs">
       <SubType>UserControl</SubType>
@@ -200,7 +211,5 @@
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Push\Solution\" />
-  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj.user
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj.user	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/HeuristicLab.Problems.ProgramSynthesis.csproj.user	(revision 14777)
@@ -2,5 +2,5 @@
 <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectView>ShowAllFiles</ProjectView>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Attributes/PushExpressionAttriubte.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Attributes/PushExpressionAttriubte.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Attributes/PushExpressionAttriubte.cs	(revision 14777)
@@ -6,9 +6,11 @@
   [AttributeUsage(AttributeTargets.Class)]
   public class PushExpressionAttribute : Attribute {
-    public readonly StackType StackType;
+    public readonly StackTypes StackTypes;
+    public readonly StackTypes AdditionalStackDependencies;
     public readonly string ExpressionName;
 
-    public PushExpressionAttribute(StackType stackType, string expressionName) {
-      this.StackType = stackType;
+    public PushExpressionAttribute(StackTypes stackTypes, string expressionName, StackTypes additionalStackDependencies = default(StackTypes)) {
+      this.StackTypes = stackTypes;
+      this.AdditionalStackDependencies = additionalStackDependencies;
       this.ExpressionName = expressionName;
     }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IEnabledExpressionsConfiguration.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IEnabledExpressionsConfiguration.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IEnabledExpressionsConfiguration.cs	(revision 14777)
@@ -22,8 +22,8 @@
     IList<string> EnabledExpressions { get; }
 
-    void EnableStack(StackType type);
-    void DisableStack(StackType type);
-    void EnableExpressionOfStack(StackType type);
-    void DisableExpressionOfStack(StackType type);
+    void EnableStack(StackTypes types);
+    void DisableStack(StackTypes types);
+    void EnableExpressionOfStack(StackTypes types);
+    void DisableExpressionOfStack(StackTypes types);
     void EnableExpression(string name);
     void DisableExpression(string name);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IReadonlyPushConfiguration.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IReadonlyPushConfiguration.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/IReadonlyPushConfiguration.cs	(revision 14777)
@@ -2,8 +2,12 @@
   using System.Collections.Generic;
 
-  public interface IReadonlyPushConfiguration {
+  using HeuristicLab.Common;
+
+  public interface IReadOnlyPushConfiguration : IDeepCloneable {
     bool IsBooleanStackEnabled { get; }
     bool IsIntegerStackEnabled { get; }
     bool IsFloatStackEnabled { get; }
+    bool IsCharStackEnabled { get; }
+    bool IsStringStackEnabled { get; }
     bool IsCodeStackEnabled { get; }
     bool IsNameStackEnabled { get; }
@@ -11,4 +15,5 @@
     int EvalPushLimit { get; }
     int MaxDepth { get; }
+    int MaxStringLength { get; }
     int MaxPointsInProgram { get; }
     int MaxPointsInRandomExpression { get; }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushConfiguration.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushConfiguration.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushConfiguration.cs	(revision 14777)
@@ -12,11 +12,13 @@
 
   [StorableClass]
-  public class PushConfiguration : NamedItem, IReadonlyPushConfiguration, IEnabledExpressionsConfiguration {
-    private static readonly string itemName = "PushGP Configuration";
+  public class PushConfiguration : NamedItem, IReadOnlyPushConfiguration, IEnabledExpressionsConfiguration {
+    private static readonly string itemName = "Push Configuration";
 
     public PushConfiguration() {
-      this.EvalPushLimit = 4096;
+      this.EvalPushLimit = 1024;
       this.MaxPointsInProgram = 128;
       this.MaxPointsInRandomExpression = 64;
+      this.MaxDepth = 4;
+      this.MaxStringLength = 64;
 
       this.TopLevelPushCode = true;
@@ -30,9 +32,11 @@
       this.ErcProbability = 0.2;
 
-      this.EnabledExpressions = ExpressionTable.ExpressionNames.ToList();
+      this.enabledExpressions = ExpressionTable.ExpressionNames.ToList();
     }
 
     [StorableConstructor]
-    public PushConfiguration(bool deserializing) : base(deserializing) { }
+    public PushConfiguration(bool deserializing)
+      : base(deserializing) {
+    }
 
     public PushConfiguration(PushConfiguration origin, Cloner cloner) : base(origin, cloner) {
@@ -42,4 +46,6 @@
       this.MaxPointsInProgram = origin.MaxPointsInProgram;
       this.MaxPointsInRandomExpression = origin.MaxPointsInRandomExpression;
+      this.MaxDepth = origin.MaxDepth;
+      this.MaxStringLength = origin.MaxStringLength;
 
       this.TopLevelPushCode = origin.TopLevelPushCode;
@@ -63,8 +69,22 @@
     public event EventHandler<EnabledExpressionsChangedEventArgs> EnabledExpressionsChanged;
 
-    [Storable]
-    public IList<string> EnabledExpressions { get; private set; }
-
-    IReadOnlyList<string> IReadonlyPushConfiguration.EnabledExpressions { get { return this.EnabledExpressions as IReadOnlyList<string>; } }
+
+    private readonly List<string> enabledExpressions = new List<string>();
+
+    [Storable]
+    public IList<string> EnabledExpressions
+    {
+      get
+      {
+        return enabledExpressions;
+      }
+      set
+      {
+        enabledExpressions.Clear();
+        enabledExpressions.AddRange(value);
+      }
+    }
+
+    IReadOnlyList<string> IReadOnlyPushConfiguration.EnabledExpressions { get { return this.EnabledExpressions as IReadOnlyList<string>; } }
 
     [Storable]
@@ -84,6 +104,6 @@
         this.isBooleanStackEnabled = value;
 
-        if (this.isBooleanStackEnabled) EnableExpressionOfStack(StackType.Boolean);
-        else DisableExpressionOfStack(StackType.Boolean);
+        if (this.isBooleanStackEnabled) EnableExpressionOfStack(StackTypes.Boolean);
+        else DisableExpressionOfStack(StackTypes.Boolean);
       }
     }
@@ -105,6 +125,6 @@
         this.isIntegerStackEnabled = value;
 
-        if (this.isIntegerStackEnabled) EnableExpressionOfStack(StackType.Integer);
-        else DisableExpressionOfStack(StackType.Integer);
+        if (this.isIntegerStackEnabled) EnableExpressionOfStack(StackTypes.Integer);
+        else DisableExpressionOfStack(StackTypes.Integer);
       }
     }
@@ -126,6 +146,6 @@
         this.isFloatStackEnabled = value;
 
-        if (this.isFloatStackEnabled) EnableExpressionOfStack(StackType.Float);
-        else DisableExpressionOfStack(StackType.Float);
+        if (this.isFloatStackEnabled) EnableExpressionOfStack(StackTypes.Float);
+        else DisableExpressionOfStack(StackTypes.Float);
       }
     }
@@ -147,6 +167,6 @@
         this.isCodeStackEnabled = value;
 
-        if (this.isCodeStackEnabled) EnableExpressionOfStack(StackType.Code);
-        else DisableExpressionOfStack(StackType.Code);
+        if (this.isCodeStackEnabled) EnableExpressionOfStack(StackTypes.Code);
+        else DisableExpressionOfStack(StackTypes.Code);
       }
     }
@@ -168,6 +188,48 @@
         this.isExecStackEnabled = value;
 
-        if (this.isExecStackEnabled) EnableExpressionOfStack(StackType.Exec);
-        else DisableExpressionOfStack(StackType.Exec);
+        if (this.isExecStackEnabled) EnableExpressionOfStack(StackTypes.Exec);
+        else DisableExpressionOfStack(StackTypes.Exec);
+      }
+    }
+
+    [Storable]
+    private bool isCharStackEnabled = true;
+
+    public bool IsCharStackEnabled
+    {
+      get
+      {
+        return this.isCharStackEnabled;
+      }
+
+      set
+      {
+        if (this.isCharStackEnabled == value) return;
+
+        this.isCharStackEnabled = value;
+
+        if (this.isCharStackEnabled) EnableExpressionOfStack(StackTypes.Char);
+        else DisableExpressionOfStack(StackTypes.Char);
+      }
+    }
+
+    [Storable]
+    private bool isStringStackEnabled = true;
+
+    public bool IsStringStackEnabled
+    {
+      get
+      {
+        return this.isStringStackEnabled;
+      }
+
+      set
+      {
+        if (this.isStringStackEnabled == value) return;
+
+        this.isStringStackEnabled = value;
+
+        if (this.isStringStackEnabled) EnableExpressionOfStack(StackTypes.String);
+        else DisableExpressionOfStack(StackTypes.String);
       }
     }
@@ -189,6 +251,6 @@
         this.isNameStackEnabled = value;
 
-        if (this.isNameStackEnabled) EnableExpressionOfStack(StackType.Name);
-        else DisableExpressionOfStack(StackType.Name);
+        if (this.isNameStackEnabled) EnableExpressionOfStack(StackTypes.Name);
+        else DisableExpressionOfStack(StackTypes.Name);
       }
     }
@@ -244,4 +306,7 @@
     public bool TopLevelPopCode { get; set; }
 
+    [Storable]
+    public int MaxStringLength { get; set; }
+
     /// <summary>
     ///     The minimum INTEGER that will be produced as an ephemeral random INTEGER constant or from a call to INTEGER.RAND.
@@ -276,12 +341,12 @@
     public double NewErcNameProbability { get; set; }
 
-    public void EnableExpressionOfStack(StackType type) {
-      foreach (var name in ExpressionTable.StackTypeToNamesTable[type]) {
+    public void EnableExpressionOfStack(StackTypes types) {
+      foreach (var name in ExpressionTable.StackTypeToNamesTable[types]) {
         EnableExpression(name);
       }
     }
 
-    public void DisableExpressionOfStack(StackType type) {
-      foreach (var name in ExpressionTable.StackTypeToNamesTable[type]) {
+    public void DisableExpressionOfStack(StackTypes types) {
+      foreach (var name in ExpressionTable.StackTypeToNamesTable[types]) {
         DisableExpression(name);
       }
@@ -322,33 +387,39 @@
     }
 
-    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:
+    public void EnableStack(StackTypes types) {
+      SetStack(types, true);
+    }
+
+    public void DisableStack(StackTypes types) {
+      SetStack(types, false);
+    }
+
+    public void SetStack(StackTypes types, bool value) {
+      switch (types) {
+        case StackTypes.Boolean:
           IsBooleanStackEnabled = value;
           break;
-        case StackType.Integer:
+        case StackTypes.Integer:
           IsIntegerStackEnabled = value;
           break;
-        case StackType.Float:
+        case StackTypes.Float:
           IsFloatStackEnabled = value;
           break;
-        case StackType.Name:
+        case StackTypes.Name:
           IsNameStackEnabled = value;
           break;
-        case StackType.Code:
+        case StackTypes.Code:
           IsCodeStackEnabled = value;
           break;
-        case StackType.Exec:
+        case StackTypes.Exec:
           this.IsExecStackEnabled = value;
           break;
-        default: throw new InvalidOperationException("Stacktype unkown");
+        case StackTypes.Char:
+          this.IsCharStackEnabled = value;
+          break;
+        case StackTypes.String:
+          this.IsStringStackEnabled = value;
+          break;
+        default: throw new InvalidOperationException("Stacktype unknown");
       }
     }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/IPushProgramCreator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/IPushProgramCreator.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/IPushProgramCreator.cs	(revision 14777)
@@ -13,5 +13,5 @@
   public interface IPushProgramCreator : ISolutionCreator
   {
-    PushProgram CreateProgram(IRandom random, IReadonlyPushConfiguration config);
+    PushProgram CreateProgram(IRandom random, IReadOnlyPushConfiguration config);
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/PointsBasedPushProgramCreator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/PointsBasedPushProgramCreator.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Creator/PointsBasedPushProgramCreator.cs	(revision 14777)
@@ -23,5 +23,5 @@
 //    }
 
-//    public PushProgram CreateProgram(IRandom random, IReadonlyPushConfiguration config) {
+//    public PushProgram CreateProgram(IRandom random, IReadOnlyPushConfiguration config) {
 //      return CodeGenerator.RandomProgram(10, random, config);
 //    }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/IPooledObject.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/IPooledObject.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/IPooledObject.cs	(revision 14777)
@@ -0,0 +1,5 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool {
+  public interface IPooledObject {
+    void Reset();
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ManagedPoolProvider.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ManagedPoolProvider.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ManagedPoolProvider.cs	(revision 14777)
@@ -8,12 +8,15 @@
   using System.Runtime.Serialization.Formatters.Binary;
 
-  public interface IManagedPool<T> : IDisposable where T : class {
-    T Get();
+  public interface IManagedPool<T> : IDisposable where T : class, IPooledObject {
+    T Get(bool reset = true);
   }
 
-  public class ManagedPoolProvider<T> where T : class {
+  public class ManagedPoolProvider<T> where T : class, IPooledObject {
     private readonly ConcurrentStack<T[]> partitions = new ConcurrentStack<T[]>();
     private readonly ObjectPool<IManagedPool<T>> managedPools;
-    private T[] DummyPartition;
+    private readonly BinaryFormatter binaryFormatter = new BinaryFormatter();
+    private byte[] dummyPartition;
+
+    private readonly Func<T> factory;
 
     public readonly int PartitionSize;
@@ -21,20 +24,25 @@
     public const int DefaultMaxInstanceCount = 65536;
 
-    public ManagedPoolProvider(int partitionSize, int? maxPartitionCount = null) {
+    public ManagedPoolProvider(int partitionSize, Func<T> factory, int? maxPartitionCount = null) {
       PartitionSize = partitionSize;
       MaxParitionCount = maxPartitionCount ?? DefaultMaxInstanceCount / PartitionSize;
+      this.factory = factory;
 
-      managedPools = new ObjectPool<IManagedPool<T>>(() => new ManagedPool<T>(this));
+      managedPools = new ObjectPool<IManagedPool<T>>(() => new ManagedPool<T>(this), MaxParitionCount);
     }
+    public int InstanceCount { get { return partitions.Count * PartitionSize; } }
 
-    public void InitDummyPartition(Func<T> factory) {
-      DummyPartition = new T[PartitionSize];
+    private void InitDummyPartition(Func<T> factory) {
+      var temp = new T[PartitionSize];
 
       for (var i = 0; i < PartitionSize; i++) {
-        DummyPartition[i] = factory();
+        temp[i] = factory();
+      }
+
+      using (var memoryStream = new MemoryStream()) {
+        binaryFormatter.Serialize(memoryStream, temp);
+        dummyPartition = memoryStream.ToArray();
       }
     }
-
-    public int InstanceCount { get { return partitions.Count * PartitionSize; } }
 
     public void ReleasePartitions(params T[][] partition) {
@@ -45,11 +53,12 @@
     private T[] GetPartition() {
       T[] partition;
-      return partitions.TryPop(out partition) ? partition : DeepArrayCopy(DummyPartition);
+      return partitions.TryPop(out partition) ? partition : CloneDummyPartition();
     }
 
-    private readonly BinaryFormatter binaryFormatter = new BinaryFormatter();
-    private T[] DeepArrayCopy(object objectToCopy) {
-      using (var memoryStream = new MemoryStream()) {
-        binaryFormatter.Serialize(memoryStream, objectToCopy);
+    private T[] CloneDummyPartition() {
+      if (dummyPartition == null)
+        InitDummyPartition(factory);
+
+      using (var memoryStream = new MemoryStream(dummyPartition)) {
         memoryStream.Seek(0, SeekOrigin.Begin);
 
@@ -62,5 +71,5 @@
     }
 
-    private class ManagedPool<T> : IManagedPool<T> where T : class {
+    private class ManagedPool<T> : IManagedPool<T> where T : class, IPooledObject {
       private readonly ManagedPoolProvider<T> provider;
       private readonly IList<T[]> partitions = new List<T[]>();
@@ -73,5 +82,5 @@
       }
 
-      public T Get() {
+      public T Get(bool reset = true) {
         if (entryIndex == provider.PartitionSize) {
           currentPartition = provider.GetPartition();
@@ -80,5 +89,9 @@
         }
 
-        return currentPartition[entryIndex++];
+        var entry = currentPartition[entryIndex++];
+
+        if (reset) entry.Reset();
+
+        return entry;
       }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ObjectPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ObjectPool.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/ObjectPool.cs	(revision 14777)
@@ -25,5 +25,5 @@
   ///    If there is no intent for reusing the object, do not use pool - just use "new".
   /// </summary>
-  internal sealed class ObjectPool<T> where T : class {
+  public sealed class ObjectPool<T> where T : class {
     private struct Element {
       internal T Value;
@@ -39,8 +39,8 @@
 
 
-    internal ObjectPool(Func<T> factory)
+    public ObjectPool(Func<T> factory)
         : this(factory, Environment.ProcessorCount * 2) { }
 
-    internal ObjectPool(Func<T> factory, int size) {
+    public ObjectPool(Func<T> factory, int size) {
       _factory = factory;
       _items = new Element[size];
@@ -60,5 +60,5 @@
     /// reducing how far we will typically search.
     /// </remarks>
-    internal T Allocate() {
+    public T Allocate() {
       var items = _items;
       T inst;
@@ -90,5 +90,5 @@
     /// reducing how far we will typically search in Allocate.
     /// </remarks>
-    internal void Free(T obj) {
+    public void Free(T obj) {
       var items = _items;
       for (int i = 0; i < items.Length; i++) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/PooledList.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/PooledList.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Pool/PooledList.cs	(revision 14777)
@@ -0,0 +1,12 @@
+﻿using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool {
+  using System;
+
+  [Serializable]
+  public class PooledList<T> : List<T>, IPooledObject {
+    public void Reset() {
+      this.Clear();
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/Tree.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/Tree.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/Tree.cs	(revision 14777)
@@ -0,0 +1,4 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Data.Tree {
+  public class Tree<T> : TreeNode<T> {
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeExtensions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeExtensions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeExtensions.cs	(revision 14777)
@@ -0,0 +1,71 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Data.Tree {
+  using System.Linq;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+
+  public static class TreeExtensions {
+    public static Tree<T> ToTree<T>(
+      this IEnumerable<T> items,
+      Predicate<T> isChild,
+      Func<T, IReadOnlyList<T>> childrenResolver) {
+      var tree = new Tree<T>();
+
+      foreach (var item in items) {
+        if (isChild(item)) {
+          var subNode = childrenResolver(item).ToTree(isChild, childrenResolver);
+          subNode.Value = item;
+          tree.AddNode(subNode);
+        } else {
+          tree.Add(item);
+        }
+      }
+
+      return tree;
+    }
+
+    public static IEnumerable<TreeNode<T>> DepthFirst<T>(this TreeNode<T> node) {
+      foreach (var child in node.Children) {
+        if (child.Children.Count > 0) {
+          foreach (var subChild in child.DepthFirst()) {
+            yield return subChild;
+          }
+        } else yield return child;
+      }
+    }
+
+    public static IEnumerable<T> DepthFirst<T>(this TreeNode<T> node, Func<IEnumerable<T>, T> resolveParent) {
+      foreach (var child in node.Children) {
+        if (child.Children.Count > 0) {
+          var subExpressions = child.DepthFirst(resolveParent);
+          yield return resolveParent(subExpressions);
+        } else yield return child.Value;
+      }
+    }
+
+    public static PushProgram ToPushProgram(this TreeNode<Expression> tree, Func<Expression, bool> condition = null) {
+      var expressions = tree.DepthFirst(e => ResolveProgram(e, condition));
+
+      return ResolveProgram(expressions, condition);
+    }
+
+    public static Tree<Expression> ToTree(this PushProgram program) {
+      var tree = program.Expressions.ToTree(e => e.IsProgram, e => ((PushProgram)e).Expressions);
+      tree.Value = program;
+
+      return tree;
+    }
+
+    private static PushProgram ResolveProgram(IEnumerable<Expression> expressions, Func<Expression, bool> condition = null) {
+
+      if (condition != null) {
+        expressions = expressions.Where(condition);
+      }
+
+      return new PushProgram(expressions.ToArray());
+    }
+  }
+
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeNode.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeNode.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Data/Tree/TreeNode.cs	(revision 14777)
@@ -0,0 +1,28 @@
+﻿using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Data.Tree {
+  public class TreeNode<T> {
+    public T Value { get; set; }
+    public IList<TreeNode<T>> Children { get; private set; }
+
+    public TreeNode() {
+      Children = new List<TreeNode<T>>();
+    }
+
+    public TreeNode(T value) : this() {
+      Value = value;
+    }
+
+    public void Add(T value) {
+      this.Children.Add(new TreeNode<T>(value));
+    }
+
+    public void AddNode(TreeNode<T> node) {
+      this.Children.Add(node);
+    }
+
+    public void ReplaceNode(int index, TreeNode<T> node) {
+      Children[index] = node;
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/BooleanExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/BooleanExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/BooleanExpressions.cs	(revision 14777)
@@ -1,11 +1,13 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
+  using System;
+
+  using Attributes;
+  using Interpreter;
+  using Stack;
 
   /// <summary>
   ///     Pushes the logical AND of the top two BOOLEANs.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.AND")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.AND")]
   public class BooleanAndExpression : PushResultExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -17,5 +19,5 @@
   ///     Pushes the logical OR of the top two BOOLEANs.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.OR")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.OR")]
   public class BooleanOrExpression : PushResultExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -27,5 +29,5 @@
   ///     Pushes the logical NOT of the top BOOLEAN.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.NOT")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.NOT")]
   public class BooleanNotExpression : PushResultExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -37,10 +39,10 @@
   ///     Pushes FALSE if the top FLOAT is 0.0, or TRUE otherwise.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.FROMFLOAT")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.FROMFLOAT", StackTypes.Float)]
   public class BooleanFromFloatExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
       if (interpreter.FloatStack.Count == 0) return false;
 
-      var value = interpreter.FloatStack.Pop() != 0.0;
+      var value = Math.Abs(interpreter.FloatStack.Pop()) > 0.0000001;
 
       interpreter.BooleanStack.Push(value);
@@ -52,5 +54,5 @@
   ///     Pushes FALSE if the top INTEGER is 0, or TRUE otherwise.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.FROMINTEGER")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.FROMINTEGER", StackTypes.Integer)]
   public class BooleanFromIntegerExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -63,3 +65,34 @@
     }
   }
+
+  /// <summary>
+  ///     Pushes the logical AND of the top two BOOLEANs, whereby the first value is inverted first.
+  /// </summary>
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.INVERT_FIRST_THEN_AND")]
+  public class BooleanInvertFirstThenAnd : PushResultExpression<bool> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.BooleanStack, 2, values => !values[0] && values[1]);
+    }
+  }
+
+  /// <summary>
+  ///     Pushes the logical AND of the top two BOOLEANs, whereby the second value is inverted first.
+  /// </summary>
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.INVERT_SECOND_THEN_AND")]
+  public class BooleanInvertSecondThenAnd : PushResultExpression<bool> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.BooleanStack, 2, values => values[0] && !values[1]);
+    }
+  }
+
+
+  /// <summary>
+  ///     Pushes the logical AND of the top two BOOLEANs, whereby the second value is inverted first.
+  /// </summary>
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.XOR")]
+  public class BooleanXorExpression : PushResultExpression<bool> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.BooleanStack, 2, values => values[0] ^ values[1]);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CharExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CharExpressions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CharExpressions.cs	(revision 14777)
@@ -0,0 +1,78 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
+
+  [PushExpression(StackTypes.Char, "CHAR.ISWHITESPACE", StackTypes.Boolean)]
+  public class CharIsWhitespaceExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.CharStack.IsEmpty) return false;
+
+      var c = interpreter.CharStack.Pop();
+      interpreter.BooleanStack.Push(char.IsWhiteSpace(c));
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.ISLETTER", StackTypes.Boolean)]
+  public class CharIsLetterExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.CharStack.IsEmpty) return false;
+
+      var c = interpreter.CharStack.Pop();
+      interpreter.BooleanStack.Push(char.IsLetter(c));
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.ISDIGIT", StackTypes.Boolean)]
+  public class CharIsDigitExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.CharStack.IsEmpty) return false;
+
+      var c = interpreter.CharStack.Pop();
+      interpreter.BooleanStack.Push(char.IsDigit(c));
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.FROMINTEGER", StackTypes.Integer)]
+  public class CharFromIntegerExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.IntegerStack.IsEmpty) return false;
+
+      var value = (int)Math.Abs(interpreter.IntegerStack.Pop() % 128);
+      var c = Convert.ToChar(value);
+
+      interpreter.CharStack.Push(c);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.FROMFLOAT", StackTypes.Float)]
+  public class CharFromFloatExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.FloatStack.IsEmpty) return false;
+
+      var value = (int)Math.Abs(interpreter.FloatStack.Pop() % 128);
+      var c = Convert.ToChar(value);
+
+      interpreter.CharStack.Push(c);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.ALLFROMSTRING", StackTypes.String)]
+  public class CharAllFromStringExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty) return false;
+
+      var chars = interpreter.StringStack.Pop().ToCharArray();
+      interpreter.CharStack.Push(chars);
+      return true;
+    }
+  }
+
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs	(revision 14777)
@@ -1,5 +1,5 @@
 ﻿/// <summary>
-/// For explicit code manipulation and execution. May also be used as a general list data type.
-/// This type must always be present, as the top level interpreter will push any code to be executed on the
+/// For explicit code manipulation and execution. May also be used as a general list data types.
+/// This types must always be present, as the top level interpreter will push any code to be executed on the
 /// CODE stack prior to execution. However, one may turn off all CODE instructions if code manipulation is not needed.
 /// </summary>
@@ -20,5 +20,5 @@
   ///     manipulates the stack then this final pop may end up popping something else.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DO")]
+  [PushExpression(StackTypes.Code, "CODE.DO", StackTypes.Exec)]
   public class CodeDoExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -36,5 +36,5 @@
   ///     Like CODE.DO but pops the stack before, rather than after, the recursive execution
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DO*")]
+  [PushExpression(StackTypes.Code, "CODE.DO*", StackTypes.Exec)]
   public class CodeDoXExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -52,5 +52,5 @@
   ///     Does nothing.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.NOOP")]
+  [PushExpression(StackTypes.Code, "CODE.NOOP")]
   public class CodeNoopExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -63,5 +63,5 @@
   ///     This can be implemented by moving the top item on the EXEC stack onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.QUOTE")]
+  [PushExpression(StackTypes.Code, "CODE.QUOTE", StackTypes.Exec)]
   public class CodeQuoteExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -81,5 +81,5 @@
   ///     (and the BOOLEAN value upon which the decision was made) are popped.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.IF")]
+  [PushExpression(StackTypes.Code, "CODE.IF", StackTypes.Exec | StackTypes.Boolean)]
   public class CodeIfExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -100,46 +100,54 @@
   ///     literal (that is, something not surrounded by parentheses) then it is surrounded by parentheses first.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.APPEND")]
+  [PushExpression(StackTypes.Code, "CODE.APPEND")]
   public class CodeAppendExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
       if (interpreter.CodeStack.Count < 2) return false;
 
-      var first = interpreter.CodeStack.Pop();
-      var second = interpreter.CodeStack.Top;
-
-      var isFirstList = first.IsProgram;
-      var isSecondList = second.IsProgram;
+      var first = interpreter.CodeStack.Top;
+      var second = interpreter.CodeStack.ReverseElementAt(1);
+      PushProgram firstProgram = null;
+      PushProgram secondProgram = null;
+
+      if (first.IsProgram) {
+        firstProgram = (PushProgram)first;
+
+        if (firstProgram.Depth > interpreter.Configuration.MaxDepth) return false;
+
+        if (second.IsProgram) {
+          secondProgram = (PushProgram)second;
+
+          if (secondProgram.Depth > interpreter.Configuration.MaxDepth ||
+              firstProgram.Count + secondProgram.Count > interpreter.Configuration.MaxPointsInProgram)
+            return false;
+        } else if (firstProgram.Count + 1 > interpreter.Configuration.MaxPointsInProgram) return false;
+      } else if (second.IsProgram) {
+        secondProgram = (PushProgram)second;
+
+        if (secondProgram.Depth > interpreter.Configuration.MaxDepth
+            || secondProgram.Count + 1 > interpreter.Configuration.MaxPointsInProgram) return false;
+      } else if (interpreter.Configuration.MaxPointsInProgram <= 2) {
+        return false;
+      }
+
+      interpreter.CodeStack.Pop();
+
+      //var first = interpreter.CodeStack.Pop();
+      //var second = interpreter.CodeStack.Top;
 
       PushProgram result;
 
-      if (isFirstList) {
-        var program1 = first as PushProgram;
-
-        if (isSecondList) {
-          var program2 = second as PushProgram;
-          var size = program2.Expressions.Count + program1.Expressions.Count;
-
-          // if size > maxPointsInProgram this expressions results in a NOOP
-          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
-
-          result = PushProgram.Merge(interpreter.PushProgramPool, program2, program1);
-        } else {
-          var size = program1.Expressions.Count + 1;
-
-          // if size > maxPointsInProgram this expressions results in a NOOP
-          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
-
-          result = PushProgram.Merge(interpreter.PushProgramPool, second, program1);
-        }
-      } else if (isSecondList) {
-        var program2 = second as PushProgram;
-        var size = program2.Expressions.Count + 1;
-
-        // if size > maxPointsInProgram this expressions results in a NOOP
-        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
-
-        result = PushProgram.Merge(interpreter.PushProgramPool, first, program2);
+      if (firstProgram != null) {
+        result = secondProgram != null
+          ? PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, secondProgram, firstProgram)
+          : PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, second, firstProgram);
+      } else if (secondProgram != null) {
+        result = PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, first, secondProgram);
       } else {
-        result = PushProgram.Create(interpreter.PushProgramPool, second, first);
+        var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
+        expressions.Add(second);
+        expressions.Add(first);
+
+        result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
       }
 
@@ -154,5 +162,5 @@
   ///     and FALSE otherwise (that is, if it is something surrounded by parentheses).
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.ATOM")]
+  [PushExpression(StackTypes.Code, "CODE.ATOM", StackTypes.Boolean)]
   public class CodeAtomExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -173,9 +181,9 @@
   ///     The name derives from the similar Lisp function; a more generic name would be "FIRST".
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CAR")]
+  [PushExpression(StackTypes.Code, "CODE.CAR")]
   public class CodeCarExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
-      if ((interpreter.CodeStack.Count == 0) ||
-          (interpreter.CodeStack.Top.GetType() != typeof(PushProgram))) return false;
+      if (interpreter.CodeStack.Count == 0 ||
+          interpreter.CodeStack.Top.IsProgram) return false;
 
       var expand = interpreter.CodeStack.Top as PushProgram;
@@ -195,5 +203,5 @@
   ///     the similar Lisp function; a more generic name would be "REST".
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CDR")]
+  [PushExpression(StackTypes.Code, "CODE.CDR")]
   public class CodeCdrExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -208,5 +216,8 @@
         if (program.IsEmpty) return false;
 
-        result = program.Copy(interpreter.PushProgramPool, 0, program.Expressions.Count - 1);
+        var expressions = program.CopyExpressions(interpreter.PoolContainer.ExpressionListPool);
+        expressions.RemoveAt(expressions.Count - 1);
+
+        result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions as IReadOnlyList<Expression>);
       } else {
         result = PushProgram.Empty;
@@ -223,29 +234,27 @@
   ///     second piece of code is "X" then this pushes "( X A B )" (after popping the argument).
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CONS")]
+  [PushExpression(StackTypes.Code, "CODE.CONS")]
   public class CodeConsExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
-      if (interpreter.CodeStack.Count < 2)
+      if (interpreter.CodeStack.Count < 2 ||
+         (interpreter.CodeStack.Top.IsProgram &&
+         ((PushProgram)interpreter.CodeStack.Top).Expressions.Count + 1 > interpreter.Configuration.MaxPointsInProgram))
         return false;
 
       PushProgram result;
 
-      if (interpreter.CodeStack.Top.IsProgram) {
-        var first = (PushProgram)interpreter.CodeStack.Pop();
-        var size = first.Expressions.Count + 1;
-
-        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
-
-        var expressions = new Expression[size];
-
-        first.CopyExpressionsTo(expressions);
-        expressions[first.Expressions.Count] = interpreter.CodeStack.Top;
-
-        result = PushProgram.Create(interpreter.PushProgramPool, expressions);
+      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
+      var first = interpreter.CodeStack.Pop();
+
+      if (first.IsProgram) {
+        expressions.AddRange(((PushProgram)first).Expressions);
       } else {
-        result = PushProgram.Create(interpreter.PushProgramPool, interpreter.CodeStack.Top);
-      }
-
+        expressions.Add(first);
+      }
+
+      expressions.Add(interpreter.CodeStack.Top);
+      result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
       interpreter.CodeStack.SetTop(result);
+
       return true;
     }
@@ -260,5 +269,5 @@
   ///     container.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CONTAINER")]
+  [PushExpression(StackTypes.Code, "CODE.CONTAINER")]
   public class CodeContainerExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -299,5 +308,5 @@
   ///     item anywhere (e.g. in a sub-list).
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CONTAINS")]
+  [PushExpression(StackTypes.Code, "CODE.CONTAINS", StackTypes.Boolean)]
   public class CodeContainsExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -321,5 +330,5 @@
   ///     may then be executed with a call to CODE.DO or a similar instruction).
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DEFINITION")]
+  [PushExpression(StackTypes.Code, "CODE.DEFINITION", StackTypes.Name)]
   public class CodeDefinitionExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -340,12 +349,13 @@
   ///     if the top two items are equivalent, and will be higher the 'more different' the items are from one another. The calculation
   ///     is as follows:
-  ///     <list type="bullet">
+  ///     <list types="bullet">
   ///         <item>
   ///             <description>
   ///                 Construct a list of all of the unique items in both of the lists(where uniqueness is determined by equalp).
   ///                 Sub-lists and atoms all count as items.
+  ///             </description>
   ///         </item>
   ///         <item>
-  ///             <description>Initialize the result to zero.
+  ///             <description>Initialize the result to zero.</description>
   ///         </item>
   ///         <item>
@@ -353,11 +363,12 @@
   ///                 For each unique item increment the result by the difference between the number of occurrences of the
   ///                 item in the two pieces of code.
+  ///             </description>
   ///         </item>
   ///         <item>
-  ///             <description>Push the result.
+  ///             <description>Push the result.</description>
   ///         </item>
   ///     </list>
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DISCREPANCY")]
+  [PushExpression(StackTypes.Code, "CODE.DISCREPANCY", StackTypes.Integer)]
   public class CodeDiscrepancyExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -417,5 +428,5 @@
   ///     absolute value is taken in case it is negative) to ensure that it is within the meaningful range.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.EXTRACT")]
+  [PushExpression(StackTypes.Code, "CODE.EXTRACT", StackTypes.Integer)]
   public class CodeExtractExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -438,5 +449,5 @@
   ///     Pops the BOOLEAN stack and pushes the popped item (TRUE or FALSE) onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.FROMBOOLEAN")]
+  [PushExpression(StackTypes.Code, "CODE.FROMBOOLEAN", StackTypes.Boolean)]
   public class CodeFromBooleanExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -455,5 +466,5 @@
   ///     Pops the FLOAT stack and pushes the popped item onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.FROMFLOAT")]
+  [PushExpression(StackTypes.Code, "CODE.FROMFLOAT", StackTypes.Float)]
   public class CodeFromFloatExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -472,5 +483,5 @@
   ///     Pops the INTEGER stack and pushes the popped integer onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.FROMINTEGER")]
+  [PushExpression(StackTypes.Code, "CODE.FROMINTEGER", StackTypes.Integer)]
   public class CodeFromIntegerExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -489,5 +500,5 @@
   ///     Pops the NAME stack and pushes the popped item onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.FROMNAME")]
+  [PushExpression(StackTypes.Code, "CODE.FROMNAME", StackTypes.Name)]
   public class CodeFromNameExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -507,5 +518,5 @@
   ///     by the top item of the INTEGER stack (and replacing whatever was there formerly).
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.CODEINSERT")]
+  [PushExpression(StackTypes.Code, "CODE.CODEINSERT", StackTypes.Integer)]
   public class CodeInsertExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -519,17 +530,18 @@
       var index = (int)interpreter.IntegerStack.Pop();
 
-      Expression[] newExpressions;
+      IList<Expression> newExpressions;
       if (!target.IsEmpty) {
         index = target.Expressions.Count - 1 - Math.Abs(index % target.Expressions.Count);
-
-        newExpressions = target.CopyExpressions();
+        newExpressions = target.CopyExpressions(interpreter.PoolContainer.ExpressionListPool);
+
         newExpressions[index] = source.IsProgram
-            ? ((PushProgram)source).Copy(interpreter.PushProgramPool)
+            ? ((PushProgram)source).Copy(interpreter.PoolContainer.PushProgramPool)
             : source;
       } else {
-        newExpressions = new[] { source };
-      }
-
-      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
+        newExpressions = interpreter.PoolContainer.ExpressionListPool.Get();
+        newExpressions.Add(source);
+      }
+
+      var result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, newExpressions as IReadOnlyList<Expression>);
       interpreter.CodeStack.SetTop(result);
 
@@ -544,5 +556,5 @@
   ///     matter what they contain.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.LENGTH")]
+  [PushExpression(StackTypes.Code, "CODE.LENGTH", StackTypes.Integer)]
   public class CodeLengthExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -564,12 +576,20 @@
   ///     Pushes a list of the top two items of the CODE stack onto the CODE stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.LIST")]
+  [PushExpression(StackTypes.Code, "CODE.LIST")]
   public class CodeListExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
-      if (interpreter.CodeStack.Count < 2) return false;
+      if (interpreter.CodeStack.Count < 2 ||
+         (interpreter.CodeStack.Top.IsProgram && ((PushProgram)interpreter.CodeStack.Top).Depth == interpreter.Configuration.MaxDepth) ||
+         (interpreter.CodeStack.ReverseElementAt(1).IsProgram && ((PushProgram)interpreter.CodeStack.ReverseElementAt(1)).Depth == interpreter.Configuration.MaxDepth))
+        return false;
 
       var first = interpreter.CodeStack.Pop();
       var second = interpreter.CodeStack.Top;
-      var expandExpression = PushProgram.Create(interpreter.PushProgramPool, second, first);
+
+      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
+      expressions.Add(second);
+      expressions.Add(first);
+
+      var expandExpression = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
 
       interpreter.CodeStack.SetTop(expandExpression);
@@ -583,5 +603,5 @@
   ///     (which is coerced to a list if necessary). Pushes FALSE onto the BOOLEAN stack otherwise.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.MEMBER")]
+  [PushExpression(StackTypes.Code, "CODE.MEMBER", StackTypes.Boolean)]
   public class CodeMemberExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -605,5 +625,5 @@
   ///     modulo the length of the expression into which it is indexing.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.NTH")]
+  [PushExpression(StackTypes.Code, "CODE.NTH", StackTypes.Integer)]
   public class CodeNthExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -643,5 +663,5 @@
   ///     its first element.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.NTHCDR")]
+  [PushExpression(StackTypes.Code, "CODE.NTHCDR", StackTypes.Integer)]
   public class CodeNthCdrExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -676,10 +696,11 @@
   ///     Pushes TRUE onto the BOOLEAN stack if the top item of the CODE stack is an empty list, or FALSE otherwise.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.NULL")]
+  [PushExpression(StackTypes.Code, "CODE.NULL", StackTypes.Boolean)]
   public class CodeNullExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
       if (interpreter.CodeStack.Count == 0) return false;
 
-      var result = interpreter.CodeStack.Pop().Equals(PushProgram.Empty);
+      var top = interpreter.CodeStack.Pop();
+      var result = top.IsProgram && ((PushProgram)top).IsEmpty;
       interpreter.BooleanStack.Push(result);
 
@@ -692,5 +713,5 @@
   ///     (which is coerced to a list if necessary). Pushes -1 if no match is found.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.POSITION")]
+  [PushExpression(StackTypes.Code, "CODE.POSITION", StackTypes.Integer)]
   public class CodePositionExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -704,5 +725,5 @@
       if (first.IsProgram) {
         var program = (PushProgram)first;
-        position = program.Expressions.Count - 1 - program.IndexOf(second);
+        position = program.IndexOf(second);
       } else if (first.Equals(second)) {
         position = 0;
@@ -719,5 +740,5 @@
   ///     and pair of parentheses counts as a point.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.SIZE")]
+  [PushExpression(StackTypes.Code, "CODE.SIZE", StackTypes.Integer)]
   public class CodeSizeExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -741,9 +762,10 @@
   ///     cases with empty-list arguments. If any of these problematic possibilities occurs the stack is left unchanged.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.SUBST")]
+  [PushExpression(StackTypes.Code, "CODE.SUBST")]
   public class CodeSubstitutionExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
-      if ((interpreter.CodeStack.Count < 3) || (interpreter.CodeStack.Top.GetType() !=
-                                                typeof(PushProgram))) return false;
+      if ((interpreter.CodeStack.Count < 3) ||
+          (interpreter.CodeStack.Top.GetType() != typeof(PushProgram)))
+        return false;
 
       var expressions = interpreter.CodeStack.Pop(2);
@@ -752,13 +774,16 @@
       var first = expressions[1] as PushProgram;
       var firstExpressions = first.Expressions;
-      var newExpressions = new Expression[firstExpressions.Count];
-
-      for (var i = 0; i < firstExpressions.Count; i++)
-        newExpressions[i] = firstExpressions[i].Equals(third)
-            ? second
-            /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
-            : firstExpressions[i];
-
-      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
+      var newExpressions = interpreter.PoolContainer.ExpressionListPool.Get();
+
+      for (var i = 0; i < firstExpressions.Count; i++) {
+        var expression = firstExpressions[i].Equals(third)
+                           ? second
+                           /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
+                           : firstExpressions[i];
+
+        newExpressions.Add(expression);
+      }
+
+      var result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, newExpressions);
 
       interpreter.CodeStack.SetTop(result);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DefineExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DefineExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DefineExpressions.cs	(revision 14777)
@@ -31,5 +31,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.DEFINE")]
+  [PushExpression(StackTypes.Code, "CODE.DEFINE", StackTypes.Name)]
   public class CodeDefineExpression : DefineExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -48,5 +48,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.DEFINE")]
+  [PushExpression(StackTypes.Exec, "EXEC.DEFINE", StackTypes.Name)]
   public class ExecDefineExpression : DefineExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -66,5 +66,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.DEFINE")]
+  [PushExpression(StackTypes.Float, "FLOAT.DEFINE", StackTypes.Name)]
   public class FloatDefineExpression : DefineExpression<double> {
 
@@ -78,5 +78,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.DEFINE")]
+  [PushExpression(StackTypes.Integer, "INTEGER.DEFINE", StackTypes.Name)]
   public class IntegerDefineExpression : DefineExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -89,5 +89,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.DEFINE")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.DEFINE", StackTypes.Name)]
   public class BooleanDefineExpression : DefineExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -99,3 +99,25 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.DEFINE", StackTypes.Name)]
+  public class CharDefineExpression : DefineExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(
+        interpreter.CharStack,
+        interpreter.NameStack,
+        interpreter.CustomExpressions,
+        v => new CharPushExpression(v));
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.DEFINE", StackTypes.Name)]
+  public class StringDefineExpression : DefineExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(
+        interpreter.StringStack,
+        interpreter.NameStack,
+        interpreter.CustomExpressions,
+        v => new StringPushExpression(v));
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoCountExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoCountExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoCountExpressions.cs	(revision 14777)
@@ -1,7 +1,10 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
+
   using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
 
+  [Serializable]
   public abstract class DoCountExpression : LoopExpression {
 
@@ -15,5 +18,5 @@
 
     protected override LoopState InitState(IPushInterpreter interpreter, IStack<Expression> sourceStack) {
-      var state = new LoopState(
+      var state = LoopState.Create(interpreter.PoolContainer.LoopStatePool,
         body: sourceStack.Pop(),
         currentIndex: 1,
@@ -40,5 +43,6 @@
   ///     ( 0 '1 - IntegerArg>' CODE.QUOTE 'CodeArg' CODE.DO*RANGE )
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DO*COUNT")]
+  [Serializable]
+  [PushExpression(StackTypes.Code, "CODE.DO*COUNT", StackTypes.Integer)]
   public class CodeDoCountExpression : DoCountExpression {
 
@@ -51,6 +55,9 @@
     }
 
-    protected override LoopExpression Clone(LoopState state) {
-      return new CodeDoCountExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<CodeDoCountExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
@@ -70,5 +77,6 @@
   ///     ( 0 '1 - IntegerArg' EXEC.DO* RANGE'ExecArg' )
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.DO*COUNT")]
+  [Serializable]
+  [PushExpression(StackTypes.Exec, "EXEC.DO*COUNT", StackTypes.Integer)]
   public class ExecDoCountExpression : DoCountExpression {
     public ExecDoCountExpression() { }
@@ -79,6 +87,9 @@
     }
 
-    protected override LoopExpression Clone(LoopState state) {
-      return new ExecDoCountExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<ExecDoCountExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoRangeExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoRangeExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoRangeExpressions.cs	(revision 14777)
@@ -1,7 +1,10 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
+
   using Attributes;
   using Interpreter;
   using Stack;
 
+  [Serializable]
   public abstract class DoRangeExpression : LoopExpression {
     protected DoRangeExpression() { }
@@ -17,5 +20,5 @@
       var incrementor = destinationIndex < interpreter.IntegerStack.Top ? -1 : 1;
 
-      return new LoopState(
+      return LoopState.Create(interpreter.PoolContainer.LoopStatePool,
           body: sourceStack.Pop(),
           currentIndex: interpreter.IntegerStack.Top + incrementor,
@@ -47,5 +50,6 @@
   ///     that is less than the specified current index.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DO*RANGE")]
+  [Serializable]
+  [PushExpression(StackTypes.Code, "CODE.DO*RANGE", StackTypes.Integer)]
   public class CodeDoRangeExpression : DoRangeExpression {
     public CodeDoRangeExpression() { }
@@ -56,6 +60,9 @@
     }
 
-    protected override LoopExpression Clone(LoopState state) {
-      return new CodeDoRangeExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<CodeDoRangeExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
@@ -85,5 +92,6 @@
   ///     index that is less than the specified current index.
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.DO*RANGE")]
+  [Serializable]
+  [PushExpression(StackTypes.Exec, "EXEC.DO*RANGE", StackTypes.Integer)]
   public class ExecDoRangeExpression : DoRangeExpression {
     public ExecDoRangeExpression() { }
@@ -93,6 +101,9 @@
       return this.Eval(interpreter, interpreter.ExecStack);
     }
-    protected override LoopExpression Clone(LoopState state) {
-      return new ExecDoRangeExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<ExecDoRangeExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoTimesExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoTimesExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoTimesExpressions.cs	(revision 14777)
@@ -1,7 +1,10 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
+
   using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
 
+  [Serializable]
   public abstract class DoTimesExpression : LoopExpression {
     protected DoTimesExpression() { }
@@ -12,5 +15,5 @@
 
     protected override LoopState InitState(IPushInterpreter interpreter, IStack<Expression> sourceStack) {
-      return new LoopState(
+      return LoopState.Create(interpreter.PoolContainer.LoopStatePool,
         body: sourceStack.Pop(),
         currentIndex: 1,
@@ -20,8 +23,8 @@
 
     protected override void PushIteration(IPushInterpreter interpreter) {
-      var newState = new LoopState(State.Body, State.CurrentIndex + this.State.Incrementor, State.DestinationIndex, State.Incrementor);
-      var nextLoopExpression = Clone(newState);
+      var newState = LoopState.Create(interpreter.PoolContainer.LoopStatePool, State.Body, State.CurrentIndex + this.State.Incrementor, State.DestinationIndex, State.Incrementor);
+      var nextLoopExpression = Clone(newState, interpreter);
 
-      interpreter.ExecStack.Push(nextLoopExpression, this.State.Body);
+      interpreter.ExecStack.Push(nextLoopExpression, State.Body);
     }
 
@@ -37,5 +40,6 @@
   ///     in the call to CODE.DO*RANGE.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.DO*TIMES")]
+  [Serializable]
+  [PushExpression(StackTypes.Code, "CODE.DO*TIMES", StackTypes.Integer)]
   public class CodeDoTimesExpression : DoTimesExpression {
     public CodeDoTimesExpression() { }
@@ -46,6 +50,9 @@
     }
 
-    protected override LoopExpression Clone(LoopState state) {
-      return new CodeDoTimesExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<CodeDoTimesExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
@@ -60,5 +67,6 @@
   ///     pushed by EXEC.DO*RANGE, prior to the execution of the loop body.
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.DO*TIMES")]
+  [Serializable]
+  [PushExpression(StackTypes.Exec, "EXEC.DO*TIMES", StackTypes.Integer)]
   public class ExecDoTimesExpression : DoTimesExpression {
     public ExecDoTimesExpression() { }
@@ -69,6 +77,9 @@
     }
 
-    protected override LoopExpression Clone(LoopState state) {
-      return new ExecDoTimesExpression(state);
+    protected override LoopExpression Clone(LoopState state, IPushInterpreter interpreter) {
+      var expression = interpreter.PoolContainer.GetStatefulExpression<ExecDoTimesExpression>();
+      expression.State = state;
+
+      return expression;
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DuplicateExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DuplicateExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DuplicateExpressions.cs	(revision 14777)
@@ -28,5 +28,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.DUP")]
+  [PushExpression(StackTypes.Integer, "INTEGER.DUP")]
   public class IntegerDuplicateExpression : DuplicateExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -35,5 +35,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.DUP")]
+  [PushExpression(StackTypes.Float, "FLOAT.DUP")]
   public class FloatDuplicateExpression : DuplicateExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -42,5 +42,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.DUP")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.DUP")]
   public class BooleanDuplicateExpression : DuplicateExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -49,5 +49,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.DUP")]
+  [PushExpression(StackTypes.Name, "NAME.DUP")]
   public class NameDuplicateExpression : DuplicateExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -56,5 +56,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.DUP")]
+  [PushExpression(StackTypes.Exec, "EXEC.DUP")]
   public class ExecDuplicateExpression : DuplicateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -63,5 +63,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.DUP")]
+  [PushExpression(StackTypes.Code, "CODE.DUP")]
   public class CodeDuplicateExpression : DuplicateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EmptyExpresssions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EmptyExpresssions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EmptyExpresssions.cs	(revision 14777)
@@ -0,0 +1,66 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
+
+  using Stack;
+
+  /// <summary>
+  /// Tells whether that stack is empty.
+  /// </summary>
+  public abstract class EmptyExpresssions<T> : StatelessExpression {
+    public bool Eval(IStack<T> stack, IStack<bool> booleanStack) {
+      booleanStack.Push(stack.IsEmpty);
+
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Exec, "EXEC.EMPTY", StackTypes.Boolean)]
+  public class ExecEmptyExpression : EmptyExpresssions<Expression> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.ExecStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.Code, "CODE.EMPTY", StackTypes.Boolean)]
+  public class CodeEmptyExpression : EmptyExpresssions<Expression> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CodeStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.Integer, "INTEGER.EMPTY", StackTypes.Boolean)]
+  public class IntegerEmptyExpression : EmptyExpresssions<long> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.IntegerStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.Float, "FLOAT.EMPTY", StackTypes.Boolean)]
+  public class FloatEmptyExpression : EmptyExpresssions<double> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.FloatStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.EMPTY", StackTypes.Boolean)]
+  public class BooleanEmptyExpression : EmptyExpresssions<bool> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.BooleanStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.Char, "CHAR.EMPTY", StackTypes.Boolean)]
+  public class CharEmptyExpression : EmptyExpresssions<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.EMPTY", StackTypes.Boolean)]
+  public class StringEmptyExpression : EmptyExpresssions<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.BooleanStack);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EqualsExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EqualsExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/EqualsExpressions.cs	(revision 14777)
@@ -20,5 +20,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.=")]
+  [PushExpression(StackTypes.Integer, "INTEGER.=", StackTypes.Boolean)]
   public class IntegerEqualsExpression : EqualsExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -27,5 +27,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.=")]
+  [PushExpression(StackTypes.Float, "FLOAT.=", StackTypes.Boolean)]
   public class FloatEqualsExpression : EqualsExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -34,5 +34,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.=")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.=", StackTypes.Boolean)]
   public class BooleanEqualsExpression : EqualsExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -41,5 +41,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.=")]
+  [PushExpression(StackTypes.Name, "NAME.=", StackTypes.Boolean)]
   public class NameEqualsExpression : EqualsExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -48,5 +48,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.=")]
+  [PushExpression(StackTypes.Exec, "EXEC.=", StackTypes.Boolean)]
   public class ExecEqualsExpression : EqualsExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -55,5 +55,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.=")]
+  [PushExpression(StackTypes.Code, "CODE.=", StackTypes.Boolean)]
   public class CodeEqualsExpression : EqualsExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -61,3 +61,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.=", StackTypes.Boolean)]
+  public class CharEqualsExpression : EqualsExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.BooleanStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.=", StackTypes.Boolean)]
+  public class StringEqualsExpression : EqualsExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.BooleanStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs	(revision 14777)
@@ -12,5 +12,5 @@
   /// one item on the BOOLEAN stack.
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.IF")]
+  [PushExpression(StackTypes.Exec, "EXEC.IF", StackTypes.Boolean)]
   public class ExecIfExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -31,5 +31,5 @@
   ///     "( EXEC.Y <TopItem> )".
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.Y")]
+  [PushExpression(StackTypes.Exec, "EXEC.Y")]
   public class ExecYExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -40,6 +40,15 @@
 
       var top = interpreter.ExecStack.Top;
+
+      if (top is PushProgram && ((PushProgram)top).Depth == interpreter.Configuration.MaxDepth)
+        return false;
+
       var execYExpression = ExpressionTable.GetStatelessExpression<ExecYExpression>();
-      var result = PushProgram.Create(interpreter.PushProgramPool, top, execYExpression);
+      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
+
+      expressions.Add(top);
+      expressions.Add(execYExpression);
+
+      var result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
 
       interpreter.ExecStack.SetTop(result);
@@ -53,5 +62,5 @@
   ///     Removes the second item on the EXEC stack.
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.K")]
+  [PushExpression(StackTypes.Exec, "EXEC.K")]
   public class ExecKExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -70,8 +79,13 @@
   ///     another instance of C, followed by another instance of A.
   /// </summary>
-  [PushExpression(StackType.Exec, "EXEC.S")]
+  [PushExpression(StackTypes.Exec, "EXEC.S")]
   public class ExecSExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
       if (interpreter.ExecStack.Count < 3) return false;
+
+      // check max depth
+      if ((interpreter.ExecStack.Top is PushProgram && ((PushProgram)interpreter.ExecStack.Top).Depth == interpreter.Configuration.MaxDepth) ||
+          (interpreter.ExecStack.ReverseElementAt(1) is PushProgram && ((PushProgram)interpreter.ExecStack.ReverseElementAt(1)).Depth == interpreter.Configuration.MaxDepth))
+        return false;
 
       var expression = interpreter.ExecStack.Pop(2);
@@ -80,5 +94,9 @@
       var c = interpreter.ExecStack.Top;
 
-      var newTop = PushProgram.Create(interpreter.PushProgramPool, c, b);
+      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
+      expressions.Add(c);
+      expressions.Add(b);
+
+      var newTop = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
 
       interpreter.ExecStack.SetTop(newTop);
@@ -88,3 +106,64 @@
     }
   }
+
+  /// <summary>
+  ///     Does nothing.
+  /// </summary>
+  [PushExpression(StackTypes.Exec, "EXEC.NOOP")]
+  public class ExecNoopExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return false;
+    }
+  }
+
+  [PushExpression(StackTypes.Exec, "EXEC.WHILE", StackTypes.Boolean)]
+  public class ExecWhileExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.ExecStack.IsEmpty)
+        return false;
+
+      if (interpreter.BooleanStack.IsEmpty) {
+        interpreter.ExecStack.Pop();
+        return true;
+      }
+
+      var booleanTop = interpreter.BooleanStack.Pop();
+
+      if (!booleanTop) {
+        interpreter.ExecStack.Pop();
+        return true;
+      }
+
+      interpreter.ExecStack.Push(this, interpreter.ExecStack.Top);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Exec, "EXEC.DO*WHILE")]
+  public class ExecDoWhileExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.ExecStack.IsEmpty)
+        return false;
+
+      interpreter.ExecStack.Push(this, interpreter.ExecStack.Top);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.Exec, "EXEC.WHEN", StackTypes.Boolean)]
+  public class ExecWhenExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.ExecStack.IsEmpty ||
+          interpreter.BooleanStack.IsEmpty)
+        return false;
+
+      var when = interpreter.BooleanStack.Pop();
+
+      if (!when) {
+        interpreter.ExecStack.Pop();
+      }
+
+      return true;
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/Expression.cs	(revision 14777)
@@ -4,9 +4,10 @@
 
   using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
 
   using Interpreter;
 
   [Serializable]
-  public abstract class Expression {
+  public abstract class Expression : IPooledObject {
     public bool IsProgram { get { return this.GetType() == typeof(PushProgram); } }
 
@@ -30,4 +31,6 @@
       return this.StringRepresentation;
     }
+
+    void IPooledObject.Reset() { }
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs	(revision 14777)
@@ -10,18 +10,25 @@
   public static class ExpressionTable {
     public static readonly IDictionary<string, Expression> StatelessExpressionTable;
-    public static readonly IDictionary<string, Func<Expression>> StatefullExpressionFactory;
-    public static readonly IDictionary<StackType, IList<string>> StackTypeToNamesTable = new Dictionary<StackType, IList<string>>();
+    public static readonly IDictionary<string, Func<Expression>> StatefulExpressionFactory;
+    public static readonly IDictionary<StackTypes, IList<string>> StackTypeToNamesTable = new Dictionary<StackTypes, IList<string>>();
     public static readonly IDictionary<int, string> IndexToNameTable = new Dictionary<int, string>();
     public static readonly IDictionary<Type, string> TypeToNameTable = new Dictionary<Type, string>();
+    public static readonly IDictionary<StackTypes, IList<string>> StackDependencyToNamesTable = new Dictionary<StackTypes, IList<string>>();
     public static readonly string[] ExpressionNames;
 
+    public static readonly Type[] StatelessExpressionTypes;
+    public static readonly Type[] StatefulExpressionTypes;
+
     public static readonly int Count;
 
     static ExpressionTable() {
+      StatelessExpressionTypes = GetExpressionTypes(typeof(StatelessExpression)).ToArray();
+      StatefulExpressionTypes = GetExpressionTypes(typeof(StatefulExpression<>)).ToArray();
+
       StatelessExpressionTable = GetStatelessExpressionTable();
-      StatefullExpressionFactory = GetStatefullExpressionFactory();
-      ExpressionNames = StatelessExpressionTable.Keys.Concat(StatefullExpressionFactory.Keys).ToArray();
-
-      Count = StatelessExpressionTable.Count + StatefullExpressionFactory.Count;
+      StatefulExpressionFactory = GetStatefulExpressionFactory();
+      ExpressionNames = StatelessExpressionTable.Keys.Concat(StatefulExpressionFactory.Keys).ToArray();
+
+      Count = StatelessExpressionTable.Count + StatefulExpressionFactory.Count;
     }
 
@@ -38,5 +45,5 @@
       get
       {
-        return StatefullExpressionFactory.Count;
+        return StatefulExpressionFactory.Count;
       }
     }
@@ -44,7 +51,6 @@
     private static Dictionary<string, Expression> GetStatelessExpressionTable() {
       var dictionary = new Dictionary<string, Expression>();
-      var expressionTypes = GetExpressionTypes(typeof(StatelessExpression));
-
-      foreach (var type in expressionTypes) {
+
+      foreach (var type in StatelessExpressionTypes) {
         var expression = Activator.CreateInstance(type) as Expression;
         var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(type, typeof(PushExpressionAttribute));
@@ -54,9 +60,16 @@
         TypeToNameTable.Add(type, attribute.ExpressionName);
 
-        if (!StackTypeToNamesTable.ContainsKey(attribute.StackType)) {
-          StackTypeToNamesTable.Add(attribute.StackType, new List<string>());
-        }
-
-        StackTypeToNamesTable[attribute.StackType].Add(attribute.ExpressionName);
+        if (!StackTypeToNamesTable.ContainsKey(attribute.StackTypes)) {
+          StackTypeToNamesTable.Add(attribute.StackTypes, new List<string>());
+        }
+
+        StackTypeToNamesTable[attribute.StackTypes].Add(attribute.ExpressionName);
+
+        var dependencies = attribute.StackTypes | attribute.AdditionalStackDependencies;
+        if (!StackDependencyToNamesTable.ContainsKey(dependencies)) {
+          StackDependencyToNamesTable.Add(dependencies, new List<string>());
+        }
+
+        StackDependencyToNamesTable[dependencies].Add(attribute.ExpressionName);
       }
 
@@ -64,10 +77,8 @@
     }
 
-    private static Dictionary<string, Func<Expression>> GetStatefullExpressionFactory() {
+    private static Dictionary<string, Func<Expression>> GetStatefulExpressionFactory() {
       var dictionary = new Dictionary<string, Func<Expression>>();
-      var statefullExpressionType = typeof(StatefulExpression<>);
-      var expressionTypes = GetExpressionTypes(statefullExpressionType);
-
-      foreach (var type in expressionTypes) {
+
+      foreach (var type in StatefulExpressionTypes) {
         // Make a NewExpression that calls the ctor
         var newExp = System.Linq.Expressions.Expression.New(type);
@@ -81,9 +92,16 @@
         TypeToNameTable.Add(type, attribute.ExpressionName);
 
-        if (!StackTypeToNamesTable.ContainsKey(attribute.StackType)) {
-          StackTypeToNamesTable.Add(attribute.StackType, new List<string>());
-        }
-
-        StackTypeToNamesTable[attribute.StackType].Add(attribute.ExpressionName);
+        if (!StackTypeToNamesTable.ContainsKey(attribute.StackTypes)) {
+          StackTypeToNamesTable.Add(attribute.StackTypes, new List<string>());
+        }
+
+        StackTypeToNamesTable[attribute.StackTypes].Add(attribute.ExpressionName);
+
+        var dependencies = attribute.StackTypes | attribute.AdditionalStackDependencies;
+        if (!StackDependencyToNamesTable.ContainsKey(dependencies)) {
+          StackDependencyToNamesTable.Add(dependencies, new List<string>());
+        }
+
+        StackDependencyToNamesTable[dependencies].Add(attribute.ExpressionName);
       }
 
@@ -124,4 +142,11 @@
     }
 
+    public static IReadOnlyList<string> GetEnabledExpressionsByStackTypes(StackTypes allowedTypes) {
+      return StackDependencyToNamesTable
+          .Where(entry => (entry.Key & ~allowedTypes) == StackTypes.None)
+          .SelectMany(entry => entry.Value)
+          .ToArray();
+    }
+
     public static PushProgram GetProgram(IManagedPool<PushProgram> pool, int[] index) {
       var expressions = new Expression[index.Length];
@@ -142,5 +167,5 @@
 
       if (!TryGetStatelessExpression(name, out expression) &&
-          !TryGetStatefullExpression(name, out expression))
+          !TryGetStatefulExpression(name, out expression))
         throw new InvalidOperationException(string.Format("Expression with name {0} not found", name));
 
@@ -153,30 +178,34 @@
 
     public static Expression GetStatelessExpression(string name) {
-      Expression expression;
-      if (StatelessExpressionTable.TryGetValue(name, out expression))
-        return expression;
+      if (StatelessExpressionTable.ContainsKey(name))
+        return StatelessExpressionTable[name];
       throw new NotSupportedException("Expression not supported: " + name);
     }
 
     public static bool TryGetStatelessExpression(string name, out Expression expression) {
-      return StatelessExpressionTable.TryGetValue(name, out expression);
-    }
-
-    public static Expression GetStatefullExpression<T>() {
-      return GetStatefullExpression(TypeToNameTable[typeof(T)]);
-    }
-
-    public static Expression GetStatefullExpression(string name) {
+      if (!StatelessExpressionTable.ContainsKey(name)) {
+        expression = null;
+        return false;
+      }
+
+      expression = StatelessExpressionTable[name];
+
+      return true;
+    }
+
+    public static Expression GetStatefulExpression<T>() {
+      return GetStatefulExpression(TypeToNameTable[typeof(T)]);
+    }
+
+    public static Expression GetStatefulExpression(string name) {
       Func<Expression> creator;
-      if (StatefullExpressionFactory.TryGetValue(name, out creator))
+      if (StatefulExpressionFactory.TryGetValue(name, out creator))
         return creator();
       throw new NotSupportedException("Expression not supported: " + name);
     }
 
-    public static bool TryGetStatefullExpression(string name, out Expression expression) {
-      Func<Expression> creator;
-
-      if (StatefullExpressionFactory.TryGetValue(name, out creator)) {
-        expression = creator();
+    public static bool TryGetStatefulExpression(string name, out Expression expression) {
+      if (StatefulExpressionFactory.ContainsKey(name)) {
+        expression = StatefulExpressionFactory[name]();
         return true;
       }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FloatExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FloatExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FloatExpressions.cs	(revision 14777)
@@ -9,5 +9,5 @@
   ///     Pushes the sum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.+")]
+  [PushExpression(StackTypes.Float, "FLOAT.+")]
   public class FloatAddExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -19,5 +19,5 @@
   ///     Pushes the difference of the top two items; that is, the second item minus the top item.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.-")]
+  [PushExpression(StackTypes.Float, "FLOAT.-")]
   public class FloatSubtractExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -29,5 +29,5 @@
   ///     Pushes the product of the top two items.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.*")]
+  [PushExpression(StackTypes.Float, "FLOAT.*")]
   public class FloatMultiplyExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -40,5 +40,5 @@
   ///     If the top item is zero this acts as a NOOP.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT./")]
+  [PushExpression(StackTypes.Float, "FLOAT./")]
   public class FloatDivideExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -54,5 +54,5 @@
   ///     for example at http://www.lispworks.com/reference/HyperSpec/Body/f_mod_r.htm.)
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.%")]
+  [PushExpression(StackTypes.Float, "FLOAT.%")]
   public class FloatModuloExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -64,5 +64,5 @@
   ///     Pushes the minimum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.MIN")]
+  [PushExpression(StackTypes.Float, "FLOAT.MIN")]
   public class FloatMinExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -74,5 +74,5 @@
   ///     Pushes the maximum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.MAX")]
+  [PushExpression(StackTypes.Float, "FLOAT.MAX")]
   public class FloatMaxExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -84,5 +84,5 @@
   ///     Pushes TRUE onto the BOOLEAN stack if the second item is less than the top item, or FALSE otherwise.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.<")]
+  [PushExpression(StackTypes.Float, "FLOAT.<", StackTypes.Boolean)]
   public class FloatSmallerThanExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -92,7 +92,17 @@
 
   /// <summary>
+  ///     Pushes TRUE onto the BOOLEAN stack if the second item is less than the top item, or FALSE otherwise.
+  /// </summary>
+  [PushExpression(StackTypes.Float, "FLOAT.<=", StackTypes.Boolean)]
+  public class FloatSmallerThanOrEqualExpression : PushResultExpression<double> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.FloatStack, interpreter.BooleanStack, 2, values => values[0] <= values[1]);
+    }
+  }
+
+  /// <summary>
   ///     Pushes TRUE onto the BOOLEAN stack if the second item is greater than the top item, or FALSE otherwise.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.>")]
+  [PushExpression(StackTypes.Float, "FLOAT.>", StackTypes.Boolean)]
   public class FloatGreaterThanExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -102,7 +112,17 @@
 
   /// <summary>
+  ///     Pushes TRUE onto the BOOLEAN stack if the second item is greater than or equal to the top item, or FALSE otherwise.
+  /// </summary>
+  [PushExpression(StackTypes.Float, "FLOAT.>=", StackTypes.Boolean)]
+  public class FloatGreaterThanOrEqualExpression : PushResultExpression<double> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.FloatStack, interpreter.BooleanStack, 2, values => values[0] >= values[1]);
+    }
+  }
+
+  /// <summary>
   ///     Pushes the sine of the top item.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.SIN")]
+  [PushExpression(StackTypes.Float, "FLOAT.SIN")]
   public class FloatSineExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -114,5 +134,5 @@
   ///     Pushes the cosine of the top item.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.COS")]
+  [PushExpression(StackTypes.Float, "FLOAT.COS")]
   public class FloatCosineExpression : PushResultExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -124,5 +144,5 @@
   ///     Pushes 1 if the top BOOLEAN is TRUE, or 0 if the top BOOLEAN is FALSE.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.FROMBOOLEAN")]
+  [PushExpression(StackTypes.Float, "FLOAT.FROMBOOLEAN", StackTypes.Boolean)]
   public class FloatFromBooleanExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -141,5 +161,5 @@
   ///     Pushes a floating point version of the top INTEGER.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.FROMINTEGER")]
+  [PushExpression(StackTypes.Float, "FLOAT.FROMINTEGER", StackTypes.Integer)]
   public class FloatFromIntegerExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FlushExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FlushExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/FlushExpressions.cs	(revision 14777)
@@ -16,5 +16,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.FLUSH")]
+  [PushExpression(StackTypes.Integer, "INTEGER.FLUSH")]
   public class IntegerFlushExpression : FlushExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -23,5 +23,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.FLUSH")]
+  [PushExpression(StackTypes.Float, "FLOAT.FLUSH")]
   public class FloatFlushExpression : FlushExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -30,5 +30,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.FLUSH")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.FLUSH")]
   public class BooleanFlushExpression : FlushExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -37,5 +37,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.FLUSH")]
+  [PushExpression(StackTypes.Name, "NAME.FLUSH")]
   public class NameFlushExpression : FlushExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -44,5 +44,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.FLUSH")]
+  [PushExpression(StackTypes.Exec, "EXEC.FLUSH")]
   public class ExecFlushExpression : FlushExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -51,5 +51,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.FLUSH")]
+  [PushExpression(StackTypes.Code, "CODE.FLUSH")]
   public class CodeFlushExpression : FlushExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -57,3 +57,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.FLUSH")]
+  public class CharFlushExpression : FlushExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.FLUSH")]
+  public class StringFlushExpression : FlushExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/IntegerExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/IntegerExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/IntegerExpressions.cs	(revision 14777)
@@ -10,5 +10,5 @@
   ///     Pushes the sum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.+")]
+  [PushExpression(StackTypes.Integer, "INTEGER.+")]
   public class IntegerAddExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -20,5 +20,5 @@
   ///     Pushes the difference of the top two items; that is, the second item minus the top item.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.-")]
+  [PushExpression(StackTypes.Integer, "INTEGER.-")]
   public class IntegerSubtractExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -30,5 +30,5 @@
   ///     Pushes the product of the top two items.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.*")]
+  [PushExpression(StackTypes.Integer, "INTEGER.*")]
   public class IntegerMultiplyExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -41,5 +41,5 @@
   ///     If the top item is zero this acts as a NOOP.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER./")]
+  [PushExpression(StackTypes.Integer, "INTEGER./")]
   public class IntegerDivideExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -56,5 +56,5 @@
   ///     http://www.lispworks.com/reference/HyperSpec/Body/f_mod_r.htm.)
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.%")]
+  [PushExpression(StackTypes.Integer, "INTEGER.%")]
   public class IntegerModuloExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -66,5 +66,5 @@
   ///     Pushes the minimum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.MIN")]
+  [PushExpression(StackTypes.Integer, "INTEGER.MIN")]
   public class IntegerMinExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -76,5 +76,5 @@
   ///     Pushes the maximum of the top two items.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.MAX")]
+  [PushExpression(StackTypes.Integer, "INTEGER.MAX")]
   public class IntegerMaxExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -86,5 +86,5 @@
   ///     Pushes TRUE onto the BOOLEAN stack if the second item is less than the top item, or FALSE otherwise.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.<")]
+  [PushExpression(StackTypes.Integer, "INTEGER.<", StackTypes.Boolean)]
   public class IntegerSmallerThanExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -96,5 +96,5 @@
   ///     Pushes TRUE onto the BOOLEAN stack if the second item is greater than the top item, or FALSE otherwise.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.>")]
+  [PushExpression(StackTypes.Integer, "INTEGER.>", StackTypes.Boolean)]
   public class IntegerGreaterThanExpression : PushResultExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -106,5 +106,5 @@
   ///     Pushes 1 if the top BOOLEAN is TRUE, or 0 if the top BOOLEAN is FALSE.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.FROMBOOLEAN")]
+  [PushExpression(StackTypes.Integer, "INTEGER.FROMBOOLEAN", StackTypes.Boolean)]
   public class IntegerFromBooleanExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -123,5 +123,5 @@
   ///     Pushes the result of truncating the top FLOAT.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.FROMFLOAT")]
+  [PushExpression(StackTypes.Integer, "INTEGER.FROMFLOAT", StackTypes.Float)]
   public class IntegerFromFloatExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/LoopExpression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/LoopExpression.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/LoopExpression.cs	(revision 14777)
@@ -1,22 +1,47 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
 
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
 
-  public struct LoopState {
-    //public LoopState() { }
-    public LoopState(Expression body, long currentIndex, long destinationIndex, long incrementor) {
-      this.Body = body;
-      this.CurrentIndex = currentIndex;
-      this.DestinationIndex = destinationIndex;
-      this.Incrementor = incrementor;
+  [Serializable]
+  public class LoopState : IPooledObject {
+    public static LoopState Create(
+      IManagedPool<LoopState> pool,
+      Expression body,
+      long currentIndex,
+      long destinationIndex,
+      long incrementor) {
+      var state = pool.Get(false);
+
+      state.Body = body;
+      state.CurrentIndex = currentIndex;
+      state.DestinationIndex = destinationIndex;
+      state.Incrementor = incrementor;
+
+      return state;
     }
 
-    public readonly Expression Body;
-    public readonly long CurrentIndex;
-    public readonly long DestinationIndex;
-    public readonly long Incrementor;
+    public Expression Body { get; private set; }
+    public long CurrentIndex { get; private set; }
+    public long DestinationIndex { get; private set; }
+    public long Incrementor { get; private set; }
 
+    private int? hashCode;
     public override int GetHashCode() {
+      if (hashCode == null) hashCode = CalcHashCode();
+      return hashCode.Value;
+    }
+
+    public void Reset() {
+      Body = null;
+      CurrentIndex = default(long);
+      DestinationIndex = default(long);
+      Incrementor = default(long);
+    }
+
+    private int CalcHashCode() {
       var hash = 19;
 
@@ -32,4 +57,5 @@
   }
 
+  [Serializable]
   public abstract class LoopExpression : StatefulExpression<LoopState> {
     protected LoopExpression() : base(new LoopState()) { }
@@ -42,5 +68,5 @@
 
         var state = this.InitState(interpreter, sourceStack);
-        var initLoopExpression = Clone(state);
+        var initLoopExpression = Clone(state, interpreter);
 
         interpreter.ExecStack.Push(initLoopExpression, state.Body);
@@ -59,19 +85,39 @@
     }
 
+    private string stringRepresentation;
+    public override string StringRepresentation
+    {
+      get
+      {
+        if (stringRepresentation == null) {
+          var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(GetType(), typeof(PushExpressionAttribute));
+          stringRepresentation = attribute.ExpressionName;
+        }
+
+        return stringRepresentation;
+      }
+    }
+
     protected virtual void PushIteration(IPushInterpreter interpreter) {
       interpreter.IntegerStack.Push(this.State.CurrentIndex);
 
-      var newState = new LoopState(State.Body, State.CurrentIndex + this.State.Incrementor, State.DestinationIndex, State.Incrementor);
-      var nextLoopExpression = Clone(newState);
+      var newState = LoopState.Create(
+        interpreter.PoolContainer.LoopStatePool,
+        State.Body,
+        State.CurrentIndex + State.Incrementor,
+        State.DestinationIndex,
+        State.Incrementor);
 
-      interpreter.ExecStack.Push(nextLoopExpression, this.State.Body);
+      var nextLoopExpression = Clone(newState, interpreter);
+
+      interpreter.ExecStack.Push(nextLoopExpression, State.Body);
     }
 
     protected virtual void PushLastIteration(IPushInterpreter interpreter) {
-      interpreter.IntegerStack.Push(this.State.CurrentIndex);
-      interpreter.ExecStack.Push(this.State.Body);
+      interpreter.IntegerStack.Push(State.CurrentIndex);
+      interpreter.ExecStack.Push(State.Body);
     }
 
-    protected abstract LoopExpression Clone(LoopState state);
+    protected abstract LoopExpression Clone(LoopState state, IPushInterpreter interpreter);
     protected abstract bool HasInsufficientArguments(IPushInterpreter interpreter, IStack<Expression> sourceStack);
     protected abstract LoopState InitState(IPushInterpreter interpreter, IStack<Expression> sourceStack);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/NameExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/NameExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/NameExpressions.cs	(revision 14777)
@@ -20,6 +20,4 @@
       return true;
     }
-
-    public override string StringRepresentation { get { return this.State; } }
   }
 
@@ -31,5 +29,5 @@
   ///     onto the NAME stack the flag will be cleared (whether or not the pushed State had a definition).
   /// </summary>
-  [PushExpression(StackType.Name, "NAME.QUOTE")]
+  [PushExpression(StackTypes.Name, "NAME.QUOTE")]
   public class NameQuoteExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -44,5 +42,5 @@
   ///     Pushes a randomly selected NAME that already has a definition.
   /// </summary>
-  [PushExpression(StackType.Name, "NAME.RANDBOUNDNAME")]
+  [PushExpression(StackTypes.Name, "NAME.RANDBOUNDNAME")]
   public class NameRandBoundNameExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PopExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PopExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PopExpressions.cs	(revision 14777)
@@ -14,5 +14,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.POP")]
+  [PushExpression(StackTypes.Integer, "INTEGER.POP")]
   public class IntegerPopExpression : PopExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -21,5 +21,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.POP")]
+  [PushExpression(StackTypes.Float, "FLOAT.POP")]
   public class FloatPopExpression : PopExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -28,5 +28,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.POP")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.POP")]
   public class BooleanPopExpression : PopExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -35,5 +35,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.POP")]
+  [PushExpression(StackTypes.Name, "NAME.POP")]
   public class NamePopExpression : PopExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -42,5 +42,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.POP")]
+  [PushExpression(StackTypes.Exec, "EXEC.POP")]
   public class ExecPopExpression : PopExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -49,5 +49,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.POP")]
+  [PushExpression(StackTypes.Code, "CODE.POP")]
   public class CodePopExpression : PopExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -55,3 +55,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.POP")]
+  public class CharPopExpression : PopExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.POP")]
+  public class StringPopExpression : PopExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushExpressions.cs	(revision 14777)
@@ -64,3 +64,23 @@
     }
   }
+
+  public class CharPushExpression : PushExpression<char> {
+    public CharPushExpression(char state)
+      : base(state) {
+    }
+
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack);
+    }
+  }
+
+  public class StringPushExpression : PushExpression<string> {
+    public StringPushExpression(string state)
+      : base(state) {
+    }
+
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack);
+    }
+  }
 }
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 14747)
+++ 	(revision )
@@ -1,202 +1,0 @@
-﻿//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.IsProgram) {
-//          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.IsProgram);
-//      //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.IsProgram) 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.IsProgram) {
-//          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].IsProgram)
-//          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 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/PushProgram.cs	(revision 14777)
@@ -10,6 +10,16 @@
   using Interpreter;
 
+  public interface IMutablePushProgram {
+    void SetAtIndex(int index, Expression expression);
+  }
+
   [Serializable]
-  public sealed class PushProgram : Expression {
+  public sealed class PushProgram : Expression, IPooledObject, IMutablePushProgram {
+#if DEBUG
+    private const int StringRepresentationCountBeforeAggregate = 50;
+#else
+    private const int StringRepresentationCountBeforeAggregate = 10;
+#endif
+
     private static readonly Expression[] EmptyExpressions = new Expression[0];
     public static readonly PushProgram Empty = new PushProgram();
@@ -21,28 +31,26 @@
     private const string Delimiter = " ";
 
-    private Expression[] expressions;
+    private IReadOnlyList<Expression> expressions;
 
     public PushProgram() : this(EmptyExpressions) {
     }
 
-    public PushProgram(Expression[] expressions) {
+    public PushProgram(IReadOnlyList<Expression> expressions) {
       this.expressions = expressions;
     }
 
     public bool IsEmpty { get { return Count == 0; } }
-    public int Count { get { return expressions.Length; } }
+    public int Count { get { return expressions.Count; } }
 
     public IReadOnlyList<Expression> Expressions { get { return this.expressions; } }
 
-    public static PushProgram Create(IManagedPool<PushProgram> pool, params Expression[] expressions) {
+    public static PushProgram Create(IManagedPool<PushProgram> pool, IReadOnlyList<Expression> expressions) {
       var program = pool.Get();
-
       program.expressions = expressions;
-      program.Reset();
-
-      return program;
-    }
-
-    private void Reset() {
+      return program;
+    }
+
+    void IPooledObject.Reset() {
+      expressions = null;
       stringRepresentation = null;
       depth = null;
@@ -51,35 +59,39 @@
     }
 
-    public static PushProgram Merge(IManagedPool<PushProgram> pool, PushProgram first, Expression second) {
+    public static PushProgram Merge(IManagedPool<PushProgram> pool, IManagedPool<PooledList<Expression>> expressionListPool,
+      PushProgram first, Expression second) {
       var program = pool.Get();
-
-      program.Reset();
-      program.expressions = new Expression[first.Expressions.Count + 1];
-      first.CopyExpressionsTo(program.expressions);
-      program.expressions[0] = first;
-
-      return program;
-    }
-
-    public static PushProgram Merge(IManagedPool<PushProgram> pool, Expression first, PushProgram second) {
+      var list = expressionListPool.Get();
+
+      list.AddRange(first.Expressions);
+      list.Add(second);
+
+      program.expressions = list;
+
+      return program;
+    }
+
+    public static PushProgram Merge(IManagedPool<PushProgram> pool, IManagedPool<PooledList<Expression>> expressionListPool,
+      Expression first, PushProgram second) {
       var program = pool.Get();
-
-      program.Reset();
-
-      program.expressions = new Expression[second.Expressions.Count + 1];
-      program.expressions[0] = first;
-      second.CopyExpressionsTo(program.expressions, 0, 1, second.Count);
-
-      return program;
-    }
-
-    public static PushProgram Merge(IManagedPool<PushProgram> pool, PushProgram first, PushProgram second) {
+      var list = expressionListPool.Get();
+
+      list.Add(first);
+      list.AddRange(second.Expressions);
+
+      program.expressions = list;
+
+      return program;
+    }
+
+    public static PushProgram Merge(IManagedPool<PushProgram> pool, IManagedPool<PooledList<Expression>> expressionListPool,
+      PushProgram first, PushProgram second) {
       var program = pool.Get();
-
-      program.Reset();
-      program.expressions = new Expression[first.Count + second.Count];
-
-      first.CopyExpressionsTo(program.expressions);
-      second.CopyExpressionsTo(program.expressions, 0, first.Count, second.Count);
+      var list = expressionListPool.Get();
+
+      list.AddRange(first.Expressions);
+      list.AddRange(second.Expressions);
+
+      program.expressions = list;
 
       return program;
@@ -87,5 +99,10 @@
 
     public int IndexOf(Expression expression) {
-      return Array.IndexOf(this.expressions, expression);
+      var max = expressions.Count - 1;
+      for (var i = max; i >= 0; i--) {
+        if (expression.Equals(expressions[i])) return max - i;
+      }
+
+      return -1;
     }
 
@@ -127,10 +144,26 @@
     }
 
-    //public PushProgram Copy() {
-    //  // as the empty list is a static stateless expression, no copy required
-    //  return ReferenceEquals(this, Empty) || this.expressions.IsEmpty
-    //    ? Empty
-    //    : new PushProgram(this.expressions.Copy());
-    //}
+    void IMutablePushProgram.SetAtIndex(int index, Expression expression) {
+
+    }
+
+    public override bool Equals(object obj) {
+      if (ReferenceEquals(this, obj))
+        return true;
+
+      if (this.GetType() != obj.GetType())
+        return false;
+
+      var other = (PushProgram)obj;
+
+      return ReferenceEquals(expressions, other.expressions) ||
+             GetHashCode() == other.GetHashCode();
+    }
+
+    public bool Equals(PushProgram other) {
+      return ReferenceEquals(this, other) ||
+             ReferenceEquals(expressions, other.expressions) ||
+             GetHashCode() == other.GetHashCode();
+    }
 
     public override bool Eval(IPushInterpreter interpreter) {
@@ -160,10 +193,8 @@
     public IEnumerable<Expression> DepthFirst() {
       foreach (var expr in this.expressions) {
-        if (expr.IsProgram) {
-          var expandExpr = (PushProgram)expr;
-
-          foreach (var sub in expandExpr.DepthFirst())
+        if (expr.IsProgram)
+          foreach (var sub in ((PushProgram)expr).DepthFirst())
             yield return sub;
-        } else yield return expr;
+        else yield return expr;
       }
     }
@@ -172,12 +203,10 @@
       if (IsEmpty) return this;
 
-      var program = new PushProgram(this.expressions) {
-        stringRepresentation = this.stringRepresentation,
-        hashCode = this.hashCode,
-        depth = this.depth,
-        treeIndex = this.treeIndex
+      return new PushProgram(expressions) {
+        stringRepresentation = stringRepresentation,
+        hashCode = hashCode,
+        depth = depth,
+        treeIndex = treeIndex
       };
-
-      return program;
     }
 
@@ -185,6 +214,7 @@
       if (IsEmpty) return this;
 
-      var program = pool.Get();
-      program.expressions = this.expressions;
+      var program = pool.Get(reset: false);
+
+      program.expressions = expressions;
       program.stringRepresentation = stringRepresentation;
       program.hashCode = hashCode;
@@ -195,41 +225,15 @@
     }
 
-    public PushProgram Copy(IManagedPool<PushProgram> pool, int startIndex, int length) {
-      if (IsEmpty) return this;
-
-      var program = pool.Get();
-      program.expressions = CopyExpressions(startIndex, length);
-
-      program.Reset();
-
-      return program;
-    }
-
-    public Expression[] CopyExpressions() {
-      return CopyExpressions(Count);
-    }
-
-    public Expression[] CopyExpressions(int length) {
+    public IList<Expression> CopyExpressions() {
+      return new List<Expression>(this.expressions);
+    }
+
+    public IList<Expression> CopyExpressions(IManagedPool<PooledList<Expression>> expressionListPool) {
       if (IsEmpty) return EmptyExpressions;
 
-      var copy = new Expression[length];
-      this.expressions.CopyTo(copy, 0);
+      var copy = expressionListPool.Get();
+      copy.AddRange(this.expressions);
 
       return copy;
-    }
-
-    public Expression[] CopyExpressions(int startIndex, int length) {
-      if (IsEmpty) return EmptyExpressions;
-
-      var copy = new Expression[length];
-      CopyExpressionsTo(copy, startIndex, 0, length);
-
-      return copy;
-    }
-
-    public void CopyExpressionsTo(Expression[] destination, int? sourceIndex = null, int? destinationIndex = null, int? length = null) {
-      if (IsEmpty) return;
-
-      Array.Copy(this.expressions, sourceIndex ?? 0, destination, destinationIndex ?? 0, length ?? Count);
     }
 
@@ -250,7 +254,7 @@
     private string BuildString() {
       // prevent too big string
-      return this.TotalCount > 50
-        ? PrefixReduced + this.Count + PostfixReduced
-        : Prefix + string.Join(Delimiter, this.expressions.Where(e => !string.IsNullOrWhiteSpace(e.StringRepresentation))) + Postfix;
+      return TotalCount > StringRepresentationCountBeforeAggregate
+        ? PrefixReduced + Count + PostfixReduced
+        : Prefix + string.Join(Delimiter, expressions) + Postfix;
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RandExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RandExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RandExpressions.cs	(revision 14777)
@@ -8,5 +8,5 @@
   ///     Pushes a random NAME.
   /// </summary>
-  [PushExpression(StackType.Name, "NAME.RAND")]
+  [PushExpression(StackTypes.Name, "NAME.RAND")]
   public class NameRandExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -21,5 +21,5 @@
   ///     Pushes a random integer.
   /// </summary>
-  [PushExpression(StackType.Integer, "INTEGER.RAND")]
+  [PushExpression(StackTypes.Integer, "INTEGER.RAND")]
   public class IntegerRandExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -36,5 +36,5 @@
   ///     Pushes a random float.
   /// </summary>
-  [PushExpression(StackType.Float, "FLOAT.RAND")]
+  [PushExpression(StackTypes.Float, "FLOAT.RAND")]
   public class FloatRandExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -49,5 +49,5 @@
   ///     Pushes a random boolean.
   /// </summary>
-  [PushExpression(StackType.Boolean, "BOOLEAN.RAND")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.RAND")]
   public class BooleanRandExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -62,5 +62,5 @@
   ///     Pushes random expressions onto the code stack.
   /// </summary>
-  [PushExpression(StackType.Code, "CODE.RAND")]
+  [PushExpression(StackTypes.Code, "CODE.RAND")]
   public class CodeRandExpression : StatelessExpression {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -69,6 +69,7 @@
 
       var size = (int)(interpreter.IntegerStack.Pop() % interpreter.Configuration.MaxPointsInRandomExpression);
-      var program = CodeGenerator.RandomProgram(
-        interpreter.PushProgramPool,
+      var program = LinearCodeGenerator.RandomProgram(
+        interpreter.PoolContainer.PushProgramPool,
+        interpreter.PoolContainer.ExpressionListPool,
         size,
         interpreter.Random,
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RotateExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RotateExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/RotateExpressions.cs	(revision 14777)
@@ -15,5 +15,5 @@
 
 
-  [PushExpression(StackType.Integer, "INTEGER.ROT")]
+  [PushExpression(StackTypes.Integer, "INTEGER.ROT")]
   public class IntegerRotateExpression : RotateExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -22,5 +22,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.ROT")]
+  [PushExpression(StackTypes.Float, "FLOAT.ROT")]
   public class FloatRotateExpression : RotateExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -29,5 +29,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.ROT")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.ROT")]
   public class BooleanRotateExpression : RotateExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -36,5 +36,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.ROT")]
+  [PushExpression(StackTypes.Name, "NAME.ROT")]
   public class NameRotateExpression : RotateExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -43,5 +43,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.ROT")]
+  [PushExpression(StackTypes.Exec, "EXEC.ROT")]
   public class ExecRotateExpression : RotateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -50,5 +50,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.ROT")]
+  [PushExpression(StackTypes.Code, "CODE.ROT")]
   public class CodeRotateExpression : RotateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -56,3 +56,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.ROT")]
+  public class CharRotateExpression : RotateExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.ROT")]
+  public class StringRotateExpression : RotateExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ShoveExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ShoveExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ShoveExpressions.cs	(revision 14777)
@@ -21,5 +21,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.SHOVE")]
+  [PushExpression(StackTypes.Integer, "INTEGER.SHOVE")]
   public class IntegerShoveExpression : ShoveExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -28,5 +28,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.SHOVE")]
+  [PushExpression(StackTypes.Float, "FLOAT.SHOVE", StackTypes.Integer)]
   public class FloatShoveExpression : ShoveExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -35,5 +35,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.SHOVE")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.SHOVE", StackTypes.Integer)]
   public class BooleanShoveExpression : ShoveExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -42,5 +42,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.SHOVE")]
+  [PushExpression(StackTypes.Name, "NAME.SHOVE", StackTypes.Integer)]
   public class NameShoveExpression : ShoveExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -49,5 +49,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.SHOVE")]
+  [PushExpression(StackTypes.Exec, "EXEC.SHOVE", StackTypes.Integer)]
   public class ExecShoveExpression : ShoveExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -56,5 +56,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.SHOVE")]
+  [PushExpression(StackTypes.Code, "CODE.SHOVE", StackTypes.Integer)]
   public class CodeShoveExpression : ShoveExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -62,3 +62,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.SHOVE", StackTypes.Integer)]
+  public class CharShoveExpression : ShoveExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.IntegerStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.SHOVE", StackTypes.Integer)]
+  public class StringShoveExpression : ShoveExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.IntegerStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StackdepthExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StackdepthExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StackdepthExpressions.cs	(revision 14777)
@@ -20,5 +20,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.STACKDEPTH")]
+  [PushExpression(StackTypes.Integer, "INTEGER.STACKDEPTH")]
   public class IntegerStackdepthExpression : StackdepthExpression<long> {
 
@@ -28,5 +28,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.STACKDEPTH")]
+  [PushExpression(StackTypes.Float, "FLOAT.STACKDEPTH", StackTypes.Integer)]
   public class FloatStackdepthExpression : StackdepthExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -35,5 +35,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.STACKDEPTH")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.STACKDEPTH", StackTypes.Integer)]
   public class BooleanStackdepthExpression : StackdepthExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -42,5 +42,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.STACKDEPTH")]
+  [PushExpression(StackTypes.Name, "NAME.STACKDEPTH", StackTypes.Integer)]
   public class NameStackdepthExpression : StackdepthExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -49,5 +49,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.STACKDEPTH")]
+  [PushExpression(StackTypes.Exec, "EXEC.STACKDEPTH", StackTypes.Integer)]
   public class ExecStackdepthExpression : StackdepthExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -56,5 +56,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.STACKDEPTH")]
+  [PushExpression(StackTypes.Code, "CODE.STACKDEPTH", StackTypes.Integer)]
   public class CodeStackdepthExpression : StackdepthExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -62,3 +62,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.STACKDEPTH", StackTypes.Integer)]
+  public class CharStackdepthExpression : StackdepthExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.IntegerStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.STACKDEPTH", StackTypes.Integer)]
+  public class StringStackdepthExpression : StackdepthExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.IntegerStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StatefulExpression.cs	(revision 14777)
@@ -1,6 +1,12 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
-  public abstract class StatefulExpression<T> : Expression {
-    public readonly T State;
+  using System;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
+
+  [Serializable]
+  public abstract class StatefulExpression<T> : Expression, IPooledObject {
+    public T State { get; protected set; }
     private int? hashCode;
+    private string stringRepresentation;
 
     protected StatefulExpression(T state) {
@@ -10,4 +16,13 @@
     protected virtual int CalcHashCode() {
       return this.State.GetHashCode();
+    }
+
+    public override string StringRepresentation
+    {
+      get
+      {
+        if (stringRepresentation == null) stringRepresentation = this.State.ToString();
+        return stringRepresentation;
+      }
     }
 
@@ -40,4 +55,8 @@
       return hashCode.Value;
     }
+
+    public void Reset() {
+      State = default(T);
+    }
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StringExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StringExpressions.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StringExpressions.cs	(revision 14777)
@@ -0,0 +1,492 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
+  using System;
+  using System.Linq;
+
+  using Attributes;
+  using Interpreter;
+  using Stack;
+
+  [PushExpression(StackTypes.String, "STRING.FROMINTEGER", StackTypes.Integer)]
+  public class StringFromIntegerExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.IntegerStack.IsEmpty)
+        return false;
+
+      var value = interpreter.IntegerStack.Pop();
+      interpreter.StringStack.Push(value.ToString());
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.FROMFLOAT", StackTypes.Float)]
+  public class StringFromFloatExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.FloatStack.IsEmpty)
+        return false;
+
+      var value = interpreter.FloatStack.Pop();
+      interpreter.StringStack.Push(value.ToString());
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.FROMBOOLEAN", StackTypes.Boolean)]
+  public class StringFromBooleanExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.BooleanStack.IsEmpty)
+        return false;
+
+      var value = interpreter.BooleanStack.Pop();
+      interpreter.StringStack.Push(value.ToString());
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.FROMCHAR", StackTypes.Char)]
+  public class StringFromCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.CharStack.IsEmpty)
+        return false;
+
+      var value = interpreter.CharStack.Pop();
+      interpreter.StringStack.Push(value.ToString());
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.CONCAT")]
+  public class StringConcatExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.Count < 2 ||
+        interpreter.StringStack.Top.Length + interpreter.StringStack.ReverseElementAt(1).Length >= interpreter.Configuration.MaxStringLength)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      interpreter.StringStack.SetTop(str + interpreter.StringStack.Top);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// Conj char onto string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.CONJCHAR", StackTypes.Char)]
+  public class StringConjCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty ||
+          interpreter.StringStack.Top.Length + 1 >= interpreter.Configuration.MaxStringLength)
+        return false;
+
+      var c = interpreter.CharStack.Pop();
+      interpreter.StringStack.SetTop(interpreter.StringStack.Top + c);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.TAKE", StackTypes.Integer)]
+  public class StringTakeExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.IntegerStack.IsEmpty)
+        return false;
+
+      var value = interpreter.IntegerStack.Pop();
+
+      if (value < 0) {
+        return true;
+      }
+
+      var str = interpreter.StringStack.Top;
+
+      if (str.Length > 0) {
+        value = Math.Min(str.Length - 1, value);
+        interpreter.StringStack.SetTop(str.Substring(0, (int)value));
+      }
+
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.SUBSTRING", StackTypes.Integer)]
+  public class StringSubstringExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.IntegerStack.Count < 2)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      var values = interpreter.IntegerStack.Pop(2);
+      var first = Math.Min(str.Length - 1, Math.Max(values[0], 0));
+      var second = Math.Min(str.Length - 1, Math.Max(values[1], first));
+      var length = second - first;
+
+      if (length > 0)
+        interpreter.StringStack.SetTop(str.Substring((int)first, (int)length));
+
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.FIRST")]
+  public class StringFirstExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.StringStack.Top.Length == 0)
+        return false;
+
+      interpreter.StringStack.SetTop(interpreter.StringStack.Top[0].ToString());
+      return true;
+    }
+  }
+
+
+  [PushExpression(StackTypes.String, "STRING.LAST")]
+  public class StringLastExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.StringStack.Top.Length == 0)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      var c = str[str.Length - 1].ToString();
+      interpreter.StringStack.SetTop(c);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.NTH", StackTypes.Integer)]
+  public class StringNthExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.IntegerStack.IsEmpty ||
+          interpreter.StringStack.Top.Length == 0)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      var index = str.Length == 1 ? 0 : (int)Math.Abs(interpreter.IntegerStack.Pop() % (str.Length - 1));
+      var c = str[index].ToString();
+      interpreter.StringStack.SetTop(c);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.REST")]
+  public class StringRestExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.StringStack.Top.Length == 0)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(1, str.Length - 1));
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.BUTLAST")]
+  public class StringButLastExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.StringStack.Top.Length == 0)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(0, str.Length - 1));
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.LENGTH", StackTypes.Integer)]
+  public class StringLengthExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      interpreter.IntegerStack.Push(str.Length);
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.REVERSE")]
+  public class StringReverseExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty)
+        return false;
+
+      interpreter.StringStack.SetTop(interpreter.StringStack.Top.Reverse().ToString());
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.PARSETOCHARS")]
+  public class StringParseToCharsExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty)
+        return false;
+
+      if (interpreter.StringStack.Top.Length == 0) {
+        interpreter.StringStack.Pop();
+        return true;
+      }
+
+      var str = interpreter.StringStack.Top;
+      interpreter.StringStack.SetTop(str[0].ToString());
+
+      if (str.Length > 1) {
+        var chars = new string[str.Length - 1];
+        for (var i = 0; i < str.Length - 1; i++) {
+          chars[i] = str[i + 1].ToString();
+        }
+
+        interpreter.StringStack.Push(chars);
+      }
+
+      return true;
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.SPLIT")]
+  public class StringSplitExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty)
+        return false;
+
+      var words = interpreter.StringStack.Top.Trim().Split();
+
+      if (words.Length == 0)
+        return false;
+
+      interpreter.StringStack.SetTop(words[0]);
+
+      if (words.Length > 1)
+        interpreter.StringStack.Push(words, 1);
+
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// True if top string is empty
+  /// </summary>
+
+  [PushExpression(StackTypes.String, "STRING.EMPTYSTRING", StackTypes.Boolean)]
+  public class StringEmptyStringExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      interpreter.BooleanStack.Push(str.Length == 0);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// True if top string is a substring of second string; false otherwise
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.CONTAINS", StackTypes.Boolean)]
+  public class StringContainsExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.Count < 2)
+        return false;
+
+      var strings = interpreter.StringStack.Pop(2);
+      interpreter.BooleanStack.Push(strings[0].IndexOf(strings[1], StringComparison.Ordinal) >= 0);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// True if the top char is in the top string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.CONTAINSCHAR", StackTypes.Boolean | StackTypes.Char)]
+  public class StringContainsCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      var c = interpreter.CharStack.Pop();
+
+      interpreter.BooleanStack.Push(str.IndexOf(c) >= 0);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// Puts on the integer stack the index of the top char in the top string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.INDEXOFCHAR", StackTypes.Integer | StackTypes.Char)]
+  public class StringIndexOfCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      var c = interpreter.CharStack.Pop();
+
+      interpreter.IntegerStack.Push(str.IndexOf(c));
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// The number of times the top char is in the top string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.OCCURENCESOFCHAR", StackTypes.Integer | StackTypes.Char)]
+  public class StringOccurrencesOfCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Pop();
+      var c = interpreter.CharStack.Pop();
+
+      var count = 0;
+      for (var i = 0; i < str.Length; i++)
+        if (str[i] == c) count++;
+
+      interpreter.IntegerStack.Push(count);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// In third string on stack, replaces second string with first string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.REPLACE")]
+  public class StringReplaceExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.Count < 3)
+        return false;
+
+      var strings = interpreter.StringStack.Pop(2);
+
+      if (strings[0].Length == 0 || strings[1].Length == 0)
+        interpreter.StringStack.SetTop(strings[0]);
+      else {
+        var result = strings[0].Replace(strings[1], interpreter.StringStack.Top);
+        interpreter.StringStack.SetTop(result);
+      }
+
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// In third string on stack, replaces first occurence of second string with first string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.REPLACEFIRST")]
+  public class StringReplaceFirstExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.Count < 3)
+        return false;
+
+      var strings = interpreter.StringStack.Pop(2);
+
+      var pos = strings[0].IndexOf(strings[1], StringComparison.Ordinal);
+
+      if (pos < 0)
+        return true;
+
+      var result = strings[0].Substring(0, pos) +
+                   interpreter.StringStack.Top +
+                   strings[0].Substring(pos + strings[1].Length);
+
+      interpreter.StringStack.SetTop(result);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// In top string on stack, replaces all occurences of second char with first char
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.REPLACECHAR", StackTypes.Char)]
+  public class StringReplaceCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.Count < 2)
+        return false;
+
+      var chars = interpreter.CharStack.Pop(2);
+      var result = interpreter.StringStack.Top.Replace(chars[0], chars[1]);
+      interpreter.StringStack.SetTop(result);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// In top string on stack, replaces first occurence of second char with first char
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.REPLACEFIRSTCHAR", StackTypes.Char)]
+  public class StringReplaceFirstCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.Count < 2)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      var chars = interpreter.CharStack.Pop(2);
+      var pos = interpreter.StringStack.Top.IndexOf(chars[0]);
+
+      if (pos < 0)
+        return true;
+
+      var result = str.Substring(0, pos) +
+                   chars[1] +
+                   str.Substring(Math.Min(pos + 2, str.Length - 1));
+      interpreter.StringStack.SetTop(result);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// In top string on stack, remove all occurences of char
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.REMOVECHAR", StackTypes.Char)]
+  public class StringRemoveCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty)
+        return false;
+
+      var c = interpreter.CharStack.Pop();
+      var result = interpreter.StringStack.Top.Trim(c);
+      interpreter.StringStack.SetTop(result);
+      return true;
+    }
+  }
+
+  /// <summary>
+  /// Returns a function that sets char at index in string
+  /// </summary>
+  [PushExpression(StackTypes.String, "STRING.SETCHAR", StackTypes.Char | StackTypes.Integer)]
+  public class StringSetCharExpression : StatelessExpression {
+    public override bool Eval(IPushInterpreter interpreter) {
+      if (interpreter.StringStack.IsEmpty ||
+          interpreter.CharStack.IsEmpty ||
+          interpreter.IntegerStack.IsEmpty)
+        return false;
+
+      var str = interpreter.StringStack.Top;
+      var i = (int)interpreter.IntegerStack.Pop();
+      var c = interpreter.CharStack.Pop();
+
+      if (str.Length == 0) {
+        interpreter.StringStack.Pop();
+        return true;
+      }
+
+      var pos = str.Length == 1 ? 0 : Math.Abs(i) % (str.Length - 1);
+      var result = str.Substring(0, pos) + c + str.Substring(Math.Min(pos + 2, str.Length - 1));
+
+      interpreter.StringStack.SetTop(result);
+      return true;
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/SwapExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/SwapExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/SwapExpressions.cs	(revision 14777)
@@ -19,5 +19,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.SWAP")]
+  [PushExpression(StackTypes.Integer, "INTEGER.SWAP")]
   public class IntegerSwapExpression : SwapExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -26,5 +26,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.SWAP")]
+  [PushExpression(StackTypes.Float, "FLOAT.SWAP")]
   public class FloatSwapExpression : SwapExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -33,5 +33,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.SWAP")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.SWAP")]
   public class BooleanSwapExpression : SwapExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -40,5 +40,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.SWAP")]
+  [PushExpression(StackTypes.Name, "NAME.SWAP")]
   public class NameSwapExpression : SwapExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -47,5 +47,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.SWAP")]
+  [PushExpression(StackTypes.Exec, "EXEC.SWAP")]
   public class ExecSwapExpression : SwapExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -54,5 +54,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.SWAP")]
+  [PushExpression(StackTypes.Code, "CODE.SWAP")]
   public class CodeSwapExpression : SwapExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -60,3 +60,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.SWAP")]
+  public class CharSwapExpression : SwapExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.SWAP")]
+  public class StringSwapExpression : SwapExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankDuplicateExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankDuplicateExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankDuplicateExpressions.cs	(revision 14777)
@@ -55,5 +55,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.YANKDUP")]
+  [PushExpression(StackTypes.Integer, "INTEGER.YANKDUP")]
   public class IntegerYankDuplicateExpression : YankDuplicateExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -62,5 +62,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.YANKDUP")]
+  [PushExpression(StackTypes.Float, "FLOAT.YANKDUP", StackTypes.Integer)]
   public class FloatYankDuplicateExpression : YankDuplicateExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -69,5 +69,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.YANKDUP")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.YANKDUP", StackTypes.Integer)]
   public class BooleanYankDuplicateExpression : YankDuplicateExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -76,5 +76,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.YANKDUP")]
+  [PushExpression(StackTypes.Name, "NAME.YANKDUP", StackTypes.Integer)]
   public class NameYankDuplicateExpression : YankDuplicateExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -83,5 +83,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.YANKDUP")]
+  [PushExpression(StackTypes.Exec, "EXEC.YANKDUP", StackTypes.Integer)]
   public class ExecYankDuplicateExpression : YankDuplicateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -90,5 +90,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.YANKDUP")]
+  [PushExpression(StackTypes.Code, "CODE.YANKDUP", StackTypes.Integer)]
   public class CodeYankDuplicateExpression : YankDuplicateExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -96,3 +96,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.YANKDUP", StackTypes.Integer)]
+  public class CharYankDuplicateExpression : YankDuplicateExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.IntegerStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.YANKDUP", StackTypes.Integer)]
+  public class StringYankDuplicateExpression : YankDuplicateExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.IntegerStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankExpressions.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankExpressions.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/YankExpressions.cs	(revision 14777)
@@ -24,5 +24,5 @@
   }
 
-  [PushExpression(StackType.Integer, "INTEGER.YANK")]
+  [PushExpression(StackTypes.Integer, "INTEGER.YANK")]
   public class IntegerYankExpression : YankExpression<long> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -31,5 +31,5 @@
   }
 
-  [PushExpression(StackType.Float, "FLOAT.YANK")]
+  [PushExpression(StackTypes.Float, "FLOAT.YANK", StackTypes.Integer)]
   public class FloatYankExpression : YankExpression<double> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -38,5 +38,5 @@
   }
 
-  [PushExpression(StackType.Boolean, "BOOLEAN.YANK")]
+  [PushExpression(StackTypes.Boolean, "BOOLEAN.YANK", StackTypes.Integer)]
   public class BooleanYankExpression : YankExpression<bool> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -45,5 +45,5 @@
   }
 
-  [PushExpression(StackType.Name, "NAME.YANK")]
+  [PushExpression(StackTypes.Name, "NAME.YANK", StackTypes.Integer)]
   public class NameYankExpression : YankExpression<string> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -52,5 +52,5 @@
   }
 
-  [PushExpression(StackType.Exec, "EXEC.YANK")]
+  [PushExpression(StackTypes.Exec, "EXEC.YANK", StackTypes.Integer)]
   public class ExecYankExpression : YankExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -59,5 +59,5 @@
   }
 
-  [PushExpression(StackType.Code, "CODE.YANK")]
+  [PushExpression(StackTypes.Code, "CODE.YANK", StackTypes.Integer)]
   public class CodeYankExpression : YankExpression<Expression> {
     public override bool Eval(IPushInterpreter interpreter) {
@@ -65,3 +65,17 @@
     }
   }
+
+  [PushExpression(StackTypes.Char, "CHAR.YANK", StackTypes.Integer)]
+  public class CharYankExpression : YankExpression<char> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.CharStack, interpreter.IntegerStack);
+    }
+  }
+
+  [PushExpression(StackTypes.String, "STRING.YANK", StackTypes.Integer)]
+  public class StringYankExpression : YankExpression<string> {
+    public override bool Eval(IPushInterpreter interpreter) {
+      return Eval(interpreter.StringStack, interpreter.IntegerStack);
+    }
+  }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/CodeGenerator.cs	(revision 14747)
+++ 	(revision )
@@ -1,107 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Generators {
-  using System;
-  using System.Collections.Generic;
-  using System.Linq;
-  using HeuristicLab.Core;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-  using HeuristicLab.Random;
-
-  /// <summary>
-  ///     The following is the standard Push random code generation algorithm, which is used for the CODE.RAND instruction.
-  ///     It may also be useful for the initialization of programs in evolutionary computation systems, and it is used for
-  ///     this purpose in PushGP.
-  ///     It produces a uniform distribution of sizes and what seems to be a reasonable distribution of shapes, in a
-  ///     reasonable amount of time.
-  /// </summary>
-  /// <see cref="http://faculty.hampshire.edu/lspector/push3-description.html#RandomCode" />
-  public static class CodeGenerator {
-
-    public static PushProgram RandomProgram(IManagedPool<PushProgram> pool, int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
-      var code = RandomCode(maxPoints, random, pushGpConfiguration, customExpressions);
-
-      return PushProgram.Create(pool, code.ToArray());
-    }
-
-    public static IEnumerable<Expression> RandomCode(int maxPoints, IRandom random = null, IReadonlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
-      if (maxPoints == 0)
-        return new Expression[0];
-
-      random = random ?? new FastRandom();
-      pushGpConfiguration = pushGpConfiguration ?? new PushConfiguration();
-
-      if (pushGpConfiguration.EnabledExpressions.Count == 0)
-        return new Expression[0];
-
-      var actualPoints = maxPoints == 1 ? 1 : random.Next(1, Math.Max(1, maxPoints));
-
-      return RandomCodeWithSize(actualPoints, random, pushGpConfiguration, customExpressions);
-    }
-
-    private static IEnumerable<Expression> RandomCodeWithSize(int points, IRandom random, IReadonlyPushConfiguration pushGpConfiguration, IDictionary<string, Expression> customExpressions = null) {
-      if (points == 1) {
-
-        // check if erc expression should be taken
-        return random.NextDouble() <= pushGpConfiguration.ErcProbability
-          ? new[] { CreateRandomErcExpression(random, pushGpConfiguration) }
-          : new[] { CreateExpression(random, pushGpConfiguration, customExpressions) };
-      }
-
-      var maxParts = points - 1;
-
-      return Decompose(maxParts, maxParts, random)
-        .SelectMany(size => RandomCodeWithSize(size, random, pushGpConfiguration, customExpressions));
-    }
-
-    private static IEnumerable<int> Decompose(int number, int maxParts, IRandom random) {
-      if ((number == 1) || (maxParts == 1))
-        return new[] { number };
-
-      var thisPart = number == 2 ? 1 : random.Next(1, number - 1);
-
-      return new[] { thisPart }.Concat(Decompose(number - thisPart, maxParts - 1, random));
-    }
-
-    private static Expression CreateExpression(IRandom random, IReadonlyPushConfiguration pushGpConfiguration, IDictionary<string, Expression> customExpressions = null) {
-      var customCount = customExpressions == null ? 0 : customExpressions.Count - 1;
-      var index = random.Next(0, pushGpConfiguration.EnabledExpressions.Count + customCount - 1);
-
-      if ((index >= 0) && (index < pushGpConfiguration.EnabledExpressions.Count)) {
-        var name = pushGpConfiguration.EnabledExpressions[index];
-        return ExpressionTable.GetExpression(name);
-      }
-
-      if (customExpressions == null)
-        throw new IndexOutOfRangeException();
-
-      return customExpressions.ElementAt(index - (pushGpConfiguration.EnabledExpressions.Count - 1)).Value;
-    }
-
-    private static Expression CreateRandomErcExpression(IRandom random, IReadonlyPushConfiguration pushGpConfiguration) {
-      var value = random.Next(0, 3);
-
-      switch (value) {
-        case 0:
-          return new IntegerPushExpression(random.Next(
-            pushGpConfiguration.MinRandomInteger,
-            pushGpConfiguration.MaxRandomInteger));
-
-        case 1:
-          return new FloatPushExpression(
-            random.NextDouble() *
-            (pushGpConfiguration.MaxRandomFloat - pushGpConfiguration.MinRandomFloat) +
-            pushGpConfiguration.MinRandomFloat);
-
-        case 2:
-          return new BooleanPushExpression(random.NextDouble() > 0.5);
-
-        case 3:
-          return new NamePushExpression(NameGenerator.RandomName(random));
-
-        default:
-          throw new NotImplementedException();
-      }
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/LinearCodeGenerator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/LinearCodeGenerator.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/LinearCodeGenerator.cs	(revision 14777)
@@ -0,0 +1,98 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Generators {
+  using HeuristicLab.Core;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+  using HeuristicLab.Random;
+
+  public class LinearCodeGenerator {
+    public static PushProgram RandomProgram(IManagedPool<PushProgram> pool, IManagedPool<PooledList<Expression>> expressionListPool, int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      var code = RandomCode(maxPoints, expressionListPool, random, pushGpConfiguration, customExpressions);
+
+      return PushProgram.Create(pool, code);
+    }
+
+    public static PushProgram RandomProgram(IManagedPool<PooledList<Expression>> expressionListPool, int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      var code = RandomCode(maxPoints, expressionListPool, random, pushGpConfiguration, customExpressions);
+
+      return new PushProgram(code);
+    }
+
+    public static PushProgram RandomProgram(int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      var code = RandomCode(maxPoints, null, random, pushGpConfiguration, customExpressions);
+
+      return new PushProgram(code);
+    }
+
+    public static IReadOnlyList<Expression> RandomCode(
+      int maxPoints,
+      IManagedPool<PooledList<Expression>> expressionListPool = null,
+      IRandom random = null,
+      IReadOnlyPushConfiguration pushGpConfiguration = null,
+      IDictionary<string, Expression> customExpressions = null) {
+      if (maxPoints == 0)
+        return new Expression[0];
+
+      random = random ?? new FastRandom();
+      pushGpConfiguration = pushGpConfiguration ?? new PushConfiguration();
+
+      var size = maxPoints <= 1 ? 1 : random.Next(1, maxPoints);
+      var expressions = expressionListPool == null ? new List<Expression>(size) : expressionListPool.Get();
+
+      for (var i = 0; i < size; i++) {
+        var expression = random.NextDouble() <= pushGpConfiguration.ErcProbability
+         ? CreateRandomErcExpression(random, pushGpConfiguration)
+         : CreateExpression(random, pushGpConfiguration, customExpressions);
+
+        expressions.Add(expression);
+      }
+
+      return expressions;
+    }
+
+    private static Expression CreateExpression(IRandom random, IReadOnlyPushConfiguration pushGpConfiguration, IDictionary<string, Expression> customExpressions = null) {
+      var customCount = customExpressions == null ? 0 : customExpressions.Count - 1;
+      var index = random.Next(0, pushGpConfiguration.EnabledExpressions.Count + customCount - 1);
+
+      if ((index >= 0) && (index < pushGpConfiguration.EnabledExpressions.Count)) {
+        var name = pushGpConfiguration.EnabledExpressions[index];
+        return ExpressionTable.GetExpression(name);
+      }
+
+      if (customExpressions == null)
+        throw new IndexOutOfRangeException();
+
+      return customExpressions.ElementAt(index - (pushGpConfiguration.EnabledExpressions.Count - 1)).Value;
+    }
+
+    private static Expression CreateRandomErcExpression(IRandom random, IReadOnlyPushConfiguration pushGpConfiguration) {
+      var value = random.Next(0, 3);
+
+      switch (value) {
+        case 0:
+          return new IntegerPushExpression(random.Next(
+            pushGpConfiguration.MinRandomInteger,
+            pushGpConfiguration.MaxRandomInteger));
+
+        case 1:
+          return new FloatPushExpression(
+            random.NextDouble() *
+            (pushGpConfiguration.MaxRandomFloat - pushGpConfiguration.MinRandomFloat) +
+            pushGpConfiguration.MinRandomFloat);
+
+        case 2:
+          return new BooleanPushExpression(random.NextDouble() > 0.5);
+
+        case 3:
+          return new NamePushExpression(NameGenerator.RandomName(random));
+
+        default:
+          throw new NotImplementedException();
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/RecursiveCodeGenerator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/RecursiveCodeGenerator.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Generators/RecursiveCodeGenerator.cs	(revision 14777)
@@ -0,0 +1,113 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Generators {
+  using System;
+  using System.Collections.Generic;
+  using System.Linq;
+  using HeuristicLab.Core;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+  using HeuristicLab.Random;
+
+  /// <summary>
+  ///     The following is the standard Push random code generation algorithm, which is used for the CODE.RAND instruction.
+  ///     It may also be useful for the initialization of programs in evolutionary computation systems, and it is used for
+  ///     this purpose in PushGP.
+  ///     It produces a uniform distribution of sizes and what seems to be a reasonable distribution of shapes, in a
+  ///     reasonable amount of time.
+  /// </summary>
+  /// <see cref="http://faculty.hampshire.edu/lspector/push3-description.html#RandomCode" />
+  public class RecursiveCodeGenerator {
+
+    public static PushProgram RandomProgram(IManagedPool<PushProgram> pool, int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      var code = RandomCode(maxPoints, random, pushGpConfiguration, customExpressions);
+
+      return PushProgram.Create(pool, code.ToArray());
+    }
+
+    public static PushProgram RandomProgram(int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      var code = RandomCode(maxPoints, random, pushGpConfiguration, customExpressions);
+
+      return new PushProgram(code.ToArray());
+    }
+
+    public static IEnumerable<Expression> RandomCode(int maxPoints, IRandom random = null, IReadOnlyPushConfiguration pushGpConfiguration = null, IDictionary<string, Expression> customExpressions = null) {
+      if (maxPoints == 0)
+        return new Expression[0];
+
+      random = random ?? new FastRandom();
+      pushGpConfiguration = pushGpConfiguration ?? new PushConfiguration();
+
+      if (pushGpConfiguration.EnabledExpressions.Count == 0)
+        return new Expression[0];
+
+      var actualPoints = maxPoints == 1 ? 1 : random.Next(1, Math.Max(1, maxPoints));
+
+      return RandomCodeWithSize(actualPoints, random, pushGpConfiguration, customExpressions);
+    }
+
+    private static IEnumerable<Expression> RandomCodeWithSize(int points, IRandom random, IReadOnlyPushConfiguration pushGpConfiguration, IDictionary<string, Expression> customExpressions = null) {
+      if (points == 1) {
+
+        // check if erc expression should be taken
+        return random.NextDouble() <= pushGpConfiguration.ErcProbability
+          ? new[] { CreateRandomErcExpression(random, pushGpConfiguration) }
+          : new[] { CreateExpression(random, pushGpConfiguration, customExpressions) };
+      }
+
+      var maxParts = points - 1;
+
+      return Decompose(maxParts, maxParts, random)
+        .SelectMany(size => RandomCodeWithSize(size, random, pushGpConfiguration, customExpressions));
+    }
+
+    private static IEnumerable<int> Decompose(int number, int maxParts, IRandom random) {
+      if ((number == 1) || (maxParts == 1))
+        return new[] { number };
+
+      var thisPart = number == 2 ? 1 : random.Next(1, number - 1);
+
+      return new[] { thisPart }.Concat(Decompose(number - thisPart, maxParts - 1, random));
+    }
+
+    private static Expression CreateExpression(IRandom random, IReadOnlyPushConfiguration pushGpConfiguration, IDictionary<string, Expression> customExpressions = null) {
+      var customCount = customExpressions == null ? 0 : customExpressions.Count - 1;
+      var index = random.Next(0, pushGpConfiguration.EnabledExpressions.Count + customCount - 1);
+
+      if ((index >= 0) && (index < pushGpConfiguration.EnabledExpressions.Count)) {
+        var name = pushGpConfiguration.EnabledExpressions[index];
+        return ExpressionTable.GetExpression(name);
+      }
+
+      if (customExpressions == null)
+        throw new IndexOutOfRangeException();
+
+      return customExpressions.ElementAt(index - (pushGpConfiguration.EnabledExpressions.Count - 1)).Value;
+    }
+
+    private static Expression CreateRandomErcExpression(IRandom random, IReadOnlyPushConfiguration pushGpConfiguration) {
+      var value = random.Next(0, 3);
+
+      switch (value) {
+        case 0:
+          return new IntegerPushExpression(random.Next(
+            pushGpConfiguration.MinRandomInteger,
+            pushGpConfiguration.MaxRandomInteger));
+
+        case 1:
+          return new FloatPushExpression(
+            random.NextDouble() *
+            (pushGpConfiguration.MaxRandomFloat - pushGpConfiguration.MinRandomFloat) +
+            pushGpConfiguration.MinRandomFloat);
+
+        case 2:
+          return new BooleanPushExpression(random.NextDouble() > 0.5);
+
+        case 3:
+          return new NamePushExpression(NameGenerator.RandomName(random));
+
+        default:
+          throw new NotImplementedException();
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/IPushInterpreter.cs	(revision 14777)
@@ -20,10 +20,12 @@
     IStack<long> IntegerStack { get; }
     IStack<double> FloatStack { get; }
+    IStack<char> CharStack { get; }
+    IStack<string> StringStack { get; }
 
     IDictionary<string, Expression> CustomExpressions { get; }
 
-    IReadonlyPushConfiguration Configuration { get; }
+    IReadOnlyPushConfiguration Configuration { get; }
 
-    IManagedPool<PushProgram> PushProgramPool { get; }
+    InterpreterPoolContainer PoolContainer { get; }
 
     bool IsNameQuoteFlagSet { get; set; }
@@ -32,6 +34,4 @@
     void Run(string code, bool stepwise = false);
     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));
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/InterpreterPoolContainer.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/InterpreterPoolContainer.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/InterpreterPoolContainer.cs	(revision 14777)
@@ -0,0 +1,84 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
+  using System;
+  using System.Collections.Generic;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+
+  public class InterpreterPoolContainer {
+    private readonly ManagedPoolProvider<PushProgram> pushProgramPoolProvider;
+    private readonly ManagedPoolProvider<LoopState> loopStatePoolProvider;
+    private readonly ManagedPoolProvider<PooledList<Expression>> expressionListPoolProvider;
+
+    private readonly IDictionary<Type, ManagedPoolProvider<Expression>> statefulExpressionPoolProviders
+      = new Dictionary<Type, ManagedPoolProvider<Expression>>();
+
+    private readonly IDictionary<Type, IManagedPool<Expression>> statefulExpressionPools
+      = new Dictionary<Type, IManagedPool<Expression>>();
+
+    public InterpreterPoolContainer(int partitionSize = 512, int maxPartitionCount = 1024) {
+      pushProgramPoolProvider = new ManagedPoolProvider<PushProgram>(partitionSize, () => new PushProgram(), maxPartitionCount);
+      loopStatePoolProvider = new ManagedPoolProvider<LoopState>(partitionSize, () => new LoopState(), maxPartitionCount);
+      expressionListPoolProvider = new ManagedPoolProvider<PooledList<Expression>>(partitionSize, () => new PooledList<Expression>(), maxPartitionCount);
+
+      InitStatefulExpressionPools();
+    }
+
+    public InterpreterPoolContainer(
+      ManagedPoolProvider<PushProgram> pushProgramPoolProvider,
+      ManagedPoolProvider<LoopState> loopStatePoolProvider,
+      ManagedPoolProvider<PooledList<Expression>> expressionListPoolProvider) {
+      this.pushProgramPoolProvider = pushProgramPoolProvider;
+      this.loopStatePoolProvider = loopStatePoolProvider;
+      this.expressionListPoolProvider = expressionListPoolProvider;
+
+      InitStatefulExpressionPools();
+    }
+
+    public IManagedPool<PushProgram> PushProgramPool { get; private set; }
+    public IManagedPool<LoopState> LoopStatePool { get; private set; }
+    public IManagedPool<PooledList<Expression>> ExpressionListPool { get; private set; }
+
+    private void InitStatefulExpressionPools() {
+      for (var i = 0; i < ExpressionTable.StatefulExpressionTypes.Length; i++) {
+        var type = ExpressionTable.StatefulExpressionTypes[i];
+        var name = ExpressionTable.TypeToNameTable[type];
+        var factory = ExpressionTable.StatefulExpressionFactory[name];
+
+        statefulExpressionPoolProviders.Add(type, new ManagedPoolProvider<Expression>(1024, factory));
+
+        statefulExpressionPools.Add(type, null);
+      }
+    }
+
+    public IManagedPool<Expression> GetStatefulExpressionPool<T, StateT>() where T : StatefulExpression<StateT> {
+      return statefulExpressionPools[typeof(T)];
+    }
+
+    public T GetStatefulExpression<T>() where T : Expression {
+      return (T)statefulExpressionPools[typeof(T)].Get();
+    }
+
+    public void CreatePools() {
+      PushProgramPool = pushProgramPoolProvider.CreatePool();
+      LoopStatePool = loopStatePoolProvider.CreatePool();
+      ExpressionListPool = expressionListPoolProvider.CreatePool();
+
+      for (var i = 0; i < ExpressionTable.StatefulExpressionTypes.Length; i++) {
+        var type = ExpressionTable.StatefulExpressionTypes[i];
+        statefulExpressionPools[type] = statefulExpressionPoolProviders[type].CreatePool();
+      }
+    }
+
+    public void DisposePools() {
+      if (PushProgramPool != null) PushProgramPool.Dispose();
+      if (LoopStatePool != null) LoopStatePool.Dispose();
+      if (ExpressionListPool != null) ExpressionListPool.Dispose();
+
+      for (var i = 0; i < ExpressionTable.StatefulExpressionTypes.Length; i++) {
+        var type = ExpressionTable.StatefulExpressionTypes[i];
+        if (statefulExpressionPools[type] != null) statefulExpressionPools[type].Dispose();
+      }
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PooledPushInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PooledPushInterpreter.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PooledPushInterpreter.cs	(revision 14777)
@@ -4,6 +4,4 @@
   using HeuristicLab.Core;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
 
   public class PooledPushInterpreter : PushInterpreter, IDisposable {
@@ -11,6 +9,6 @@
     private readonly PushInterpreterPool pool;
 
-    public PooledPushInterpreter(PushInterpreterPool pool, PushConfiguration config, ManagedPoolProvider<PushProgram> pushProgramPoolProvider, IRandom random = null)
-      : base(config, random, pushProgramPoolProvider) {
+    public PooledPushInterpreter(PushInterpreterPool pool, IReadOnlyPushConfiguration config, InterpreterPoolContainer poolContainer, IRandom random = null)
+      : base(config, random, poolContainer) {
       this.pool = pool;
     }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs	(revision 14777)
@@ -3,5 +3,4 @@
   using System.Collections.Generic;
 #if DEBUG
-  using System.Linq;
 #endif
   using System.Runtime.CompilerServices;
@@ -10,5 +9,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;
@@ -19,5 +17,6 @@
     private Task currentTask;
 
-    public PushInterpreter(IReadonlyPushConfiguration config = null, IRandom random = null, ManagedPoolProvider<PushProgram> pushProgramPoolProvider = null) {
+
+    public PushInterpreter(IReadOnlyPushConfiguration config = null, IRandom random = null, InterpreterPoolContainer poolContainer = null) {
       Random = random ?? new FastRandom();
 
@@ -43,16 +42,17 @@
         IsEnabled = Configuration.IsFloatStackEnabled
       };
+      CharStack = new PushStack<char> {
+        IsEnabled = Configuration.IsCharStackEnabled
+      };
+      StringStack = new PushStack<string> {
+        IsEnabled = Configuration.IsStringStackEnabled
+      };
 
       CustomExpressions = new Dictionary<string, Expression>();
 
-      PushProgramPoolProvider = pushProgramPoolProvider ?? new ManagedPoolProvider<PushProgram>(1024);
-
-      if (pushProgramPoolProvider == null)
-      {
-        PushProgramPoolProvider.InitDummyPartition(() => new PushProgram());
-      }
-    }
-
-    public PushInterpreter(int seed, IReadonlyPushConfiguration config = null)
+      PoolContainer = poolContainer ?? new InterpreterPoolContainer();
+    }
+
+    public PushInterpreter(int seed, IReadOnlyPushConfiguration config = null)
       : this(config, new FastRandom(seed)) {
     }
@@ -93,8 +93,7 @@
     }
 
-    private readonly ManagedPoolProvider<PushProgram> PushProgramPoolProvider;
-    public IManagedPool<PushProgram> PushProgramPool { get; private set; }
-
-    public IReadonlyPushConfiguration Configuration { get; protected set; }
+    public InterpreterPoolContainer PoolContainer { get; private set; }
+
+    public IReadOnlyPushConfiguration Configuration { get; protected set; }
 
     public IStack<Expression> CodeStack { get; private set; }
@@ -109,4 +108,6 @@
 
     public IStack<double> FloatStack { get; private set; }
+    public IStack<char> CharStack { get; private set; }
+    public IStack<string> StringStack { get; private set; }
 
     public IDictionary<string, Expression> CustomExpressions { get; private set; }
@@ -133,21 +134,21 @@
     }
 
-
     public void Run(Expression program, bool stepwise = false) {
-      using (PushProgramPool = PushProgramPoolProvider.CreatePool()) {
-        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();
-      }
+      PoolContainer.CreatePools();
+
+      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();
+
+      PoolContainer.DisposePools();
     }
 
@@ -157,5 +158,5 @@
       IsAborted = true;
 
-      if (PushProgramPool != null) PushProgramPool.Dispose();
+      PoolContainer.DisposePools();
 
       if (currentTask != null) await currentTask;
@@ -213,8 +214,9 @@
       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);
+      if (CustomExpressions.Count > 0) {
+        Console.WriteLine("--------- Custom Expressions ---------");
+        foreach (var ce in CustomExpressions) {
+          Console.WriteLine("{0}: {1}", ce.Key, ce.Value);
+        }
       }
     }
@@ -272,10 +274,10 @@
       var expression = ExecStack.Pop();
 
-      if (ExecStack.Any(e => e == null)) {
-        throw new InvalidProgramException();
-      }
+      //if (ExecStack.Any(e => e == null)) {
+      //  throw new InvalidProgramException();
+      //}
 
       var succ = expression.Eval(this);
-      last = expression;
+      //last = expression;
 
       return succ;
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreterPool.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreterPool.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreterPool.cs	(revision 14777)
@@ -9,22 +9,30 @@
   public class PushInterpreterPool {
     private readonly ObjectPool<PooledPushInterpreter> pool;
-    private ManagedPoolProvider<PushProgram> pushProgramPoolProvider;
 
-    public PushInterpreterPool(PushConfiguration config = null)
+    public readonly ManagedPoolProvider<PushProgram> PushProgramPoolProvider;
+    public readonly ManagedPoolProvider<LoopState> LoopStatePoolProvider;
+    public readonly ManagedPoolProvider<PooledList<Expression>> ExpressionListPoolProvider;
+
+
+    public PushInterpreterPool(IReadOnlyPushConfiguration config = null)
       : this(Environment.ProcessorCount * 2, 1024, null, config) {
     }
 
-    public PushInterpreterPool(int size, int pushProgramPoolPartitionSize, int? maxPartitionCount = null, PushConfiguration config = null) {
+    public PushInterpreterPool(int size, int pushProgramPoolPartitionSize, int? maxPartitionCount = null, IReadOnlyPushConfiguration config = null) {
       PushGpConfiguration = config ?? new PushConfiguration();
 
-      pushProgramPoolProvider = new ManagedPoolProvider<PushProgram>(pushProgramPoolPartitionSize, maxPartitionCount);
-      pushProgramPoolProvider.InitDummyPartition(() => new PushProgram());
+      PushProgramPoolProvider = new ManagedPoolProvider<PushProgram>(pushProgramPoolPartitionSize, () => new PushProgram(), maxPartitionCount);
+      LoopStatePoolProvider = new ManagedPoolProvider<LoopState>(pushProgramPoolPartitionSize, () => new LoopState(), maxPartitionCount);
+      ExpressionListPoolProvider = new ManagedPoolProvider<PooledList<Expression>>(pushProgramPoolPartitionSize * 2, () => new PooledList<Expression>(), maxPartitionCount);
 
-      pool = new ObjectPool<PooledPushInterpreter>(() => new PooledPushInterpreter(this, PushGpConfiguration, pushProgramPoolProvider), size);
+      pool = new ObjectPool<PooledPushInterpreter>(() => {
+        var poolContainer = new InterpreterPoolContainer(PushProgramPoolProvider, LoopStatePoolProvider, ExpressionListPoolProvider);
+        return new PooledPushInterpreter(this, PushGpConfiguration, poolContainer);
+      }, size);
     }
 
-    public PushConfiguration PushGpConfiguration { get; private set; }
+    public IReadOnlyPushConfiguration PushGpConfiguration { get; private set; }
 
-    public PooledPushInterpreter GetInstance(IRandom random = null) {
+    public PooledPushInterpreter Create(IRandom random = null) {
       var interpreter = this.pool.Allocate();
       interpreter.Random = random ?? new FastRandom();
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Parser/PushParser.cs	(revision 14777)
@@ -16,5 +16,5 @@
     private static readonly char[] symbolTrim = { '\r', '\n' };
 
-    public static PushProgram Parse(string source, int startIndex = 0) {
+    public static Expression Parse(string source, int startIndex = 0) {
       var symbols = source.Split(delimiter);
 
@@ -23,5 +23,11 @@
     }
 
-    private static PushProgram Parse(string[] symbols, int startIndex, out int endIndex) {
+    public static PushProgram ParseProgram(string source, int startIndex = 0) {
+      var expression = Parse(source, startIndex);
+
+      return expression as PushProgram ?? new PushProgram(new[] { expression });
+    }
+
+    private static Expression Parse(string[] symbols, int startIndex, out int endIndex) {
       var expressions = new List<Expression>();
 
@@ -39,5 +45,5 @@
           case closeBrace:
             endIndex = i;
-            return new PushProgram(expressions.ToArray());
+            return new PushProgram(expressions);
         }
 
@@ -51,5 +57,5 @@
         // expression
         if (ExpressionTable.TryGetStatelessExpression(symbol, out expression)
-            || ExpressionTable.TryGetStatefullExpression(symbol, out expression)) {
+            || ExpressionTable.TryGetStatefulExpression(symbol, out expression)) {
           expressions.Insert(0, expression);
           continue;
@@ -62,5 +68,12 @@
       endIndex = symbols.Length - 1;
 
-      return new PushProgram(expressions.ToArray());
+      switch (expressions.Count) {
+        case 0:
+          return PushProgram.Empty;
+        case 1:
+          return expressions[0];
+        default:
+          return new PushProgram(expressions);
+      }
     }
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/DataBounds.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/DataBounds.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/DataBounds.cs	(revision 14777)
@@ -0,0 +1,55 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
+  using HeuristicLab.Common;
+  using HeuristicLab.Core;
+  using HeuristicLab.Data;
+  using HeuristicLab.Parameters;
+  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+  [StorableClass]
+  public class DataBounds : ParameterCollection {
+
+    private const string TrainingParameterName = "Training";
+    private const string TestParameterName = "Test";
+
+    public DataBounds() : this(0, 0, 0, 0) {
+    }
+
+    public DataBounds(int trainingStart, int trainingEnd, int testStart, int testEnd) {
+      Add(new FixedValueParameter<IntRange>(TrainingParameterName, new IntRange(trainingStart, trainingEnd)));
+      Add(new FixedValueParameter<IntRange>(TestParameterName, new IntRange(testStart, testEnd)));
+    }
+
+    [StorableConstructor]
+    public DataBounds(bool deserializing) : base(deserializing) {
+    }
+
+    public DataBounds(DataBounds origin, Cloner cloner) : base(origin, cloner) {
+    }
+
+    public IValueParameter<IntRange> TrainingParameter
+    {
+      get { return (IValueParameter<IntRange>)this[TrainingParameterName]; }
+    }
+
+    public IntRange TrainingRange
+    {
+      get { return TrainingParameter.Value; }
+      set { TrainingParameter.Value = value; }
+    }
+
+    public IValueParameter<IntRange> TestParameter
+    {
+      get { return (IValueParameter<IntRange>)this[TestParameterName]; }
+    }
+
+    public IntRange TestRange
+    {
+      get { return TestParameter.Value; }
+      set { TestParameter.Value = value; }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataBounds(this, cloner);
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEncoding.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEncoding.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEncoding.cs	(revision 14777)
@@ -3,5 +3,4 @@
 
 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
-  using System.Linq;
 
   using HeuristicLab.Common;
@@ -42,15 +41,10 @@
 
     public static PushProgram MapToPushProgram(this IntegerVector vector, IReadOnlyList<string> enabledExpressions) {
-      //var expressions = vector
-      //  .Select(i => ExpressionTable.GetExpression(enabledExpressions[i]))
-      //  .ToArray();
-
       var expressions = new Expression[vector.Length];
-      for (var i = 0; i < vector.Length; i++)
-      {
+      for (var i = 0; i < vector.Length; i++) {
         expressions[i] = ExpressionTable.GetExpression(enabledExpressions[vector[i]]);
       }
 
-      return new Expressions.PushProgram(expressions);
+      return new PushProgram(expressions);
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEvaluator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEvaluator.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushEvaluator.cs	(revision 14777)
@@ -0,0 +1,80 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
+  using HeuristicLab.BenchmarkSuite;
+  using HeuristicLab.BenchmarkSuite.Problems;
+  using HeuristicLab.Core;
+  using HeuristicLab.Optimization;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
+
+  public static class PushEvaluator {
+    public static double Evaluate(IPushInterpreter interpreter, PushProgram program, Example example, double worstResult) {
+      interpreter.BooleanStack.Push(example.InputBoolean);
+      interpreter.IntegerStack.Push(example.InputInt);
+      interpreter.FloatStack.Push(example.InputFloat);
+
+      interpreter.Run(program);
+
+      return GetDiff(example.OutputInt, interpreter.IntegerStack, worstResult, LongDiffer)
+           + GetDiff(example.OutputFloat, interpreter.FloatStack, worstResult, DoubleDiffer)
+           + GetDiff(example.OutputBoolean, interpreter.BooleanStack, worstResult, BooleanDiffer);
+    }
+
+    public static double Evaluate(PushProgram program, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
+      if (endIndex - startIndex <= 0) return default(double);
+      var result = 0d;
+
+      using (var interpreter = pool.Create(random)) {
+        for (var i = startIndex; i < endIndex; i++) {
+          result += Evaluate(interpreter, program, data.Examples[i], data.WorstResult);
+          interpreter.Clear();
+        }
+      }
+
+      return result / (endIndex - startIndex);
+    }
+
+    public static double Evaluate(Individual individual, PushInterpreterPool pool, IRandom random, Data data, int startIndex, int endIndex) {
+      var program = individual.PushProgram(pool.PushGpConfiguration.EnabledExpressions as IReadOnlyList<string>);
+      return Evaluate(program, pool, random, data, startIndex, endIndex);
+    }
+
+    private static double DoubleDiffer(double a, double b) {
+      var result = a - b;
+
+      return result == double.MinValue ? double.MaxValue : Math.Abs(result);
+    }
+
+    private static double LongDiffer(long a, long b) {
+      var result = a - b;
+
+      return result == long.MinValue ? long.MaxValue : Math.Abs(result);
+    }
+
+    private static double BooleanDiffer(bool a, bool b) {
+      return a && b ? 0 : a || b ? 1 : 2;
+    }
+
+    private static double GetDiff<T>(IReadOnlyList<T> estimated, IStack<T> resultStack, double worstResult, Func<T, T, double> differ)
+      where T : IComparable {
+
+      var count = Math.Min(estimated.Count, resultStack.Count);
+      var result = resultStack.Peek(count);
+      var comparableLength = Math.Min(estimated.Count, result.Length);
+      var diff = 0d;
+
+      for (var i = 0; i < comparableLength; i++) {
+        diff += Math.Min(differ(estimated[i], result[0]), worstResult);
+      }
+
+      if (estimated.Count > result.Length) {
+        diff += worstResult * (estimated.Count - comparableLength);
+      }
+
+      return diff;
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushProblem.cs	(revision 14777)
@@ -10,5 +10,8 @@
 
   using HeuristicLab.BenchmarkSuite;
+  using HeuristicLab.BenchmarkSuite.Problems;
   using HeuristicLab.Data;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
 
   using Instances;
@@ -17,17 +20,17 @@
   using Parameters;
   using Persistence.Default.CompositeSerializers.Storable;
-  using Stack;
 
   [StorableClass]
   [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 180)]
   [Item("Push Problem", "")]
-  public class PushProblem : SingleObjectiveBasicProblem<IntegerVectorEncoding>, IProblemInstanceConsumer<IBenchmarkSuiteDataDescriptor> {
+  public class PushProblem : SingleObjectiveBasicProblem<IntegerVectorEncoding>, IProblemInstanceConsumer<Data> {
     [Storable]
     private readonly PushConfiguration config;
     private PushInterpreterPool pool;
+    private IBenchmarkSuiteDataDescriptor dataDescriptor;
 
     public PushProblem() {
       config = new PushConfiguration();
-      pool = new PushInterpreterPool(10000, 1024, 65536, config);
+      pool = new PushInterpreterPool(10000, 4096, 65536, config);
 
       InitEvents();
@@ -98,20 +101,10 @@
     private const string MaxPointsInRandomInstructionParameterDescription = "MaxPointsInRandomInstruction";
     private const string DataBoundsParameterName = "DataBounds";
+    private const string MaxProgramDepthParameterName = "MaxProgramDepth";
+    private const string MaxProgramDepthParameterDescription = "";
 
     private void InitParameters() {
-      var bounds = new IntMatrix(1, 3, new[] { "Training Start", "Training End | Test Start", "Test End" });
-      bounds.ItemChanged += (s, e) => {
-        if (this.DataDescriptor == null)
-          return;
-
-        var max = this.DataDescriptor.OriginalTestCount + this.DataDescriptor.OriginalTrainingCount - 1;
-        bounds[0, 0] = Math.Min(Math.Max(bounds[0, 0], 0), max);
-        bounds[0, 2] = Math.Max(Math.Min(bounds[0, 2], max), 0);
-        bounds[0, 1] = Math.Min(Math.Max(bounds[0, 0], bounds[0, 1]), bounds[0, 2]);
-      };
-
-      Parameters.Add(new FixedValueParameter<IntMatrix>(
-        DataBoundsParameterName,
-        bounds));
+
+      Parameters.Add(new FixedValueParameter<DataBounds>(DataBoundsParameterName));
 
       Parameters.Add(new FixedValueParameter<IntValue>(
@@ -174,5 +167,13 @@
         new IntValue(config.MaxPointsInRandomExpression)) { Hidden = true });
 
-      Parameters.Add(new ValueParameter<IBenchmarkSuiteDataDescriptor>(DataParameterName, DataParameterDescription));
+      Parameters.Add(
+        new FixedValueParameter<IntValue>(
+          MaxProgramDepthParameterName,
+          MaxProgramDepthParameterDescription,
+          new IntValue(config.MaxDepth)));
+
+      Parameters.Add(new ValueParameter<Data>(
+        DataParameterName,
+        DataParameterDescription));
 
       Encoding.Bounds[0, 0] = 0;
@@ -181,10 +182,10 @@
     }
 
-    public IValueParameter<IntMatrix> DataBoundsParameter
-    {
-      get { return (IValueParameter<IntMatrix>)Parameters[DataBoundsParameterName]; }
-    }
-
-    public IntMatrix DataBounds
+    public IValueParameter<DataBounds> DataBoundsParameter
+    {
+      get { return (IValueParameter<DataBounds>)Parameters[DataBoundsParameterName]; }
+    }
+
+    public DataBounds DataBounds
     {
       get { return DataBoundsParameter.Value; }
@@ -204,10 +205,10 @@
     }
 
-    public IValueParameter<IBenchmarkSuiteDataDescriptor> DataParameter
-    {
-      get { return (IValueParameter<IBenchmarkSuiteDataDescriptor>)Parameters[DataParameterName]; }
-    }
-
-    public IBenchmarkSuiteDataDescriptor DataDescriptor
+    public IValueParameter<Data> DataParameter
+    {
+      get { return (IValueParameter<Data>)Parameters[DataParameterName]; }
+    }
+
+    public Data Data
     {
       get { return DataParameter.Value; }
@@ -217,5 +218,5 @@
     public IValueParameter<IntValue> EvalPushLimitParameter
     {
-      get { return (IValueParameter<IntValue>)this.Parameters[EvalPushLimitParameterName]; }
+      get { return (IValueParameter<IntValue>)Parameters[EvalPushLimitParameterName]; }
     }
 
@@ -227,4 +228,19 @@
         this.EvalPushLimitParameter.Value.Value = value;
         config.EvalPushLimit = value;
+      }
+    }
+
+    public IValueParameter<IntValue> MaxDepthParameter
+    {
+      get { return (IValueParameter<IntValue>)this.Parameters[MaxProgramDepthParameterName]; }
+    }
+
+    public int MaxDepth
+    {
+      get { return config.MaxDepth; }
+      set
+      {
+        this.MaxDepthParameter.Value.Value = value;
+        config.MaxDepth = value;
       }
     }
@@ -394,5 +410,5 @@
       var bestIdx = Array.IndexOf(qualities, bestQuality);
       var bestIndividual = individuals[bestIdx];
-      var solution = new PushSolution(bestIndividual.IntegerVector(), bestQuality, DataDescriptor, random, config);
+      var solution = new PushSolution(bestIndividual.IntegerVector(), bestQuality, Data, random, config, DataBounds.TrainingRange.Start, DataBounds.TrainingRange.End);
 
       if (!results.ContainsKey(bestSolutionResultName)) {
@@ -404,72 +420,33 @@
 
     public override double Evaluate(Individual individual, IRandom random) {
-      if (DataBounds[0, 1] <= 0) return default(double);
-
-      var program = individual.PushProgram(config.EnabledExpressions as IReadOnlyList<string>);
-      var result = 0d;
-
-      using (var interpreter = pool.GetInstance(random)) {
-        for (var i = DataBounds[0, 0]; i < DataBounds[0, 1]; i++) {
-          var example = DataDescriptor.Examples[i];
-
-          interpreter.BooleanStack.Push(example.InputBoolean);
-          interpreter.IntegerStack.Push(example.InputInt);
-          interpreter.FloatStack.Push(example.InputFloat);
-
-          interpreter.Run(program);
-
-          result += GetDiff(example.OutputInt, interpreter.IntegerStack, DataDescriptor.WorstResult, LongDiffer)
-                  + GetDiff(example.OutputFloat, interpreter.FloatStack, DataDescriptor.WorstResult, DoubleDiffer)
-                  + GetDiff(example.OutputBoolean, interpreter.BooleanStack, DataDescriptor.WorstResult, BooleanDiffer);
-
-          interpreter.Clear();
-        }
-      }
-
-      return result / DataBounds[0, 1];
-    }
-
-    private static double DoubleDiffer(double a, double b) {
-      var result = a - b;
-
-      return result == double.MinValue ? double.MaxValue : Math.Abs(result);
-    }
-
-    private static double LongDiffer(long a, long b) {
-      var result = a - b;
-
-      return result == long.MinValue ? long.MaxValue : Math.Abs(result);
-    }
-
-    private static double BooleanDiffer(bool a, bool b) {
-      return a && b ? 0 : a || b ? 1 : 2;
-    }
-
-    private static double GetDiff<T>(IReadOnlyList<T> estimated, IStack<T> resultStack, double worstResult, Func<T, T, double> differ)
-      where T : IComparable {
-
-      var count = Math.Min(estimated.Count, resultStack.Count);
-      var result = resultStack.Peek(count);
-      var comparableLength = Math.Min(estimated.Count, result.Length);
-      var diff = 0d;
-
-      for (var i = 0; i < comparableLength; i++) {
-        diff += Math.Min(differ(estimated[i], result[0]), worstResult);
-      }
-
-      if (estimated.Count > result.Length) {
-        diff += worstResult * (estimated.Count - comparableLength);
-      }
-
-      return diff;
-    }
-
-    public void Load(IBenchmarkSuiteDataDescriptor descriptor) {
-      this.DataDescriptor = descriptor;
-      BestKnownQuality = descriptor.BestResult;
-
-      DataBounds[0, 0] = 0;
-      DataBounds[0, 2] = this.DataDescriptor.OriginalTrainingCount + this.DataDescriptor.OriginalTestCount;
-      DataBounds[0, 1] = this.DataDescriptor.OriginalTrainingCount;
+      return PushEvaluator.Evaluate(individual, pool, random, Data, DataBounds.TrainingRange.Start, DataBounds.TrainingRange.End);
+    }
+
+    public void Load(Data data) {
+      Data = data;
+      BestKnownQuality = data.BestResult;
+      MaxProgramLength = data.MaxSize;
+      EvalPushLimit = data.EvalLimit;
+
+      config.EnabledExpressions = (IList<string>)ExpressionTable.GetEnabledExpressionsByStackTypes((StackTypes)data.EnabledDataTypes);
+
+      // update enabled stack types
+      foreach (var stackType in ExpressionTable.StackTypeToNamesTable.Keys) {
+        var enabledStackExpressions = config.EnabledExpressions.Intersect(ExpressionTable.StackTypeToNamesTable[stackType]);
+        config.SetStack(stackType, enabledStackExpressions.Any());
+      }
+
+      Encoding.Bounds[0, 0] = 0;
+      Encoding.Bounds[0, 1] = config.EnabledExpressions.Count - 1;
+      Encoding.Length = config.MaxPointsInProgram;
+
+      // TODO
+      // data.MaxGenerations
+      // data.ProgEvalBudget
+
+      DataBounds.TrainingRange.Start = 0;
+      DataBounds.TrainingRange.End = Data.OriginalTrainingCount - 1;
+      DataBounds.TestRange.Start = Data.OriginalTrainingCount;
+      DataBounds.TestRange.End = Data.OriginalTrainingCount + Data.OriginalTestCount;
     }
   }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushSolution.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushSolution.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Problem/PushSolution.cs	(revision 14777)
@@ -1,11 +1,9 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Problem {
-  using HeuristicLab.BenchmarkSuite;
+  using HeuristicLab.BenchmarkSuite.Problems;
   using HeuristicLab.Common;
   using HeuristicLab.Core;
   using HeuristicLab.Encodings.IntegerVectorEncoding;
-  using HeuristicLab.Optimization;
   using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
 
   [StorableClass]
@@ -16,30 +14,37 @@
     public readonly IntegerVector IntegerVector;
     [Storable]
-    public readonly IBenchmarkSuiteDataDescriptor DataDescriptor;
+    public readonly Data Data;
     [Storable]
     public readonly IRandom Random;
     [Storable]
-    public readonly IReadonlyPushConfiguration Config;
+    public readonly IReadOnlyPushConfiguration Config;
+    [Storable]
+    public readonly int DataStart;
+    [Storable]
+    public readonly int DataEnd;
 
-    public PushSolution(IntegerVector integerVector, double quality, IBenchmarkSuiteDataDescriptor dataDescriptor, IRandom random, IReadonlyPushConfiguration config)
+    public PushSolution(IntegerVector integerVector, double quality, Data data, IRandom random, IReadOnlyPushConfiguration config, int dataStart, int dataEnd)
       : base("Solution", "A push solution.") {
       IntegerVector = integerVector;
       Quality = quality;
-      DataDescriptor = dataDescriptor;
+      Data = data;
       Random = random;
       Config = config;
+      DataStart = dataStart;
+      DataEnd = dataEnd;
     }
 
     public PushSolution(PushSolution origin, Cloner cloner) : base(origin, cloner) {
-      IntegerVector = origin.IntegerVector;
+      IntegerVector = cloner.Clone(origin.IntegerVector);
       Quality = origin.Quality;
+      Data = cloner.Clone(origin.Data);
+      Random = cloner.Clone(origin.Random);
+      Config = cloner.Clone(origin.Config);
+      DataStart = origin.DataStart;
+      DataEnd = origin.DataEnd;
     }
 
     [StorableConstructor]
     private PushSolution(bool deserializing) : base(deserializing) { }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/PushEvalutator.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/PushEvalutator.cs	(revision 14747)
+++ 	(revision )
@@ -1,12 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.Problems.PushGP.ProgramSynthesis {
-
-  public class PushEvalutator {
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/PushProgram.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/PushProgram.cs	(revision 14747)
+++ 	(revision )
@@ -1,58 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-
-namespace HeuristicLab.Problems.PushGP.ProgramSynthesis {
-  using System.Drawing;
-
-  using HeuristicLab.Algorithms.PushGP.Expressions;
-  using HeuristicLab.Common;
-  using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-  public class PushProgram : ExecExpandExpression, ISymbolicExpressionTree {
-    public PushProgram(Expression[] state)
-      : base(state) {
-    }
-
-    public PushProgram(ExecExpandExpression origin)
-      : base(origin) {
-    }
-
-    public object Clone() {
-      throw new NotImplementedException();
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      throw new NotImplementedException();
-    }
-
-    public string ItemName { get; private set; }
-
-    public string ItemDescription { get; private set; }
-
-    public Version ItemVersion { get; private set; }
-
-    public Image ItemImage { get; private set; }
-
-    public event EventHandler ItemImageChanged;
-
-    public event EventHandler ToStringChanged;
-
-    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesBreadth() {
-      throw new NotImplementedException();
-    }
-
-    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesPrefix() {
-      throw new NotImplementedException();
-    }
-
-    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesPostfix() {
-      throw new NotImplementedException();
-    }
-
-    public ISymbolicExpressionTreeNode Root { get; set; }
-
-    public int Length { get { return this.State.Length; } }
-
-    public new int Depth { get { return base.Depth; } }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/ISimplifier.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/ISimplifier.cs	(revision 14747)
+++ 	(revision )
@@ -1,10 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier {
-  using System;
-
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-  using HeuristicLab.Core;
-
-  public interface ISimplifier {
-    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 14747)
+++ 	(revision )
@@ -1,58 +1,0 @@
-﻿//namespace HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier {
-//  using System;
-//  using HeuristicLab.Core;
-//  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-
-//  public class RandomSimplifier : ISimplifier {
-//    public int Trys { get; set; }
-
-//    public PushProgram Simplify(PushProgram program, IRandom random, Predicate<PushProgram> isBetter) {
-
-//      if (program.TotalCount == 1) {
-//        return isBetter(PushProgram.Empty) ? PushProgram.Empty : program;
-//      }
-
-//      var copy = program.Copy();
-//      var maxTries = Math.Min(Trys, program.TotalCount - 2);
-//      var successfulRemoves = 0;
-
-//      for (var i = 0; i < maxTries; i++) {
-//        var rndIndex = random.Next(1, program.TotalCount - 1 - successfulRemoves);
-//        var node = copy.GetFromTree(
-//          rndIndex,
-//          (super, parent, child, childIndex, parentIndex) => new {
-//            Super = super,
-//            Parent = parent,
-//            ChildIndex = childIndex,
-//            ParentIndex = parentIndex
-//          });
-
-//        var oldParentExpressions = node.Parent.State;
-//        var newParentExpressions = RemoveAt(oldParentExpressions, node.ChildIndex);
-//        var newParent = new PushProgram(newParentExpressions);
-
-//        var superExpressions = node.Super == null ? copy.State : node.Super.State;
-//        superExpressions[node.ParentIndex] = newParent;
-
-//        if (isBetter(copy)) {
-//          successfulRemoves++;
-//        } else {
-//          superExpressions[node.ParentIndex] = node.Parent;
-//        }
-//      }
-
-//      return copy;
-//    }
-
-//    private static T[] RemoveAt<T>(T[] source, int index) {
-//      var dest = new T[source.Length - 1];
-//      if (index > 0)
-//        Array.Copy(source, 0, dest, 0, index);
-
-//      if (index < source.Length - 1)
-//        Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
-
-//      return dest;
-//    }
-//  }
-//}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/Simplifier.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/Simplifier.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Simplifier/Simplifier.cs	(revision 14777)
@@ -0,0 +1,42 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier {
+  using System;
+
+  using Expressions;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Tree;
+
+  public static class Simplifier {
+    private static readonly TreeNode<Expression> NoopNode =
+      new TreeNode<Expression>(ExpressionTable.GetStatelessExpression<CodeNoopExpression>());
+
+    public static PushProgram Simplify(PushProgram program, Func<PushProgram, double> evaluator) {
+      var bestResult = evaluator(program);
+      var tree = program.ToTree();
+      var optimizedTree = RemoveUnnecessaryExpressions(tree, tree, ref bestResult, evaluator);
+
+      return optimizedTree.ToPushProgram(e => !ReferenceEquals(e, NoopNode.Value));
+    }
+
+    private static TreeNode<Expression> RemoveUnnecessaryExpressions(Tree<Expression> program, TreeNode<Expression> node, ref double bestResult, Func<PushProgram, double> evaluator) {
+      for (var i = 0; i < node.Children.Count; i++) {
+        var child = node.Children[i];
+        node.ReplaceNode(i, NoopNode);
+
+        var currentProgram = program.ToPushProgram();
+        var currentResult = evaluator(currentProgram);
+
+        if (currentResult <= bestResult) {
+          bestResult = currentResult;
+        } else if (child.Value.IsProgram) {
+          node.ReplaceNode(i, child);
+          var subProgram = RemoveUnnecessaryExpressions(program, child, ref bestResult, evaluator);
+          node.ReplaceNode(i, subProgram);
+        } else {
+          node.ReplaceNode(i, child);
+        }
+      }
+
+      return node;
+    }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IStack.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IStack.cs	(revision 14777)
@@ -22,9 +22,9 @@
 
     void Push(T item);
+    void Push(T item1, T item2);
+    void Push(T item1, T item2, T item3);
+    void Push(T item1, T item2, T item3, T item4);
 
-    void Push(params T[] items);
-    void ReversePush(params T[] items);
-
-    void Push(IReadOnlyList<T> items);
+    void Push(IReadOnlyList<T> items, int startIndex = 0);
 
     T Peek();
@@ -35,8 +35,4 @@
 
     void Insert(int index, T item);
-
-    void Insert(int index, params T[] items);
-
-    void Insert(int index, IEnumerable<T> items);
 
     T ReverseElementAt(int offset);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs	(revision 14777)
@@ -33,5 +33,5 @@
       get
       {
-        return this.data.Capacity;
+        return data.Capacity;
       }
     }
@@ -41,5 +41,5 @@
       get
       {
-        return this.data[this.Count - 1];
+        return data[Count - 1];
       }
     }
@@ -49,5 +49,5 @@
       get
       {
-        return this.Count > 0 ? this.data[this.Count - 1] : default(T);
+        return Count > 0 ? Top : default(T);
       }
     }
@@ -57,5 +57,5 @@
       get
       {
-        return this.data[0];
+        return data[0];
       }
     }
@@ -65,5 +65,5 @@
       get
       {
-        return this.Count > 0 ? this.data[0] : default(T);
+        return Count > 0 ? Bottom : default(T);
       }
     }
@@ -73,5 +73,5 @@
       get
       {
-        return this.data.Count;
+        return data.Count;
       }
     }
@@ -81,5 +81,5 @@
       get
       {
-        return this.Count == 0;
+        return Count == 0;
       }
     }
@@ -94,33 +94,33 @@
 
     public void Add(T item) {
-      this.Push(item);
+      Push(item);
     }
 
     public void Clear() {
-      this.data.Clear();
+      data.Clear();
     }
 
     public bool Contains(T item) {
-      return this.data.Contains(item);
+      return data.Contains(item);
     }
 
     public void CopyTo(T[] array, int arrayIndex) {
-      this.data.CopyTo(array, arrayIndex);
+      data.CopyTo(array, arrayIndex);
     }
 
     public IEnumerator<T> GetEnumerator() {
-      return this.data.GetEnumerator();
+      return data.GetEnumerator();
     }
 
     public T ElementAt(int index) {
-      return this.data[index];
+      return data[index];
     }
 
     public T ReverseElementAt(int offset) {
-      return this.data[this.data.Count - 1 - offset];
+      return data[data.Count - 1 - offset];
     }
 
     public void SetTop(T value) {
-      this.data[this.Count - 1] = value;
+      data[Count - 1] = value;
     }
 
@@ -129,32 +129,32 @@
       get
       {
-        return this.data[key];
+        return data[key];
       }
       set
       {
-        this.data[key] = value;
+        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;
+      var top = Top;
+      var bottomIndex = Count - count;
+
+      for (var i = Count - 1; i > bottomIndex; i--) data[i] = data[i - 1];
+
+      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);
+      if (index == Count - 1) return;
+
+      var item = ElementAt(index);
+      data.RemoveAt(index);
+      data.Add(item);
     }
 
     public T Pop() {
-      var value = this.data[this.Count - 1];
-      this.data.RemoveAt(this.Count - 1);
+      var value = data[Count - 1];
+      data.RemoveAt(Count - 1);
 
       return value;
@@ -163,5 +163,5 @@
     public T[] Pop(int count) {
       var items = Peek(count);
-      this.Remove(count);
+      Remove(count);
 
       return items;
@@ -173,8 +173,8 @@
 
     public T[] Peek(int count) {
-      var startIndex = this.Count - count;
+      var startIndex = Count - count;
 
       var items = new T[count];
-      this.data.CopyTo(startIndex, items, 0, count);
+      data.CopyTo(startIndex, items, 0, count);
 
       return items;
@@ -184,5 +184,29 @@
       if (!IsEnabled) return;
 
-      this.data.Add(item);
+      data.Add(item);
+    }
+
+    public void Push(T item1, T item2) {
+      if (!IsEnabled) return;
+
+      data.Add(item1);
+      data.Add(item2);
+    }
+
+    public void Push(T item1, T item2, T item3) {
+      if (!IsEnabled) return;
+
+      data.Add(item1);
+      data.Add(item2);
+      data.Add(item3);
+    }
+
+    public void Push(T item1, T item2, T item3, T item4) {
+      if (!IsEnabled) return;
+
+      data.Add(item1);
+      data.Add(item2);
+      data.Add(item3);
+      data.Add(item4);
     }
 
@@ -190,29 +214,17 @@
       if (!IsEnabled) return;
 
-      var startIndex = this.Count - count;
+      var startIndex = 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);
+      data.CopyTo(startIndex, items, 0, count);
+      Remove(count - 1);
+
+      data[Count - 1] = templateFunc(items);
+    }
+
+    public void Push(IReadOnlyList<T> items, int startIndex = 0) {
+      if (!IsEnabled) return;
+
+      for (var i = startIndex; i < items.Count; i++) data.Add(items[i]);
     }
 
@@ -220,47 +232,30 @@
       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);
+      data.Insert(index, item);
     }
 
     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;
+      return this.data.Remove(item);
     }
 
     public void RemoveTop() {
-      this.data.RemoveAt(this.Count - 1);
+      data.RemoveAt(Count - 1);
     }
 
     public void Remove(int count) {
-      for (var i = 0; i < count; i++) this.data.RemoveAt(this.Count - 1);
+      this.data.RemoveRange(this.Count - count, count);
     }
 
     public void RemoveAt(int index) {
-      this.data.RemoveAt(index);
+      data.RemoveAt(index);
     }
 
     public void RemoveAt(int index, int count) {
-      this.data.RemoveRange(index, count);
+      data.RemoveRange(index, count);
     }
 
     public bool TryPop(out T item) {
-      if (this.Count > 0) {
-        item = this.Pop();
+      if (Count > 0) {
+        item = Pop();
         return true;
       }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackType.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackType.cs	(revision 14747)
+++ 	(revision )
@@ -1,10 +1,0 @@
-﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
-  public enum StackType : byte {
-    Integer,
-    Float,
-    Boolean,
-    Name,
-    Code,
-    Exec,
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs	(revision 14777)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs	(revision 14777)
@@ -0,0 +1,16 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
+  using System;
+
+  [Flags]
+  public enum StackTypes : ushort {
+    None = 0x00, // Required to specify expression dependencies
+    Integer = 0x02,
+    Float = 0x04,
+    Char = 0x08,
+    String = 0x10,
+    Boolean = 0x20,
+    Name = 0x40,
+    Code = 0x80,
+    Exec = 0x100,
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.cs	(revision 14777)
@@ -43,13 +43,13 @@
 
     private void ExpressionsTreeViewAfterCheck(object sender, TreeViewEventArgs e) {
-      var isStackNode = e.Node.Tag is StackType;
+      var isStackNode = e.Node.Tag is StackTypes;
 
       if (isStackNode) {
         if (e.Node.Checked) {
-          Content.EnableStack((StackType)e.Node.Tag);
+          Content.EnableStack((StackTypes)e.Node.Tag);
           foreach (var subNode in e.Node.Nodes.Cast<TreeNode>())
             subNode.Checked = true;
         } else {
-          Content.DisableStack((StackType)e.Node.Tag);
+          Content.DisableStack((StackTypes)e.Node.Tag);
           foreach (var subNode in e.Node.Nodes.Cast<TreeNode>())
             subNode.Checked = false;
@@ -71,4 +71,6 @@
       }
 
+      this.nameTextBox.Text = "Push Expression Selection";
+
       var treeNodes = GetTreeNodes(Content.EnabledExpressions).ToArray();
       expressionsTreeView.Nodes.AddRange(treeNodes);
@@ -79,5 +81,5 @@
         var stackTreeNode = new TreeNode {
           Tag = stackType,
-          Text = Enum.GetName(typeof(StackType), stackType),
+          Text = Enum.GetName(typeof(StackTypes), stackType),
         };
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.resx
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.resx	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/ExpressionSelectionView.resx	(revision 14777)
@@ -68,9 +68,9 @@
             <xsd:complexType>
               <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+                <xsd:element name="value" types="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute name="name" use="required" types="xsd:string" />
+              <xsd:attribute name="types" types="xsd:string" />
+              <xsd:attribute name="mimetypes" types="xsd:string" />
               <xsd:attribute ref="xml:space" />
             </xsd:complexType>
@@ -78,6 +78,6 @@
           <xsd:element name="assembly">
             <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="alias" types="xsd:string" />
+              <xsd:attribute name="name" types="xsd:string" />
             </xsd:complexType>
           </xsd:element>
@@ -85,10 +85,10 @@
             <xsd:complexType>
               <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+                <xsd:element name="value" types="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" types="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute name="name" types="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="types" types="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetypes" types="xsd:string" msdata:Ordinal="4" />
               <xsd:attribute ref="xml:space" />
             </xsd:complexType>
@@ -97,7 +97,7 @@
             <xsd:complexType>
               <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="value" types="xsd:string" minOccurs="0" msdata:Ordinal="1" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
+              <xsd:attribute name="name" types="xsd:string" use="required" />
             </xsd:complexType>
           </xsd:element>
@@ -118,8 +118,8 @@
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="errorProvider.TrayLocation" types="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
-  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="toolTip.TrayLocation" types="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>140, 17</value>
   </metadata>
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.Designer.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.Designer.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.Designer.cs	(revision 14777)
@@ -25,33 +25,60 @@
     private void InitializeComponent() {
       System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PushProgramDebuggerView));
-      this.execGroupBox = new System.Windows.Forms.GroupBox();
-      this.execList = new System.Windows.Forms.ListView();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.simplifyButton = new System.Windows.Forms.Button();
+      this.skipNoopsCheckBox = new System.Windows.Forms.CheckBox();
+      this.runButton = new System.Windows.Forms.Button();
+      this.stepWidthBox = new System.Windows.Forms.NumericUpDown();
+      this.resetButton = new System.Windows.Forms.Button();
+      this.stepButton = new System.Windows.Forms.Button();
+      this.exampleComboBox = new System.Windows.Forms.ComboBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.debugTableLayout = new System.Windows.Forms.TableLayoutPanel();
+      this.codeGroupBox = new System.Windows.Forms.GroupBox();
+      this.codeList = new System.Windows.Forms.ListBox();
+      this.nameGroupBox = new System.Windows.Forms.GroupBox();
+      this.nameList = new System.Windows.Forms.ListBox();
       this.integerGroupBox = new System.Windows.Forms.GroupBox();
       this.integerList = new System.Windows.Forms.ListBox();
       this.floatGroupBox = new System.Windows.Forms.GroupBox();
+      this.groupBox2 = new System.Windows.Forms.GroupBox();
+      this.listBox2 = new System.Windows.Forms.ListBox();
       this.floatList = new System.Windows.Forms.ListBox();
-      this.codeGroupBox = new System.Windows.Forms.GroupBox();
-      this.codeList = new System.Windows.Forms.ListBox();
+      this.execGroupBox = new System.Windows.Forms.GroupBox();
+      this.execList = new System.Windows.Forms.ListView();
       this.booleanGroupBox = new System.Windows.Forms.GroupBox();
+      this.groupBox4 = new System.Windows.Forms.GroupBox();
+      this.listBox3 = new System.Windows.Forms.ListBox();
       this.booleanList = new System.Windows.Forms.ListBox();
-      this.nameGroupBox = new System.Windows.Forms.GroupBox();
-      this.nameList = new System.Windows.Forms.ListBox();
-      this.stepButton = new System.Windows.Forms.Button();
-      this.resetButton = new System.Windows.Forms.Button();
-      this.label1 = new System.Windows.Forms.Label();
-      this.exampleComboBox = new System.Windows.Forms.ComboBox();
-      this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
-      this.stepWidthBox = new System.Windows.Forms.NumericUpDown();
-      this.runButton = new System.Windows.Forms.Button();
-      this.skipNoopsCheckBox = new System.Windows.Forms.CheckBox();
+      this.stringGroupBox = new System.Windows.Forms.GroupBox();
+      this.groupBox6 = new System.Windows.Forms.GroupBox();
+      this.listBox5 = new System.Windows.Forms.ListBox();
+      this.stringList = new System.Windows.Forms.ListBox();
+      this.charGroupBox = new System.Windows.Forms.GroupBox();
+      this.groupBox8 = new System.Windows.Forms.GroupBox();
+      this.listBox7 = new System.Windows.Forms.ListBox();
+      this.charList = new System.Windows.Forms.ListBox();
+      this.tabPage2 = new System.Windows.Forms.TabPage();
+      this.resultsDataGrid = new System.Windows.Forms.DataGridView();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
-      this.execGroupBox.SuspendLayout();
+      this.tabControl.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.stepWidthBox)).BeginInit();
+      this.debugTableLayout.SuspendLayout();
+      this.codeGroupBox.SuspendLayout();
+      this.nameGroupBox.SuspendLayout();
       this.integerGroupBox.SuspendLayout();
       this.floatGroupBox.SuspendLayout();
-      this.codeGroupBox.SuspendLayout();
+      this.groupBox2.SuspendLayout();
+      this.execGroupBox.SuspendLayout();
       this.booleanGroupBox.SuspendLayout();
-      this.nameGroupBox.SuspendLayout();
-      this.tableLayoutPanel1.SuspendLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.stepWidthBox)).BeginInit();
+      this.groupBox4.SuspendLayout();
+      this.stringGroupBox.SuspendLayout();
+      this.groupBox6.SuspendLayout();
+      this.charGroupBox.SuspendLayout();
+      this.groupBox8.SuspendLayout();
+      this.tabPage2.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.resultsDataGrid)).BeginInit();
       this.SuspendLayout();
       //
@@ -60,233 +87,76 @@
       this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
       this.errorProvider.SetIconPadding(this.nameTextBox, 2);
-      this.nameTextBox.Size = new System.Drawing.Size(890, 20);
+      this.nameTextBox.Size = new System.Drawing.Size(1176, 20);
       //
       // infoLabel
       //
-      this.infoLabel.Location = new System.Drawing.Point(954, 3);
-      //
-      // execGroupBox
-      //
-      this.execGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.execGroupBox.Controls.Add(this.execList);
-      this.execGroupBox.Location = new System.Drawing.Point(3, 3);
-      this.execGroupBox.Name = "execGroupBox";
-      this.execGroupBox.Size = new System.Drawing.Size(244, 633);
-      this.execGroupBox.TabIndex = 3;
-      this.execGroupBox.TabStop = false;
-      this.execGroupBox.Text = "Exec";
-      //
-      // execList
-      //
-      this.execList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.execList.Location = new System.Drawing.Point(3, 16);
-      this.execList.Name = "execList";
-      this.execList.Size = new System.Drawing.Size(235, 605);
-      this.execList.TabIndex = 1;
-      this.execList.UseCompatibleStateImageBehavior = false;
-      this.execList.View = System.Windows.Forms.View.List;
-      this.execList.VirtualMode = true;
-      //
-      // integerGroupBox
-      //
-      this.integerGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.integerGroupBox.Controls.Add(this.integerList);
-      this.integerGroupBox.Location = new System.Drawing.Point(628, 3);
-      this.integerGroupBox.Name = "integerGroupBox";
-      this.integerGroupBox.Size = new System.Drawing.Size(119, 633);
-      this.integerGroupBox.TabIndex = 4;
-      this.integerGroupBox.TabStop = false;
-      this.integerGroupBox.Text = "Integer";
-      //
-      // integerList
-      //
-      this.integerList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.integerList.FormattingEnabled = true;
-      this.integerList.HorizontalScrollbar = true;
-      this.integerList.Location = new System.Drawing.Point(6, 19);
-      this.integerList.Name = "integerList";
-      this.integerList.SelectionMode = System.Windows.Forms.SelectionMode.None;
-      this.integerList.Size = new System.Drawing.Size(107, 602);
-      this.integerList.TabIndex = 3;
-      //
-      // floatGroupBox
-      //
-      this.floatGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.floatGroupBox.Controls.Add(this.floatList);
-      this.floatGroupBox.Location = new System.Drawing.Point(753, 3);
-      this.floatGroupBox.Name = "floatGroupBox";
-      this.floatGroupBox.Size = new System.Drawing.Size(119, 633);
-      this.floatGroupBox.TabIndex = 5;
-      this.floatGroupBox.TabStop = false;
-      this.floatGroupBox.Text = "Float";
-      //
-      // floatList
-      //
-      this.floatList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.floatList.FormattingEnabled = true;
-      this.floatList.HorizontalScrollbar = true;
-      this.floatList.Location = new System.Drawing.Point(6, 19);
-      this.floatList.Name = "floatList";
-      this.floatList.SelectionMode = System.Windows.Forms.SelectionMode.None;
-      this.floatList.Size = new System.Drawing.Size(107, 602);
-      this.floatList.TabIndex = 4;
-      //
-      // codeGroupBox
-      //
-      this.codeGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.codeGroupBox.Controls.Add(this.codeList);
-      this.codeGroupBox.Location = new System.Drawing.Point(253, 3);
-      this.codeGroupBox.Name = "codeGroupBox";
-      this.codeGroupBox.Size = new System.Drawing.Size(244, 633);
-      this.codeGroupBox.TabIndex = 5;
-      this.codeGroupBox.TabStop = false;
-      this.codeGroupBox.Text = "Code";
-      //
-      // codeList
-      //
-      this.codeList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.codeList.FormattingEnabled = true;
-      this.codeList.HorizontalScrollbar = true;
-      this.codeList.Location = new System.Drawing.Point(7, 19);
-      this.codeList.Name = "codeList";
-      this.codeList.SelectionMode = System.Windows.Forms.SelectionMode.None;
-      this.codeList.Size = new System.Drawing.Size(231, 602);
-      this.codeList.TabIndex = 1;
-      //
-      // booleanGroupBox
-      //
-      this.booleanGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.booleanGroupBox.Controls.Add(this.booleanList);
-      this.booleanGroupBox.Location = new System.Drawing.Point(878, 3);
-      this.booleanGroupBox.Name = "booleanGroupBox";
-      this.booleanGroupBox.Size = new System.Drawing.Size(119, 633);
-      this.booleanGroupBox.TabIndex = 5;
-      this.booleanGroupBox.TabStop = false;
-      this.booleanGroupBox.Text = "Boolean";
-      //
-      // booleanList
-      //
-      this.booleanList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.booleanList.FormattingEnabled = true;
-      this.booleanList.HorizontalScrollbar = true;
-      this.booleanList.Location = new System.Drawing.Point(6, 19);
-      this.booleanList.Name = "booleanList";
-      this.booleanList.SelectionMode = System.Windows.Forms.SelectionMode.None;
-      this.booleanList.Size = new System.Drawing.Size(107, 602);
-      this.booleanList.TabIndex = 5;
-      //
-      // nameGroupBox
-      //
-      this.nameGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.nameGroupBox.Controls.Add(this.nameList);
-      this.nameGroupBox.Location = new System.Drawing.Point(503, 3);
-      this.nameGroupBox.Name = "nameGroupBox";
-      this.nameGroupBox.Size = new System.Drawing.Size(119, 633);
-      this.nameGroupBox.TabIndex = 5;
-      this.nameGroupBox.TabStop = false;
-      this.nameGroupBox.Text = "Name";
-      //
-      // nameList
-      //
-      this.nameList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.nameList.FormattingEnabled = true;
-      this.nameList.HorizontalScrollbar = true;
-      this.nameList.Location = new System.Drawing.Point(6, 19);
-      this.nameList.Name = "nameList";
-      this.nameList.SelectionMode = System.Windows.Forms.SelectionMode.None;
-      this.nameList.Size = new System.Drawing.Size(107, 602);
-      this.nameList.TabIndex = 2;
-      //
-      // stepButton
-      //
-      this.stepButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.stepButton.Image = ((System.Drawing.Image)(resources.GetObject("stepButton.Image")));
-      this.stepButton.Location = new System.Drawing.Point(112, 698);
-      this.stepButton.Name = "stepButton";
-      this.stepButton.Size = new System.Drawing.Size(28, 26);
-      this.stepButton.TabIndex = 6;
-      this.toolTip.SetToolTip(this.stepButton, "Step");
-      this.stepButton.UseVisualStyleBackColor = true;
-      //
-      // resetButton
-      //
-      this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.resetButton.Image = ((System.Drawing.Image)(resources.GetObject("resetButton.Image")));
-      this.resetButton.Location = new System.Drawing.Point(6, 698);
-      this.resetButton.Name = "resetButton";
-      this.resetButton.Size = new System.Drawing.Size(28, 26);
-      this.resetButton.TabIndex = 7;
-      this.toolTip.SetToolTip(this.resetButton, "Reset to start");
-      this.resetButton.UseVisualStyleBackColor = true;
-      //
-      // label1
-      //
-      this.label1.AutoSize = true;
-      this.label1.Location = new System.Drawing.Point(3, 29);
-      this.label1.Name = "label1";
-      this.label1.Size = new System.Drawing.Size(50, 13);
-      this.label1.TabIndex = 8;
-      this.label1.Text = "Example:";
-      //
-      // exampleComboBox
-      //
-      this.exampleComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.exampleComboBox.FormattingEnabled = true;
-      this.exampleComboBox.Location = new System.Drawing.Point(58, 26);
-      this.exampleComboBox.Name = "exampleComboBox";
-      this.exampleComboBox.Size = new System.Drawing.Size(890, 21);
-      this.exampleComboBox.TabIndex = 9;
-      //
-      // tableLayoutPanel1
-      //
-      this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.tableLayoutPanel1.AutoScroll = true;
-      this.tableLayoutPanel1.ColumnCount = 7;
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 125F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 125F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 125F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 125F));
-      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 36F));
-      this.tableLayoutPanel1.Controls.Add(this.codeGroupBox, 1, 0);
-      this.tableLayoutPanel1.Controls.Add(this.nameGroupBox, 2, 0);
-      this.tableLayoutPanel1.Controls.Add(this.integerGroupBox, 3, 0);
-      this.tableLayoutPanel1.Controls.Add(this.floatGroupBox, 4, 0);
-      this.tableLayoutPanel1.Controls.Add(this.booleanGroupBox, 5, 0);
-      this.tableLayoutPanel1.Controls.Add(this.execGroupBox, 0, 0);
-      this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 53);
-      this.tableLayoutPanel1.Name = "tableLayoutPanel1";
-      this.tableLayoutPanel1.RowCount = 1;
-      this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
-      this.tableLayoutPanel1.Size = new System.Drawing.Size(1036, 639);
-      this.tableLayoutPanel1.TabIndex = 1;
+      this.infoLabel.Location = new System.Drawing.Point(1259, 3);
+      //
+      // tabControl
+      //
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.tabPage1);
+      this.tabControl.Controls.Add(this.tabPage2);
+      this.tabControl.Location = new System.Drawing.Point(6, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(1269, 698);
+      this.tabControl.TabIndex = 12;
+      //
+      // tabPage1
+      //
+      this.tabPage1.Controls.Add(this.simplifyButton);
+      this.tabPage1.Controls.Add(this.skipNoopsCheckBox);
+      this.tabPage1.Controls.Add(this.runButton);
+      this.tabPage1.Controls.Add(this.stepWidthBox);
+      this.tabPage1.Controls.Add(this.resetButton);
+      this.tabPage1.Controls.Add(this.stepButton);
+      this.tabPage1.Controls.Add(this.exampleComboBox);
+      this.tabPage1.Controls.Add(this.label1);
+      this.tabPage1.Controls.Add(this.debugTableLayout);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(1261, 672);
+      this.tabPage1.TabIndex = 0;
+      this.tabPage1.Text = "Debug";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      //
+      // simplifyButton
+      //
+      this.simplifyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.simplifyButton.Location = new System.Drawing.Point(237, 640);
+      this.simplifyButton.Name = "simplifyButton";
+      this.simplifyButton.Size = new System.Drawing.Size(62, 26);
+      this.simplifyButton.TabIndex = 17;
+      this.simplifyButton.Text = "Simplify";
+      this.toolTip.SetToolTip(this.simplifyButton, "Run all instructions");
+      this.simplifyButton.UseVisualStyleBackColor = true;
+      //
+      // skipNoopsCheckBox
+      //
+      this.skipNoopsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.skipNoopsCheckBox.AutoSize = true;
+      this.skipNoopsCheckBox.Checked = true;
+      this.skipNoopsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.skipNoopsCheckBox.Location = new System.Drawing.Point(150, 646);
+      this.skipNoopsCheckBox.Name = "skipNoopsCheckBox";
+      this.skipNoopsCheckBox.Size = new System.Drawing.Size(81, 17);
+      this.skipNoopsCheckBox.TabIndex = 16;
+      this.skipNoopsCheckBox.Text = "Skip NOOP";
+      this.skipNoopsCheckBox.UseVisualStyleBackColor = true;
+      //
+      // runButton
+      //
+      this.runButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.runButton.Image = ((System.Drawing.Image)(resources.GetObject("runButton.Image")));
+      this.runButton.Location = new System.Drawing.Point(40, 640);
+      this.runButton.Name = "runButton";
+      this.runButton.Size = new System.Drawing.Size(28, 26);
+      this.runButton.TabIndex = 15;
+      this.toolTip.SetToolTip(this.runButton, "Run all instructions");
+      this.runButton.UseVisualStyleBackColor = true;
       //
       // stepWidthBox
@@ -294,5 +164,5 @@
       this.stepWidthBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
       this.stepWidthBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.stepWidthBox.Location = new System.Drawing.Point(73, 699);
+      this.stepWidthBox.Location = new System.Drawing.Point(73, 641);
       this.stepWidthBox.Maximum = new decimal(new int[] {
             99999,
@@ -307,5 +177,5 @@
       this.stepWidthBox.Name = "stepWidthBox";
       this.stepWidthBox.Size = new System.Drawing.Size(40, 24);
-      this.stepWidthBox.TabIndex = 2;
+      this.stepWidthBox.TabIndex = 12;
       this.stepWidthBox.Value = new decimal(new int[] {
             1,
@@ -314,27 +184,418 @@
             0});
       //
-      // runButton
-      //
-      this.runButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.runButton.Image = ((System.Drawing.Image)(resources.GetObject("runButton.Image")));
-      this.runButton.Location = new System.Drawing.Point(40, 698);
-      this.runButton.Name = "runButton";
-      this.runButton.Size = new System.Drawing.Size(28, 26);
-      this.runButton.TabIndex = 10;
-      this.toolTip.SetToolTip(this.runButton, "Run all instructions");
-      this.runButton.UseVisualStyleBackColor = true;
-      //
-      // skipNoopsCheckBox
-      //
-      this.skipNoopsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.skipNoopsCheckBox.AutoSize = true;
-      this.skipNoopsCheckBox.Checked = true;
-      this.skipNoopsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.skipNoopsCheckBox.Location = new System.Drawing.Point(150, 704);
-      this.skipNoopsCheckBox.Name = "skipNoopsCheckBox";
-      this.skipNoopsCheckBox.Size = new System.Drawing.Size(81, 17);
-      this.skipNoopsCheckBox.TabIndex = 11;
-      this.skipNoopsCheckBox.Text = "Skip NOOP";
-      this.skipNoopsCheckBox.UseVisualStyleBackColor = true;
+      // resetButton
+      //
+      this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.resetButton.Image = ((System.Drawing.Image)(resources.GetObject("resetButton.Image")));
+      this.resetButton.Location = new System.Drawing.Point(6, 640);
+      this.resetButton.Name = "resetButton";
+      this.resetButton.Size = new System.Drawing.Size(28, 26);
+      this.resetButton.TabIndex = 14;
+      this.toolTip.SetToolTip(this.resetButton, "Reset to start");
+      this.resetButton.UseVisualStyleBackColor = true;
+      //
+      // stepButton
+      //
+      this.stepButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.stepButton.Image = ((System.Drawing.Image)(resources.GetObject("stepButton.Image")));
+      this.stepButton.Location = new System.Drawing.Point(112, 640);
+      this.stepButton.Name = "stepButton";
+      this.stepButton.Size = new System.Drawing.Size(28, 26);
+      this.stepButton.TabIndex = 13;
+      this.toolTip.SetToolTip(this.stepButton, "Step");
+      this.stepButton.UseVisualStyleBackColor = true;
+      //
+      // exampleComboBox
+      //
+      this.exampleComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.exampleComboBox.FormattingEnabled = true;
+      this.exampleComboBox.Location = new System.Drawing.Point(58, 6);
+      this.exampleComboBox.Name = "exampleComboBox";
+      this.exampleComboBox.Size = new System.Drawing.Size(1165, 21);
+      this.exampleComboBox.TabIndex = 11;
+      //
+      // label1
+      //
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 9);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(50, 13);
+      this.label1.TabIndex = 10;
+      this.label1.Text = "Example:";
+      //
+      // debugTableLayout
+      //
+      this.debugTableLayout.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.debugTableLayout.AutoScroll = true;
+      this.debugTableLayout.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+      this.debugTableLayout.ColumnCount = 9;
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 270F));
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 270F));
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.debugTableLayout.Controls.Add(this.codeGroupBox, 1, 0);
+      this.debugTableLayout.Controls.Add(this.nameGroupBox, 2, 0);
+      this.debugTableLayout.Controls.Add(this.integerGroupBox, 3, 0);
+      this.debugTableLayout.Controls.Add(this.floatGroupBox, 4, 0);
+      this.debugTableLayout.Controls.Add(this.execGroupBox, 0, 0);
+      this.debugTableLayout.Controls.Add(this.booleanGroupBox, 5, 0);
+      this.debugTableLayout.Controls.Add(this.stringGroupBox, 6, 0);
+      this.debugTableLayout.Controls.Add(this.charGroupBox, 7, 0);
+      this.debugTableLayout.Location = new System.Drawing.Point(6, 33);
+      this.debugTableLayout.Name = "debugTableLayout";
+      this.debugTableLayout.RowCount = 1;
+      this.debugTableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle());
+      this.debugTableLayout.Size = new System.Drawing.Size(1259, 601);
+      this.debugTableLayout.TabIndex = 2;
+      //
+      // codeGroupBox
+      //
+      this.codeGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.codeGroupBox.Controls.Add(this.codeList);
+      this.codeGroupBox.Location = new System.Drawing.Point(273, 3);
+      this.codeGroupBox.Name = "codeGroupBox";
+      this.codeGroupBox.Size = new System.Drawing.Size(264, 595);
+      this.codeGroupBox.TabIndex = 5;
+      this.codeGroupBox.TabStop = false;
+      this.codeGroupBox.Text = "Code";
+      //
+      // codeList
+      //
+      this.codeList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.codeList.FormattingEnabled = true;
+      this.codeList.HorizontalScrollbar = true;
+      this.codeList.Location = new System.Drawing.Point(7, 19);
+      this.codeList.Name = "codeList";
+      this.codeList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.codeList.Size = new System.Drawing.Size(251, 563);
+      this.codeList.TabIndex = 1;
+      //
+      // nameGroupBox
+      //
+      this.nameGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.nameGroupBox.Controls.Add(this.nameList);
+      this.nameGroupBox.Location = new System.Drawing.Point(543, 3);
+      this.nameGroupBox.Name = "nameGroupBox";
+      this.nameGroupBox.Size = new System.Drawing.Size(119, 595);
+      this.nameGroupBox.TabIndex = 5;
+      this.nameGroupBox.TabStop = false;
+      this.nameGroupBox.Text = "Name";
+      //
+      // nameList
+      //
+      this.nameList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.nameList.FormattingEnabled = true;
+      this.nameList.HorizontalScrollbar = true;
+      this.nameList.Location = new System.Drawing.Point(6, 19);
+      this.nameList.Name = "nameList";
+      this.nameList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.nameList.Size = new System.Drawing.Size(107, 563);
+      this.nameList.TabIndex = 2;
+      //
+      // integerGroupBox
+      //
+      this.integerGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.integerGroupBox.Controls.Add(this.integerList);
+      this.integerGroupBox.Location = new System.Drawing.Point(668, 3);
+      this.integerGroupBox.Name = "integerGroupBox";
+      this.integerGroupBox.Size = new System.Drawing.Size(119, 595);
+      this.integerGroupBox.TabIndex = 4;
+      this.integerGroupBox.TabStop = false;
+      this.integerGroupBox.Text = "Integer";
+      //
+      // integerList
+      //
+      this.integerList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.integerList.FormattingEnabled = true;
+      this.integerList.HorizontalScrollbar = true;
+      this.integerList.Location = new System.Drawing.Point(6, 19);
+      this.integerList.Name = "integerList";
+      this.integerList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.integerList.Size = new System.Drawing.Size(107, 563);
+      this.integerList.TabIndex = 3;
+      //
+      // floatGroupBox
+      //
+      this.floatGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.floatGroupBox.Controls.Add(this.groupBox2);
+      this.floatGroupBox.Controls.Add(this.floatList);
+      this.floatGroupBox.Location = new System.Drawing.Point(793, 3);
+      this.floatGroupBox.Name = "floatGroupBox";
+      this.floatGroupBox.Size = new System.Drawing.Size(119, 595);
+      this.floatGroupBox.TabIndex = 5;
+      this.floatGroupBox.TabStop = false;
+      this.floatGroupBox.Text = "Float";
+      //
+      // groupBox2
+      //
+      this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBox2.Controls.Add(this.listBox2);
+      this.groupBox2.Location = new System.Drawing.Point(1003, 3);
+      this.groupBox2.Name = "groupBox2";
+      this.groupBox2.Size = new System.Drawing.Size(253, 595);
+      this.groupBox2.TabIndex = 6;
+      this.groupBox2.TabStop = false;
+      this.groupBox2.Text = "Float";
+      //
+      // listBox2
+      //
+      this.listBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.listBox2.FormattingEnabled = true;
+      this.listBox2.HorizontalScrollbar = true;
+      this.listBox2.Location = new System.Drawing.Point(6, 19);
+      this.listBox2.Name = "listBox2";
+      this.listBox2.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.listBox2.Size = new System.Drawing.Size(107, 563);
+      this.listBox2.TabIndex = 4;
+      //
+      // floatList
+      //
+      this.floatList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.floatList.FormattingEnabled = true;
+      this.floatList.HorizontalScrollbar = true;
+      this.floatList.Location = new System.Drawing.Point(6, 19);
+      this.floatList.Name = "floatList";
+      this.floatList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.floatList.Size = new System.Drawing.Size(107, 563);
+      this.floatList.TabIndex = 4;
+      //
+      // execGroupBox
+      //
+      this.execGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.execGroupBox.Controls.Add(this.execList);
+      this.execGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.execGroupBox.Name = "execGroupBox";
+      this.execGroupBox.Size = new System.Drawing.Size(264, 595);
+      this.execGroupBox.TabIndex = 3;
+      this.execGroupBox.TabStop = false;
+      this.execGroupBox.Text = "Exec";
+      //
+      // execList
+      //
+      this.execList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.execList.Location = new System.Drawing.Point(3, 16);
+      this.execList.Name = "execList";
+      this.execList.Size = new System.Drawing.Size(255, 571);
+      this.execList.TabIndex = 1;
+      this.execList.UseCompatibleStateImageBehavior = false;
+      this.execList.View = System.Windows.Forms.View.List;
+      this.execList.VirtualMode = true;
+      //
+      // booleanGroupBox
+      //
+      this.booleanGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.booleanGroupBox.Controls.Add(this.groupBox4);
+      this.booleanGroupBox.Controls.Add(this.booleanList);
+      this.booleanGroupBox.Location = new System.Drawing.Point(918, 3);
+      this.booleanGroupBox.Name = "booleanGroupBox";
+      this.booleanGroupBox.Size = new System.Drawing.Size(119, 595);
+      this.booleanGroupBox.TabIndex = 7;
+      this.booleanGroupBox.TabStop = false;
+      this.booleanGroupBox.Text = "Boolean";
+      //
+      // groupBox4
+      //
+      this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBox4.Controls.Add(this.listBox3);
+      this.groupBox4.Location = new System.Drawing.Point(1003, 3);
+      this.groupBox4.Name = "groupBox4";
+      this.groupBox4.Size = new System.Drawing.Size(253, 595);
+      this.groupBox4.TabIndex = 6;
+      this.groupBox4.TabStop = false;
+      this.groupBox4.Text = "Float";
+      //
+      // listBox3
+      //
+      this.listBox3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.listBox3.FormattingEnabled = true;
+      this.listBox3.HorizontalScrollbar = true;
+      this.listBox3.Location = new System.Drawing.Point(6, 19);
+      this.listBox3.Name = "listBox3";
+      this.listBox3.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.listBox3.Size = new System.Drawing.Size(107, 563);
+      this.listBox3.TabIndex = 4;
+      //
+      // booleanList
+      //
+      this.booleanList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.booleanList.FormattingEnabled = true;
+      this.booleanList.HorizontalScrollbar = true;
+      this.booleanList.Location = new System.Drawing.Point(6, 19);
+      this.booleanList.Name = "booleanList";
+      this.booleanList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.booleanList.Size = new System.Drawing.Size(107, 563);
+      this.booleanList.TabIndex = 4;
+      //
+      // stringGroupBox
+      //
+      this.stringGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.stringGroupBox.Controls.Add(this.groupBox6);
+      this.stringGroupBox.Controls.Add(this.stringList);
+      this.stringGroupBox.Location = new System.Drawing.Point(1043, 3);
+      this.stringGroupBox.Name = "stringGroupBox";
+      this.stringGroupBox.Size = new System.Drawing.Size(120, 595);
+      this.stringGroupBox.TabIndex = 8;
+      this.stringGroupBox.TabStop = false;
+      this.stringGroupBox.Text = "String";
+      //
+      // groupBox6
+      //
+      this.groupBox6.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBox6.Controls.Add(this.listBox5);
+      this.groupBox6.Location = new System.Drawing.Point(1003, 3);
+      this.groupBox6.Name = "groupBox6";
+      this.groupBox6.Size = new System.Drawing.Size(254, 595);
+      this.groupBox6.TabIndex = 6;
+      this.groupBox6.TabStop = false;
+      this.groupBox6.Text = "Float";
+      //
+      // listBox5
+      //
+      this.listBox5.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.listBox5.FormattingEnabled = true;
+      this.listBox5.HorizontalScrollbar = true;
+      this.listBox5.Location = new System.Drawing.Point(6, 19);
+      this.listBox5.Name = "listBox5";
+      this.listBox5.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.listBox5.Size = new System.Drawing.Size(108, 563);
+      this.listBox5.TabIndex = 4;
+      //
+      // stringList
+      //
+      this.stringList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.stringList.FormattingEnabled = true;
+      this.stringList.HorizontalScrollbar = true;
+      this.stringList.Location = new System.Drawing.Point(6, 19);
+      this.stringList.Name = "stringList";
+      this.stringList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.stringList.Size = new System.Drawing.Size(108, 563);
+      this.stringList.TabIndex = 4;
+      //
+      // charGroupBox
+      //
+      this.charGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.charGroupBox.Controls.Add(this.groupBox8);
+      this.charGroupBox.Controls.Add(this.charList);
+      this.charGroupBox.Location = new System.Drawing.Point(1169, 3);
+      this.charGroupBox.Name = "charGroupBox";
+      this.charGroupBox.Size = new System.Drawing.Size(119, 595);
+      this.charGroupBox.TabIndex = 9;
+      this.charGroupBox.TabStop = false;
+      this.charGroupBox.Text = "Char";
+      //
+      // groupBox8
+      //
+      this.groupBox8.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBox8.Controls.Add(this.listBox7);
+      this.groupBox8.Location = new System.Drawing.Point(1003, 3);
+      this.groupBox8.Name = "groupBox8";
+      this.groupBox8.Size = new System.Drawing.Size(253, 595);
+      this.groupBox8.TabIndex = 6;
+      this.groupBox8.TabStop = false;
+      this.groupBox8.Text = "Float";
+      //
+      // listBox7
+      //
+      this.listBox7.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.listBox7.FormattingEnabled = true;
+      this.listBox7.HorizontalScrollbar = true;
+      this.listBox7.Location = new System.Drawing.Point(6, 19);
+      this.listBox7.Name = "listBox7";
+      this.listBox7.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.listBox7.Size = new System.Drawing.Size(107, 563);
+      this.listBox7.TabIndex = 4;
+      //
+      // charList
+      //
+      this.charList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.charList.FormattingEnabled = true;
+      this.charList.HorizontalScrollbar = true;
+      this.charList.Location = new System.Drawing.Point(6, 19);
+      this.charList.Name = "charList";
+      this.charList.SelectionMode = System.Windows.Forms.SelectionMode.None;
+      this.charList.Size = new System.Drawing.Size(107, 563);
+      this.charList.TabIndex = 4;
+      //
+      // tabPage2
+      //
+      this.tabPage2.Controls.Add(this.resultsDataGrid);
+      this.tabPage2.Location = new System.Drawing.Point(4, 22);
+      this.tabPage2.Name = "tabPage2";
+      this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage2.Size = new System.Drawing.Size(1261, 672);
+      this.tabPage2.TabIndex = 1;
+      this.tabPage2.Text = "Results";
+      this.tabPage2.UseVisualStyleBackColor = true;
+      //
+      // resultsDataGrid
+      //
+      this.resultsDataGrid.AllowUserToAddRows = false;
+      this.resultsDataGrid.AllowUserToDeleteRows = false;
+      this.resultsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.resultsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.resultsDataGrid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
+      this.resultsDataGrid.Location = new System.Drawing.Point(7, 7);
+      this.resultsDataGrid.Name = "resultsDataGrid";
+      this.resultsDataGrid.ReadOnly = true;
+      this.resultsDataGrid.Size = new System.Drawing.Size(1248, 659);
+      this.resultsDataGrid.TabIndex = 0;
       //
       // PushProgramDebuggerView
@@ -342,34 +603,31 @@
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.Controls.Add(this.skipNoopsCheckBox);
-      this.Controls.Add(this.runButton);
-      this.Controls.Add(this.stepWidthBox);
-      this.Controls.Add(this.tableLayoutPanel1);
-      this.Controls.Add(this.exampleComboBox);
-      this.Controls.Add(this.label1);
-      this.Controls.Add(this.resetButton);
-      this.Controls.Add(this.stepButton);
+      this.Controls.Add(this.tabControl);
       this.Name = "PushProgramDebuggerView";
-      this.Size = new System.Drawing.Size(1058, 727);
-      this.Controls.SetChildIndex(this.stepButton, 0);
-      this.Controls.SetChildIndex(this.resetButton, 0);
-      this.Controls.SetChildIndex(this.label1, 0);
-      this.Controls.SetChildIndex(this.exampleComboBox, 0);
-      this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
+      this.Size = new System.Drawing.Size(1278, 727);
+      this.Controls.SetChildIndex(this.tabControl, 0);
       this.Controls.SetChildIndex(this.nameLabel, 0);
       this.Controls.SetChildIndex(this.nameTextBox, 0);
       this.Controls.SetChildIndex(this.infoLabel, 0);
-      this.Controls.SetChildIndex(this.stepWidthBox, 0);
-      this.Controls.SetChildIndex(this.runButton, 0);
-      this.Controls.SetChildIndex(this.skipNoopsCheckBox, 0);
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
-      this.execGroupBox.ResumeLayout(false);
+      this.tabControl.ResumeLayout(false);
+      this.tabPage1.ResumeLayout(false);
+      this.tabPage1.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.stepWidthBox)).EndInit();
+      this.debugTableLayout.ResumeLayout(false);
+      this.codeGroupBox.ResumeLayout(false);
+      this.nameGroupBox.ResumeLayout(false);
       this.integerGroupBox.ResumeLayout(false);
       this.floatGroupBox.ResumeLayout(false);
-      this.codeGroupBox.ResumeLayout(false);
+      this.groupBox2.ResumeLayout(false);
+      this.execGroupBox.ResumeLayout(false);
       this.booleanGroupBox.ResumeLayout(false);
-      this.nameGroupBox.ResumeLayout(false);
-      this.tableLayoutPanel1.ResumeLayout(false);
-      ((System.ComponentModel.ISupportInitialize)(this.stepWidthBox)).EndInit();
+      this.groupBox4.ResumeLayout(false);
+      this.stringGroupBox.ResumeLayout(false);
+      this.groupBox6.ResumeLayout(false);
+      this.charGroupBox.ResumeLayout(false);
+      this.groupBox8.ResumeLayout(false);
+      this.tabPage2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.resultsDataGrid)).EndInit();
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -379,24 +637,41 @@
     #endregion
 
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage tabPage1;
+    private System.Windows.Forms.CheckBox skipNoopsCheckBox;
+    private System.Windows.Forms.Button runButton;
+    private System.Windows.Forms.NumericUpDown stepWidthBox;
+    private System.Windows.Forms.Button resetButton;
+    private System.Windows.Forms.Button stepButton;
+    private System.Windows.Forms.ComboBox exampleComboBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TableLayoutPanel debugTableLayout;
+    private System.Windows.Forms.GroupBox codeGroupBox;
+    private System.Windows.Forms.ListBox codeList;
+    private System.Windows.Forms.GroupBox nameGroupBox;
+    private System.Windows.Forms.ListBox nameList;
+    private System.Windows.Forms.GroupBox integerGroupBox;
+    private System.Windows.Forms.ListBox integerList;
+    private System.Windows.Forms.GroupBox floatGroupBox;
+    private System.Windows.Forms.ListBox floatList;
     private System.Windows.Forms.GroupBox execGroupBox;
-    private System.Windows.Forms.GroupBox integerGroupBox;
-    private System.Windows.Forms.GroupBox floatGroupBox;
-    private System.Windows.Forms.GroupBox codeGroupBox;
+    private System.Windows.Forms.ListView execList;
+    private System.Windows.Forms.TabPage tabPage2;
+    private System.Windows.Forms.DataGridView resultsDataGrid;
+    private System.Windows.Forms.Button simplifyButton;
+    private System.Windows.Forms.GroupBox stringGroupBox;
+    private System.Windows.Forms.GroupBox groupBox6;
+    private System.Windows.Forms.ListBox listBox5;
+    private System.Windows.Forms.ListBox stringList;
     private System.Windows.Forms.GroupBox booleanGroupBox;
-    private System.Windows.Forms.GroupBox nameGroupBox;
-    private System.Windows.Forms.ListBox integerList;
-    private System.Windows.Forms.ListBox floatList;
-    private System.Windows.Forms.ListBox codeList;
+    private System.Windows.Forms.GroupBox groupBox4;
+    private System.Windows.Forms.ListBox listBox3;
     private System.Windows.Forms.ListBox booleanList;
-    private System.Windows.Forms.ListBox nameList;
-    private System.Windows.Forms.Button stepButton;
-    private System.Windows.Forms.Button resetButton;
-    private System.Windows.Forms.Label label1;
-    private System.Windows.Forms.ComboBox exampleComboBox;
-    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
-    private System.Windows.Forms.NumericUpDown stepWidthBox;
-    private System.Windows.Forms.Button runButton;
-    private System.Windows.Forms.CheckBox skipNoopsCheckBox;
-    private System.Windows.Forms.ListView execList;
+    private System.Windows.Forms.GroupBox groupBox2;
+    private System.Windows.Forms.ListBox listBox2;
+    private System.Windows.Forms.GroupBox charGroupBox;
+    private System.Windows.Forms.GroupBox groupBox8;
+    private System.Windows.Forms.ListBox listBox7;
+    private System.Windows.Forms.ListBox charList;
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs	(revision 14777)
@@ -9,7 +9,10 @@
 
   using HeuristicLab.BenchmarkSuite;
+  using HeuristicLab.BenchmarkSuite.Problems;
+  using HeuristicLab.BenchmarkSuite.Views;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Problem;
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
   using HeuristicLab.Random;
 
@@ -18,4 +21,5 @@
   public partial class PushProgramDebuggerView : NamedItemView {
     private const string Separator = ", ";
+    private const string EmptySign = "-";
     private PushProgram program;
 
@@ -31,14 +35,26 @@
       Name = "Push Program Debugger";
 
+      InitEvents();
+      InitExecList();
+    }
+
+    private void InitEvents() {
       exampleComboBox.SelectedIndexChanged += SelectedExampleIndexChanged;
       runButton.Click += RunButtonClick;
       resetButton.Click += ResetButtonClick;
       stepButton.Click += StepButtonClick;
-
+      simplifyButton.Click += SimplifyButtonClick;
+    }
+
+    private void SimplifyButtonClick(object sender, EventArgs e) {
+
+    }
+
+    private void InitExecList() {
       execList.RetrieveVirtualItem += ExecListRetrieveVirtualItem;
       execList.CacheVirtualItems += ExecListCacheVirtualItems;
 
       execList.View = View.Details;
-      execList.HeaderStyle = ColumnHeaderStyle.Nonclickable;
+      execList.HeaderStyle = ColumnHeaderStyle.None;
       execList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.None);
       execList.Columns.Add(new ColumnHeader { Width = execList.Width - 40 });
@@ -111,16 +127,20 @@
 
     private void SetReadonlyFields() {
-      exampleComboBox.Enabled = !ReadOnly;
-      execList.Enabled = !ReadOnly;
-      codeList.Enabled = !ReadOnly;
-      nameList.Enabled = !ReadOnly;
-      integerList.Enabled = !ReadOnly;
-      floatList.Enabled = !ReadOnly;
-      booleanList.Enabled = !ReadOnly;
-      stepButton.Enabled = !ReadOnly;
-      runButton.Enabled = !ReadOnly;
-      resetButton.Enabled = !ReadOnly;
-      skipNoopsCheckBox.Enabled = !ReadOnly;
-      stepWidthBox.Enabled = !ReadOnly;
+      var enabled = !ReadOnly;
+
+      exampleComboBox.Enabled = enabled;
+      execList.Enabled = enabled;
+      codeList.Enabled = enabled;
+      nameList.Enabled = enabled;
+      integerList.Enabled = enabled;
+      floatList.Enabled = enabled;
+      booleanList.Enabled = enabled;
+      stringList.Enabled = enabled;
+      charList.Enabled = enabled;
+      stepButton.Enabled = enabled;
+      runButton.Enabled = enabled;
+      resetButton.Enabled = enabled;
+      skipNoopsCheckBox.Enabled = enabled;
+      stepWidthBox.Enabled = enabled;
     }
 
@@ -200,5 +220,5 @@
       interpreter.Clear();
 
-      var example = Content.DataDescriptor.Examples[this.exampleComboBox.SelectedIndex];
+      var example = Content.Data.Examples[this.exampleComboBox.SelectedIndex];
 
       interpreter.BooleanStack.Push(example.InputBoolean);
@@ -217,9 +237,12 @@
       if (Content == null) return;
 
+      this.nameTextBox.Text = "Push Solution";
+
       var random = Content.Random ?? new FastRandom();
       interpreter = new PushInterpreter(Content.Config, random);
       program = Content.IntegerVector.MapToPushProgram(Content.Config.EnabledExpressions);
 
-      UpdateExamples(Content.DataDescriptor);
+      UpdateExamples(Content.Data);
+      InitResultGrid();
 
       if (this.exampleComboBox.SelectedIndex < 0) {
@@ -228,4 +251,102 @@
         Reset();
       }
+    }
+
+    private void InitResultGrid() {
+      var cellTemplate = new DataGridViewTextBoxCell();
+
+      for (var i = 0; i < Content.Data.InputArgumentTypes.Length; i++) {
+        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.InputArgumentTypes[i]);
+        var column = new DataGridViewColumn {
+          HeaderText = string.Format("Input {0} : {1}", i + 1, headerTypeName),
+          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
+          CellTemplate = cellTemplate
+        };
+
+        resultsDataGrid.Columns.Add(column);
+      }
+
+      for (var i = 0; i < Content.Data.OutputArgumentTypes.Length; i++) {
+        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.OutputArgumentTypes[i]);
+
+        var estimatedOutputColumn = new DataGridViewColumn {
+          HeaderText = string.Format("Estimated Output {0} : {1}", i + 1, headerTypeName),
+          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
+          CellTemplate = cellTemplate
+        };
+
+        var outputColumn = new DataGridViewColumn {
+          HeaderText = string.Format("Output {0} : {1}", i + 1, headerTypeName),
+          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
+          CellTemplate = cellTemplate
+        };
+
+        resultsDataGrid.Columns.Add(estimatedOutputColumn);
+        resultsDataGrid.Columns.Add(outputColumn);
+      }
+
+      resultsDataGrid.Columns.Add(
+        new DataGridViewColumn {
+          HeaderText = "Absolute Diff.",
+          AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader,
+          CellTemplate = cellTemplate
+        });
+
+      resultsDataGrid.Columns.Add(
+        new DataGridViewColumn {
+          HeaderText = "Relative Diff.",
+          AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader,
+          CellTemplate = cellTemplate,
+        });
+
+      var pool = new PushInterpreterPool(Content.Config);
+      var program = Content.IntegerVector.MapToPushProgram(Content.Config.EnabledExpressions);
+
+      using (var pushInterpreter = pool.Create(Content.Random)) {
+        foreach (var example in Content.Data.Examples) {
+          var row = new DataGridViewRow();
+          var absoluteDiff = PushEvaluator.Evaluate(pushInterpreter, program, example, Content.Data.WorstResult);
+          var relativeDiff = absoluteDiff / Math.Abs(Content.Data.BestResult - Content.Data.WorstResult) * 100d;
+
+          row.HeaderCell.Value = row.Index + 1;
+          row.CreateCells(resultsDataGrid);
+
+          for (var i = 0; i < Content.Data.InputArgumentTypes.Length; i++) {
+            row.Cells[i].Value = ViewHelper.StringifyInput(Content.Data.InputArgumentTypes[i], example, Separator);
+          }
+
+          for (var i = 0; i < Content.Data.OutputArgumentTypes.Length; i++) {
+            row.Cells[Content.Data.InputArgumentTypes.Length + i * 2].Value = ViewHelper.StringifyOutput(Content.Data.OutputArgumentTypes[i], example, Separator);
+            row.Cells[Content.Data.InputArgumentTypes.Length + i * 2 + 1].Value = StringifyResult(Content.Data.OutputArgumentTypes[i], pushInterpreter, example, Separator);
+          }
+
+          row.Cells[Content.Data.TotalArgumentCount + 1].Value = absoluteDiff;
+          row.Cells[Content.Data.TotalArgumentCount + 2].Value = relativeDiff + "%";
+
+          this.resultsDataGrid.Rows.Add(row);
+          pushInterpreter.Clear();
+        }
+      }
+    }
+
+    private string StringifyResult(ExampleArgumentType type, IPushInterpreter interpreter, Example example, string valueSeparator) {
+      switch (type) {
+        case ExampleArgumentType.Integer:
+        case ExampleArgumentType.IntegerCollection: return interpreter.IntegerStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.IntegerStack.Peek(GetCount(interpreter.IntegerStack, example.OutputInt)));
+
+        case ExampleArgumentType.Float:
+        case ExampleArgumentType.FloatCollection: return interpreter.FloatStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.FloatStack.Peek(GetCount(interpreter.FloatStack, example.OutputFloat)));
+
+        case ExampleArgumentType.Bool: return interpreter.BooleanStack.IsEmpty ? EmptySign : interpreter.BooleanStack.Top.ToString();
+        case ExampleArgumentType.Char: return interpreter.CharStack.IsEmpty ? EmptySign : interpreter.CharStack.Top.ToString();
+
+        case ExampleArgumentType.String:
+        case ExampleArgumentType.StringCollection: return interpreter.StringStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.StringStack.Peek(GetCount(interpreter.StringStack, example.OutputString)));
+        default: return string.Empty;
+      }
+    }
+
+    private int GetCount<T>(IStack<T> stack, T[] data) {
+      return Math.Max(0, Math.Min(data.Length, stack.Count));
     }
 
@@ -251,66 +372,28 @@
         return;
 
-      if (interpreter.Configuration.IsCodeStackEnabled) {
-        this.codeList.Enabled = true;
-
-        foreach (var item in interpreter.CodeStack.Reverse())
-          this.codeList.Items.Add(item);
-
-        this.codeGroupBox.Text = string.Format("Code [{0}]", this.codeList.Items.Count);
+      ManageStackType(interpreter.Configuration.IsCodeStackEnabled, codeList, codeGroupBox, interpreter.CodeStack, "Code");
+      ManageStackType(interpreter.Configuration.IsIntegerStackEnabled, integerList, integerGroupBox, interpreter.IntegerStack, "Integer");
+      ManageStackType(interpreter.Configuration.IsFloatStackEnabled, floatList, floatGroupBox, interpreter.FloatStack, "Float");
+      ManageStackType(interpreter.Configuration.IsBooleanStackEnabled, booleanList, booleanGroupBox, interpreter.BooleanStack, "Boolean");
+      ManageStackType(interpreter.Configuration.IsNameStackEnabled, nameList, nameGroupBox, interpreter.NameStack, "Name");
+      ManageStackType(interpreter.Configuration.IsStringStackEnabled, stringList, stringGroupBox, interpreter.StringStack, "String");
+      ManageStackType(interpreter.Configuration.IsCharStackEnabled, charList, charGroupBox, interpreter.CharStack, "Char");
+    }
+
+    private void ManageStackType<T>(bool enabled, ListBox listbox, GroupBox groupBox, IStack<T> stack, string name) {
+      if (enabled) {
+        listbox.Enabled = true;
+
+        foreach (var item in stack.Reverse())
+          listbox.Items.Add(item);
+
+        groupBox.Text = string.Format("{0} [{1}]", name, listbox.Items.Count);
       } else {
-        this.codeList.Enabled = false;
-        this.codeGroupBox.Text = "Code - Disabled";
-      }
-
-      if (interpreter.Configuration.IsIntegerStackEnabled) {
-        this.integerList.Enabled = true;
-
-        foreach (var item in interpreter.IntegerStack.Reverse())
-          this.integerList.Items.Add(item);
-
-        this.integerGroupBox.Text = string.Format("Integer [{0}]", this.integerList.Items.Count);
-      } else {
-        this.integerList.Enabled = false;
-        this.integerGroupBox.Text = "Integer - Disabled";
-      }
-
-      if (interpreter.Configuration.IsFloatStackEnabled) {
-        this.floatList.Enabled = true;
-
-        foreach (var item in interpreter.FloatStack.Reverse())
-          this.floatList.Items.Add(item);
-
-        this.floatGroupBox.Text = string.Format("Float [{0}]", this.floatList.Items.Count);
-      } else {
-        this.floatList.Enabled = false;
-        this.floatGroupBox.Text = "Float - Disabled";
-      }
-
-      if (interpreter.Configuration.IsBooleanStackEnabled) {
-        this.booleanList.Enabled = true;
-
-        foreach (var item in interpreter.BooleanStack.Reverse())
-          this.booleanList.Items.Add(item);
-
-        this.booleanGroupBox.Text = string.Format("Boolean [{0}]", this.booleanList.Items.Count);
-      } else {
-        this.booleanList.Enabled = false;
-        this.booleanGroupBox.Text = "Boolean - Disabled";
-      }
-
-      if (interpreter.Configuration.IsNameStackEnabled) {
-        this.nameList.Enabled = true;
-
-        foreach (var item in interpreter.NameStack.Reverse())
-          this.nameList.Items.Add(item);
-
-        this.nameGroupBox.Text = string.Format("Name [{0}]", this.nameList.Items.Count);
-      } else {
-        this.nameList.Enabled = false;
-        this.nameGroupBox.Text = "Name - Disabled";
-      }
-    }
-
-    private void UpdateExamples(IBenchmarkSuiteDataDescriptor data) {
+        listbox.Enabled = false;
+        groupBox.Text = string.Format("{0} - DISABLED", name);
+      }
+    }
+
+    private void UpdateExamples(Data data) {
       if (data == null) return;
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.resx
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.resx	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.resx	(revision 14777)
@@ -125,13 +125,12 @@
   </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
-  <data name="stepButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="runButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
-        JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAABFklE
-        QVQ4T2P4//8/Bk7oecKMTRwbxioINEAGiJmwyaFjrIKFs57/j5/8VokYQ7AK5s589j+h+97/uAmvNQh5
-        B6tgxpSn/+ft//0/qOHma6ABtvgMwSoI1PB/9r5f/zu3/v3vVnr5P5Bvj8sQDAEQjux69H/Ktl//S5b+
-        /Z8w/e9/m9yzOA1B4cBwYPPD/61r34M1G5d8+S8dfe2/ceSy/w5FZ+PRDUHRCMMeVff/l8x9B9es6NLz
-        X9pndSA2tRgCIGxfevd/YMszJM0rvbCpA2GsghZ5d/7bFFyBabbBpgaGsQoaZt0Ga5byWu6KTR4ZYxXU
-        SbsBtHmNLzY5dIxVUMp7rZ+09wqciQcZYxUkBWMVJB7/ZwAA4djU9I5dK1UAAAAASUVORK5CYII=
+        JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsElE
+        QVQ4T2P4//8/RRirYNn+bDds4tgwVsGEGRH/iTUEqyDIAMsyfaIMwSoYNSXo/4Zbi4kyBKtg8ARvkEai
+        DMEq6NPlDDYAhKMWBeA1BEMAhB2bLf5nbIgFa7Zt1v+vU6zwXyKNG0SroatF4cCweY0eimb+BBasmkEY
+        QwCE9UqVidIMwlgFVfKliNIMwlgFpTMEidIMwlgFRZI5idIMwlgFidUMwlgFScFYBYnH/xkAJP3E6UxO
+        vJ8AAAAASUVORK5CYII=
 </value>
   </data>
@@ -197,12 +196,13 @@
 </value>
   </data>
-  <data name="runButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="stepButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
-        JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsElE
-        QVQ4T2P4//8/RRirYNn+bDds4tgwVsGEGRH/iTUEqyDIAMsyfaIMwSoYNSXo/4Zbi4kyBKtg8ARvkEai
-        DMEq6NPlDDYAhKMWBeA1BEMAhB2bLf5nbIgFa7Zt1v+vU6zwXyKNG0SroatF4cCweY0eimb+BBasmkEY
-        QwCE9UqVidIMwlgFVfKliNIMwlgFpTMEidIMwlgFRZI5idIMwlgFidUMwlgFScFYBYnH/xkAJP3E6UxO
-        vJ8AAAAASUVORK5CYII=
+        JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAABFklE
+        QVQ4T2P4//8/Bk7oecKMTRwbxioINEAGiJmwyaFjrIKFs57/j5/8VokYQ7AK5s589j+h+97/uAmvNQh5
+        B6tgxpSn/+ft//0/qOHma6ABtvgMwSoI1PB/9r5f/zu3/v3vVnr5P5Bvj8sQDAEQjux69H/Ktl//S5b+
+        /Z8w/e9/m9yzOA1B4cBwYPPD/61r34M1G5d8+S8dfe2/ceSy/w5FZ+PRDUHRCMMeVff/l8x9B9es6NLz
+        X9pndSA2tRgCIGxfevd/YMszJM0rvbCpA2GsghZ5d/7bFFyBabbBpgaGsQoaZt0Ga5byWu6KTR4ZYxXU
+        SbsBtHmNLzY5dIxVUMp7rZ+09wqciQcZYxUkBWMVJB7/ZwAA4djU9I5dK1UAAAAASUVORK5CYII=
 </value>
   </data>
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/Example.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/Example.cs	(revision 14747)
+++ 	(revision )
@@ -1,7 +1,0 @@
-﻿namespace HeuristicLab.Tests.Benchmark {
-  public class Example<Tin, Tout> {
-    public Tin Input { get; set; }
-
-    public Tout Output { get; set; }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/ExampleConverter.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/ExampleConverter.cs	(revision 14747)
+++ 	(revision )
@@ -1,24 +1,0 @@
-﻿namespace Push.Data {
-  using System.Linq;
-
-  public static class ExampleConverter {
-    private const char ArrayValueSeparator = ' ';
-
-    private static readonly char[] arraySymbolTrim = { '[', ']' };
-
-    public static long Integer(string str) {
-      return long.Parse(str);
-    }
-
-    public static long[] Integers(string str) {
-      var values =
-        str.Trim(arraySymbolTrim).Split(ArrayValueSeparator).Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
-
-      var result = new long[values.Count];
-
-      for (var i = 0; i < result.Length; i++) result[i] = Integer(values[i]);
-
-      return result;
-    }
-  }
-}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/ProblemTests.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/ProblemTests.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Benchmark/ProblemTests.cs	(revision 14777)
@@ -26,10 +26,10 @@
     }
 
-    [TestMethod]
-    [TestProperty("Time", "Medium")]
-    [TestCategory("ProblemTest")]
-    public void Checksum() {
-      RandomWalk(new Checksum());
-    }
+    //[TestMethod]
+    //[TestProperty("Time", "Medium")]
+    //[TestCategory("ProblemTest")]
+    //public void Checksum() {
+    //  RandomWalk(new Checksum());
+    //}
 
     //[TestMethod]
@@ -152,6 +152,6 @@
         PushProgram program;
 
-        using (var interpreter = pool.GetInstance(random)) {
-          program = CodeGenerator.RandomProgram(interpreter.PushProgramPool, maxProgramSizeLimit, random);
+        using (var interpreter = pool.Create(random)) {
+          program = RecursiveCodeGenerator.RandomProgram(maxProgramSizeLimit, random);
 
           for (var j = 0; j < data.OriginalTrainingCount; j++) {
@@ -193,5 +193,5 @@
       var resultsTest = new double[data.OriginalTestCount];
       Parallel.For(data.OriginalTestCount, data.OriginalTestCount, i => {
-        using (var interpreter = pool.GetInstance()) {
+        using (var interpreter = pool.Create()) {
           var example = data.Examples[i];
 
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/HeuristicLab.Tests.csproj.user
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/HeuristicLab.Tests.csproj.user	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/HeuristicLab.Tests.csproj.user	(revision 14777)
@@ -2,5 +2,5 @@
 <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectView>ShowAllFiles</ProjectView>
   </PropertyGroup>
 </Project>
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Interpreter/InterpreterTest.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Tests/Interpreter/InterpreterTest.cs	(revision 14747)
+++ 	(revision )
@@ -1,52 +1,0 @@
-﻿using HeuristicLab.Algorithms.PushGP.Interpreter;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace HeuristicLab.Tests.Interpreter
-{
-    public class InterpreterTest
-    {
-        protected PushGPInterpreter interpreter;
-
-        [TestInitialize]
-        public void BeforeTest()
-        {
-            interpreter = new PushGPInterpreter(new Configuration
-            {
-                TopLevelPushCode = false
-            });
-        }
-
-        protected void TestStackCounts(int? execStack = 0, int? codeStack = 0, int? nameStack = 0, int? booleanStack = 0, int? floatStack = 0, int? integerStack = 0)
-        {
-            if (execStack.HasValue)
-            {
-                Assert.AreEqual(execStack, interpreter.ExecStack.Count);
-            }
-
-            if (codeStack.HasValue)
-            {
-                Assert.AreEqual(codeStack, interpreter.CodeStack.Count);
-            }
-
-            if (nameStack.HasValue)
-            {
-                Assert.AreEqual(nameStack, interpreter.NameStack.Count);
-            }
-
-            if (booleanStack.HasValue)
-            {
-                Assert.AreEqual(booleanStack, interpreter.BooleanStack.Count);
-            }
-
-            if (floatStack.HasValue)
-            {
-                Assert.AreEqual(floatStack, interpreter.FloatStack.Count);
-            }
-
-            if (integerStack.HasValue)
-            {
-                Assert.AreEqual(integerStack, interpreter.IntegerStack.Count);
-            }
-        }
-    }
-}
Index: branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/PushGP.Cli/Program.cs	(revision 14777)
@@ -1,34 +1,15 @@
 ﻿using System;
-using System.Diagnostics;
-using System.Linq;
 using System.Threading.Tasks;
 
 namespace HeuristicLab.Algorithms.PushGP.Cli {
   using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Generators;
   using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
-  using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
-  using HeuristicLab.Random;
 
   class Program {
     static void Main(string[] args) {
-      //SimpleTest();
-      //Stepwise().Wait();
-      //PerformanceTestInterpreter();
-      //PerformanceParallelTestInterpreter();
-      //PerformanceTestCodeGenerator();
-      TestRobustness();
-      //TestPool();
-      //TestPoolPerformance();
-      //TestSimplifier();
+      if (args.Length == 0) return;
 
-      Console.WriteLine("\nPress any key to continue...");
-
-      //if (args.Length == 0) return;
-
-      //var code = args[0];
-      //EvaluateStepwise(code).Wait();
+      var code = args[0];
+      EvaluateStepwise(code).Wait();
 
       Console.ReadKey();
@@ -58,185 +39,4 @@
       interpreter.PrintStacks();
     }
-
-    static void SimpleTest() {
-      var interpreter = new PushInterpreter();
-
-      interpreter.Run("5 INTEGER.DUP INTEGER.+");
-
-      interpreter.PrintStacks();
-    }
-
-    static async Task Stepwise() {
-      var interpreter = new PushInterpreter();
-
-      interpreter.RunAsync("( 0 2 CODE.QUOTE ( 1 INTEGER.+ 0 3 CODE.QUOTE ( 1 INTEGER.+ INTEGER.* ) CODE.DO*RANGE INTEGER.+ ) CODE.DO*RANGE )", true).Wait();
-
-      while (!interpreter.IsCompleted) {
-        Console.Clear();
-        interpreter.PrintStacks();
-        interpreter.Step();
-
-        var input = Console.ReadKey();
-        if (input.Key == ConsoleKey.Escape) {
-          break;
-        } else if (input.Key == ConsoleKey.Spacebar) {
-          await interpreter.ResumeAsync();
-        }
-      }
-
-      Console.Clear();
-      interpreter.PrintStacks();
-    }
-
-    static void PerformanceTestInterpreter() {
-      var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )");
-
-      var interpreter = new PushInterpreter();
-      var sw = new Stopwatch();
-
-      sw.Start();
-      for (var i = 0; i < 60000000; i++) {
-        interpreter.Run(program);
-        interpreter.Clear();
-      }
-      sw.Stop();
-
-      Console.WriteLine(sw.Elapsed);
-    }
-
-    static void PerformanceParallelTestInterpreter() {
-      var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )");
-
-      var sw = new Stopwatch();
-      var iterations = 100;
-      var amount = 600000;
-      var pool = new PushInterpreterPool(iterations, 1024);
-
-      sw.Start();
-      Parallel.For(0, iterations, i => {
-        using (var interpreter = pool.GetInstance()) {
-
-          for (var j = 0; j < amount; j++) {
-            interpreter.Run(program);
-            interpreter.Clear();
-          }
-        }
-      });
-      sw.Stop();
-
-      Console.WriteLine(sw.Elapsed);
-    }
-
-    static void PerformanceTestCodeGenerator() {
-      var sw = new Stopwatch();
-      var random = new FastRandom(1337);
-
-      sw.Start();
-      var expressions = CodeGenerator.RandomCode(60000000, random).ToList();
-      sw.Stop();
-
-      Console.WriteLine("Generated {0} in {1}", expressions.Count(), sw.Elapsed);
-    }
-
-    static void TestRobustness() {
-      var sw = new Stopwatch();
-      var parallelism = Environment.ProcessorCount;
-      var maxProgramSizeLimit = 1024;
-      var partitionSize = 10000;
-      var execCounters = new int[parallelism];
-
-      var config = new PushConfiguration {
-        EvalPushLimit = 4096,
-        IsCodeStackEnabled = false,
-        //IsExecStackEnable = false,
-        //IsBooleanStackEnabled = false,
-        //IsFloatStackEnabled = false,
-        //IsIntegerStackEnabled = false,
-        IsNameStackEnabled = false,
-      };
-
-      var pool = new PushInterpreterPool(config);
-
-      sw.Start();
-      Parallel.For(0, parallelism, i => {
-        var random = new MersenneTwister(1337);
-        using (var interpreter = pool.GetInstance(random)) {
-          for (var j = 0; j < partitionSize; j++) {
-            var program = CodeGenerator.RandomProgram(interpreter.PushProgramPool, maxProgramSizeLimit, random, config);
-            interpreter.Run(program);
-
-            execCounters[i] += interpreter.ExecCounter;
-            interpreter.Clear();
-          }
-        }
-      });
-      sw.Stop();
-
-      Console.WriteLine("ExecCount: {0}", execCounters.Sum());
-      Console.WriteLine("Duration: {0}", sw.Elapsed);
-    }
-
-    static void TestPool() {
-      var pool = new PushInterpreterPool();
-      var normal = new PushInterpreter();
-      int id;
-
-      using (var interpreter = pool.GetInstance()) {
-        interpreter.Run("( 1 2 INTEGER.+ )");
-
-        id = interpreter.GetHashCode();
-        if (id == normal.GetHashCode()) Console.WriteLine("equal 1");
-      }
-
-      using (var interpreter = pool.GetInstance())
-      using (var interpreter2 = pool.GetInstance()) {
-        interpreter.Run("( 1 2 INTEGER.+ )");
-        if (id == interpreter.GetHashCode()) Console.WriteLine("equal 2");
-        if (id == interpreter2.GetHashCode()) Console.WriteLine("equal 3");
-      }
-    }
-
-    static void TestPoolPerformance() {
-      var sw = new Stopwatch();
-      var iterations = 100000000;
-
-      sw.Start();
-      for (var i = 0; i < iterations; i++) {
-        var interpreter = new PushInterpreter();
-        interpreter.Clear();
-      }
-      sw.Stop();
-
-      Console.WriteLine(sw.Elapsed);
-
-      var pool = new PushInterpreterPool();
-      sw.Restart();
-      for (var i = 0; i < iterations; i++) {
-        using (var interpreter = pool.GetInstance()) {
-          interpreter.Clear();
-        }
-      }
-      sw.Stop();
-
-      Console.WriteLine(sw.Elapsed);
-    }
-
-    //static void TestSimplifier() {
-    //  var interpreter = new PushInterpreter();
-    //  var program = PushParser.Parse("( 5 INTEGER.DUP FLOAT.+ INTEGER.+ )") as PushProgram;
-    //  var simplifier = new RandomSimplifier { Trys = 10 };
-    //  var random = new FastRandom(1337);
-
-    //  var simplerProgram = simplifier.Simplify(
-    //    program,
-    //    random,
-    //    solution => {
-    //      interpreter.Clear();
-    //      interpreter.Run(solution);
-    //      return interpreter.IntegerStack.Top == 10;
-    //    });
-
-    //  Console.WriteLine(simplerProgram);
-    //}
   }
 }
Index: branches/PushGP/HeuristicLab.PushGP/PushGp.sln
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/PushGp.sln	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/PushGp.sln	(revision 14777)
@@ -12,5 +12,5 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.ProgramSynthesis", "HeuristicLab.Problems.ProgramSynthesis\HeuristicLab.Problems.ProgramSynthesis.csproj", "{5C93448C-47E3-4C3F-B1D0-EE62A48C3204}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestPooling", "TestPooling\TestPooling.csproj", "{B184A849-1403-4F5F-96F8-952C6599A7C0}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeatureTests", "FeatureTests\FeatureTests.csproj", "{B184A849-1403-4F5F-96F8-952C6599A7C0}"
 EndProject
 Global
Index: branches/PushGP/HeuristicLab.PushGP/PushGp.sln.DotSettings.user
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/PushGp.sln.DotSettings.user	(revision 14747)
+++ branches/PushGP/HeuristicLab.PushGP/PushGp.sln.DotSettings.user	(revision 14777)
@@ -3,3 +3,5 @@
   &lt;Assembly Path="T:\BTSync\projects\svn\hl\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll" /&gt;&#xD;
   &lt;Assembly Path="T:\BTSync\projects\svn\hl\trunk\sources\bin\HeuristicLab.Data-3.3.dll" /&gt;&#xD;
-&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>
+&lt;/AssemblyExplorer&gt;</s:String>
+	<s:Boolean x:Key="/Default/VsIntegrationViewOptions/ShowCharts/@EntryValue">False</s:Boolean>
+	</wpf:ResourceDictionary>
