Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPrintStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPrintStack.cs	(revision 15189)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPrintStack.cs	(revision 15189)
@@ -0,0 +1,11 @@
+﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
+  public interface IPrintStack : IPushStack<string> {
+    void NewLine();
+    void Push<T>(T item);
+    void Push(double item);
+    void Push(long item);
+    void Push(int item);
+    void Push(char item);
+    void Push(bool item);
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPushStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPushStack.cs	(revision 15032)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/IPushStack.cs	(revision 15189)
@@ -1,4 +1,3 @@
 ﻿namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
-  using System;
   using System.Collections.Generic;
 
@@ -18,11 +17,8 @@
     void Push(IEnumerable<T> items);
     new void Clear();
-    T Peek();
-    T[] Peek(int count);
-    void PushResult(int count, Func<T[], T> templateFunc);
+    IReadOnlyList<T> Peek(int count);
     void Insert(int index, T item);
-    T ReverseElementAt(int offset);
     T Pop();
-    T[] Pop(int count);
+    IReadOnlyList<T> Pop(int count);
     bool TryPop(out T item);
     T ElementAt(int index);
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/InterpreterStackStringifier.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/InterpreterStackStringifier.cs	(revision 15032)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/InterpreterStackStringifier.cs	(revision 15189)
@@ -45,5 +45,5 @@
 
     private static IEnumerable<string> StringifyLiteralStack<T>(IPushStack<T> stack, string prefix = "", string postfix = "", bool reverse = true) {
-      var result = stack.AsEnumerable();
+      var result = stack.AsStrings();
 
       if (reverse)
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PrintStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PrintStack.cs	(revision 15189)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PrintStack.cs	(revision 15189)
@@ -0,0 +1,354 @@
+﻿using System.Text;
+
+
+namespace HeuristicLab.Problems.ProgramSynthesis.Push.Stack {
+  using System.Collections;
+  using System.Collections.Generic;
+
+  using HeuristicLab.Problems.ProgramSynthesis.Push.Extensions;
+
+  /// <summary>
+  /// Optimized for string concatenation to reduce memory effort
+  /// </summary>
+  public class PrintStack : IPrintStack {
+    private string currentTop;
+    private readonly IPushStack<string> stack = new PushStack<string>();
+    private readonly StringBuilder stringBuilder = new StringBuilder();
+
+    private string CurrentTop
+    {
+      get
+      {
+        return currentTop ?? (currentTop = stringBuilder.ToString());
+      }
+    }
+
+    public IEnumerator<string> GetEnumerator() {
+      return stack.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    public void Add(string item) {
+      Push(item);
+    }
+
+    void IPushStack<string>.Clear() {
+      stack.Clear();
+      stringBuilder.Clear();
+      currentTop = null;
+    }
+
+    public IReadOnlyList<string> Peek(int count) {
+      if (count == 1)
+        return new[] { CurrentTop };
+
+      var peek = stack.Peek(count - 1);
+      var result = new List<string>(peek) { CurrentTop };
+
+      return result;
+    }
+
+    public void Insert(int index, string item) {
+      if (index == 0)
+        Add(item);
+
+      stack.Insert(index - 1, item);
+    }
+
+    public string Pop() {
+      var result = CurrentTop;
+
+      var top = stack.Pop();
+      SetBuilderToTop(top);
+
+      return result;
+    }
+
+    public IReadOnlyList<string> Pop(int count) {
+      if (count == 1)
+        return new[] { Pop() };
+
+      var popped = stack.Pop(count - 1);
+      var result = new List<string>(popped) { CurrentTop };
+
+      var newTop = stack.Pop();
+      SetBuilderToTop(newTop);
+
+      return result;
+    }
+
+    private void ClearTop() {
+      stringBuilder.Clear();
+      currentTop = null;
+    }
+
+    private void SetBuilderToTop(string top) {
+      stringBuilder.Clear();
+      stringBuilder.Append(top);
+      currentTop = top;
+    }
+
+    public bool TryPop(out string item) {
+      if (string.IsNullOrEmpty(CurrentTop)) {
+        item = null;
+        return false;
+      }
+
+      item = Pop();
+      return true;
+    }
+
+    public string ElementAt(int index) {
+      if (index == 0)
+        return CurrentTop;
+
+      return stack.ElementAt(index - 1);
+    }
+
+    public string Top
+    {
+      get
+      {
+        return CurrentTop;
+      }
+      set
+      {
+        SetBuilderToTop(value);
+      }
+    }
+
+    public string TopOrDefault { get { return CurrentTop; } }
+
+    public string Bottom { get { return Count > 1 ? stack.Bottom : CurrentTop; } }
+
+    public string BottomOrDefault { get { return Bottom; } }
+
+    public string this[int key]
+    {
+      get
+      {
+        return key == 0 ? CurrentTop : stack[key - 1];
+      }
+      set
+      {
+        if (key == 0)
+          SetBuilderToTop(value);
+        else
+          stack[key - 1] = value;
+      }
+    }
+
+    public int Count
+    {
+      get
+      {
+        return stack.Count + (string.IsNullOrEmpty(CurrentTop) ? 0 : 1);
+      }
+    }
+
+    public void NewLine() {
+      if (IsEmpty) return;
+
+      stack.Push(CurrentTop);
+      ClearTop();
+    }
+
+    public void Push<T>(T item) {
+      stringBuilder.Append(item);
+      currentTop = null;
+    }
+
+    public void Push(float item) {
+      stringBuilder.Concat(item);
+      currentTop = null;
+    }
+
+    public void Push(double item) {
+      stringBuilder.Concat(item);
+      currentTop = null;
+    }
+
+    public void Push(long item) {
+      stringBuilder.Concat(item);
+      currentTop = null;
+    }
+
+    public void Push(int item) {
+      stringBuilder.Concat(item);
+      currentTop = null;
+    }
+
+    public void Push(char item) {
+      stringBuilder.Append(item);
+      currentTop = null;
+    }
+
+    public void Push(bool item) {
+      stringBuilder.Append(item);
+      currentTop = null;
+    }
+
+
+    public void Push(string item) {
+      stringBuilder.Append(item);
+      currentTop = null;
+    }
+
+    public void Push(string item1, string item2) {
+      stringBuilder.Append(item1);
+      stringBuilder.Append(item2);
+      currentTop = null;
+    }
+
+    public void Push(string item1, string item2, string item3) {
+      stringBuilder.Append(item1);
+      stringBuilder.Append(item2);
+      stringBuilder.Append(item3);
+      currentTop = null;
+    }
+
+    public void Push(string item1, string item2, string item3, string item4) {
+      stringBuilder.Append(item1);
+      stringBuilder.Append(item2);
+      stringBuilder.Append(item3);
+      stringBuilder.Append(item4);
+      currentTop = null;
+    }
+
+    public void Push(IReadOnlyList<string> items, int startIndex) {
+      for (var i = startIndex; i < items.Count; i++)
+        stringBuilder.Append(items[i]);
+
+      currentTop = null;
+    }
+
+    public void Push(IReadOnlyList<string> items) {
+      Push(items, 0);
+    }
+
+    public void Push(IEnumerable<string> items) {
+      foreach (var item in items)
+        stringBuilder.Append(item);
+
+      currentTop = null;
+    }
+
+    void IPushStack.Clear() {
+      stringBuilder.Clear();
+      currentTop = null;
+      stack.Clear();
+    }
+
+    public void Swap(int count) {
+      stack.Push(CurrentTop);
+      stack.Swap(count);
+
+      var newTop = stack.Pop();
+      SetBuilderToTop(newTop);
+    }
+
+    public void Yank(int index) {
+      if (index == Count - 1) return;
+
+      stack.Push(CurrentTop);
+
+      var item = stack[index];
+      stack.RemoveAt(index);
+      SetBuilderToTop(item);
+    }
+
+    public void RemoveTop() {
+      var newTop = stack.Pop();
+      SetBuilderToTop(newTop);
+    }
+
+    public void Remove(int count) {
+      if (count == 1)
+        RemoveTop();
+
+      stack.Remove(count - 1);
+      var newTop = stack.Pop();
+      SetBuilderToTop(newTop);
+    }
+
+    public void RemoveAt(int index) {
+      if (index == 0)
+        ClearTop();
+      else
+        stack.RemoveAt(index - 1);
+    }
+
+    public void RemoveAt(int index, int count) {
+      if (index == 0)
+        count--;
+
+      stack.RemoveAt(index - 1, count);
+
+      if (index == 0) {
+        var newTop = stack.Pop();
+        SetBuilderToTop(newTop);
+      }
+    }
+
+    public IEnumerable<string> AsStrings() {
+      foreach (var item in stack)
+        yield return item;
+
+      if (!IsEmpty)
+        yield return CurrentTop;
+    }
+
+    public IEnumerable<object> AsObjects() {
+      return AsStrings();
+    }
+
+    void ICollection<string>.Clear() {
+      stack.Clear();
+      stringBuilder.Clear();
+    }
+
+    public bool Contains(string item) {
+
+      return CurrentTop.Equals(item) || stack.Contains(item);
+    }
+
+    public void CopyTo(string[] array, int arrayIndex) {
+      stack.CopyTo(array, arrayIndex);
+      array[arrayIndex + stack.Count] = CurrentTop;
+    }
+
+    public bool Remove(string item) {
+      if (item.Equals(CurrentTop)) {
+        RemoveTop();
+        return true;
+      }
+
+      return stack.Remove(item);
+    }
+
+    int IPushStack<string>.Count
+    {
+      get
+      {
+        return Count;
+      }
+    }
+
+    public bool IsEmpty { get { return stack.IsEmpty && string.IsNullOrEmpty(CurrentTop); } }
+
+    public bool IsEnabled { get; set; }
+
+    int ICollection<string>.Count
+    {
+      get
+      {
+        return Count;
+      }
+    }
+
+    public bool IsReadOnly { get { return false; } }
+  }
+}
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs	(revision 15032)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/PushStack.cs	(revision 15189)
@@ -122,8 +122,4 @@
     }
 
-    public T ReverseElementAt(int offset) {
-      return data[offset];
-    }
-
     public T this[int index]
     {
@@ -145,5 +141,5 @@
       if (index == Count - 1) return;
 
-      var item = ReverseElementAt(index);
+      var item = data[index];
       data.RemoveAt(index);
       data.Add(item);
@@ -157,5 +153,5 @@
     }
 
-    public T[] Pop(int count) {
+    public IReadOnlyList<T> Pop(int count) {
       var items = Peek(count);
       Remove(count);
@@ -164,9 +160,5 @@
     }
 
-    public T Peek() {
-      return Top;
-    }
-
-    public T[] Peek(int count) {
+    public IReadOnlyList<T> Peek(int count) {
       var startIndex = Count - count;
 
@@ -207,16 +199,4 @@
     }
 
-    public void PushResult(int count, Func<T[], T> templateFunc) {
-      if (!IsEnabled) return;
-
-      var startIndex = Count - count;
-      var items = new T[count];
-
-      data.CopyTo(startIndex, items, 0, count);
-      Remove(count - 1);
-
-      data[Count - 1] = templateFunc(items);
-    }
-
     public void Push(IReadOnlyList<T> items, int startIndex) {
       if (!IsEnabled) return;
Index: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs
===================================================================
--- branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs	(revision 15032)
+++ branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Stack/StackTypes.cs	(revision 15189)
@@ -20,3 +20,25 @@
     BooleanVector = 0x2000,
   }
+
+  //public static class StackTypeExtensions {
+  //  private static readonly IReadOnlyDictionary<StackTypes, string> StackTypesNameDict = new Dictionary<StackTypes, string> {
+  //    { StackTypes.Integer, "Integer" },
+  //    { StackTypes.Float, "Float" },
+  //    { StackTypes.Char, "Char" },
+  //    { StackTypes.String, "String" },
+  //    { StackTypes.Boolean, "Boolean" },
+  //    { StackTypes.Name, "Name" },
+  //    { StackTypes.Code, "Code" },
+  //    { StackTypes.Exec, "Exec" },
+  //    { StackTypes.Print, "Print" },
+  //    { StackTypes.IntegerVector, "IntegerVector" },
+  //    { StackTypes.FloatVector, "FloatVector" },
+  //    { StackTypes.StringVector, "StringVector" },
+  //    { StackTypes.BooleanVector, "BooleanVector" },
+  //  };
+
+  //  public static string GetName(this StackTypes types) {
+  //    return StackTypesNameDict[types];
+  //  }
+  //}
 }
