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();
