Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/HeuristicLab.Problems.GeneticProgramming.Views-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/HeuristicLab.Problems.GeneticProgramming.Views-3.3.csproj	(revision 13311)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/HeuristicLab.Problems.GeneticProgramming.Views-3.3.csproj	(revision 13312)
@@ -133,4 +133,34 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Robocode\BattleRunnerDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Robocode\BattleRunnerDialog.Designer.cs">
+      <DependentUpon>BattleRunnerDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Robocode\CodeSymbolView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Robocode\CodeSymbolView.Designer.cs">
+      <DependentUpon>CodeSymbolView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Robocode\EnemyCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Robocode\EnemyCollectionView.Designer.cs">
+      <DependentUpon>EnemyCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Robocode\SolutionCodeView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Robocode\SolutionCodeView.Designer.cs">
+      <DependentUpon>SolutionCodeView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Robocode\SolutionProgramView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Robocode\SolutionProgramView.Designer.cs">
+      <DependentUpon>SolutionProgramView.cs</DependentUpon>
+    </Compile>
   </ItemGroup>
   <ItemGroup>
@@ -140,4 +170,14 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
       <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Plugin.cs.frame	(revision 13311)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Plugin.cs.frame	(revision 13312)
@@ -28,4 +28,7 @@
   [Plugin("HeuristicLab.Problems.GeneticProgramming.Views","Provides views for for genetic programming problems such as the artificial ant problem.", "3.3.0.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.GeneticProgramming.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common","3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources","3.3")]
+  [PluginDependency("HeuristicLab.Collections","3.3")]
   [PluginDependency("HeuristicLab.Core","3.3")]
   [PluginDependency("HeuristicLab.Core.Views","3.3")]
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.Designer.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.Designer.cs	(revision 13312)
@@ -0,0 +1,200 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  partial class BattleRunnerDialog {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.label1 = new System.Windows.Forms.Label();
+      this.robocodePathTextBox = new System.Windows.Forms.TextBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.nrOfRoundsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.searchButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.runInRobocodeButton = new System.Windows.Forms.Button();
+      this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.enemyCollectionView = new EnemyCollectionView();
+      ((System.ComponentModel.ISupportInitialize)(this.nrOfRoundsNumericUpDown)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(12, 15);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(85, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Robocode Path:";
+      // 
+      // robocodePathTextBox
+      // 
+      this.robocodePathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.robocodePathTextBox.Location = new System.Drawing.Point(117, 12);
+      this.robocodePathTextBox.Name = "robocodePathTextBox";
+      this.robocodePathTextBox.Size = new System.Drawing.Size(715, 20);
+      this.robocodePathTextBox.TabIndex = 1;
+      this.robocodePathTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.robocodePathTextBox_Validating);
+      this.robocodePathTextBox.Validated += new System.EventHandler(this.robocodePathTextBox_Validated);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(12, 40);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(99, 13);
+      this.label2.TabIndex = 2;
+      this.label2.Text = "Number of Rounds:";
+      // 
+      // nrOfRoundsNumericUpDown
+      // 
+      this.nrOfRoundsNumericUpDown.Location = new System.Drawing.Point(117, 38);
+      this.nrOfRoundsNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.nrOfRoundsNumericUpDown.Name = "nrOfRoundsNumericUpDown";
+      this.nrOfRoundsNumericUpDown.Size = new System.Drawing.Size(73, 20);
+      this.nrOfRoundsNumericUpDown.TabIndex = 3;
+      this.nrOfRoundsNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      // 
+      // searchButton
+      // 
+      this.searchButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.searchButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Zoom;
+      this.searchButton.Location = new System.Drawing.Point(838, 9);
+      this.searchButton.Name = "searchButton";
+      this.searchButton.Size = new System.Drawing.Size(24, 24);
+      this.searchButton.TabIndex = 4;
+      this.searchButton.UseVisualStyleBackColor = true;
+      this.searchButton.Click += new System.EventHandler(this.searchButton_Click);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(787, 567);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 5;
+      this.cancelButton.Text = "Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      // 
+      // runInRobocodeButton
+      // 
+      this.runInRobocodeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.runInRobocodeButton.Location = new System.Drawing.Point(656, 567);
+      this.runInRobocodeButton.Name = "runInRobocodeButton";
+      this.runInRobocodeButton.Size = new System.Drawing.Size(125, 23);
+      this.runInRobocodeButton.TabIndex = 6;
+      this.runInRobocodeButton.Text = "Run in Robocode";
+      this.runInRobocodeButton.UseVisualStyleBackColor = true;
+      this.runInRobocodeButton.Click += new System.EventHandler(this.runInRobocodeButton_Click);
+      // 
+      // folderBrowserDialog
+      // 
+      this.folderBrowserDialog.ShowNewFolderButton = false;
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // enemyCollectionView
+      // 
+      this.enemyCollectionView.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.enemyCollectionView.Caption = "EnemyCollection View";
+      this.enemyCollectionView.Content = null;
+      this.enemyCollectionView.Location = new System.Drawing.Point(12, 64);
+      this.enemyCollectionView.Name = "enemyCollectionView";
+      this.enemyCollectionView.ReadOnly = false;
+      this.enemyCollectionView.Size = new System.Drawing.Size(850, 497);
+      this.enemyCollectionView.TabIndex = 0;
+      // 
+      // BattleRunnerDialog
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(874, 602);
+      this.Controls.Add(this.runInRobocodeButton);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.searchButton);
+      this.Controls.Add(this.enemyCollectionView);
+      this.Controls.Add(this.nrOfRoundsNumericUpDown);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.robocodePathTextBox);
+      this.Controls.Add(this.label1);
+      this.Name = "BattleRunnerDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Run Battle";
+      ((System.ComponentModel.ISupportInitialize)(this.nrOfRoundsNumericUpDown)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TextBox robocodePathTextBox;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.NumericUpDown nrOfRoundsNumericUpDown;
+    private EnemyCollectionView enemyCollectionView;
+    private System.Windows.Forms.Button searchButton;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.Button runInRobocodeButton;
+    private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/BattleRunnerDialog.cs	(revision 13312)
@@ -0,0 +1,82 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.IO;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  public partial class BattleRunnerDialog : Form {
+    public int NrOfRounds {
+      get { return (int)nrOfRoundsNumericUpDown.Value; }
+      set { nrOfRoundsNumericUpDown.Value = value; }
+    }
+
+    public EnemyCollection Enemies {
+      get { return enemyCollectionView.Content; }
+      set { enemyCollectionView.Content = value; }
+    }
+
+    public BattleRunnerDialog(Solution solution) {
+      InitializeComponent();
+      errorProvider.SetIconAlignment(robocodePathTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconPadding(robocodePathTextBox, 2);
+      nrOfRoundsNumericUpDown.Maximum = int.MaxValue;
+      NrOfRounds = solution.NrOfRounds;
+      Enemies = (EnemyCollection)solution.Enemies.Clone(new Cloner());
+      robocodePathTextBox.Text = Enemies.RobocodePath;
+    }
+
+    private void searchButton_Click(object sender, System.EventArgs e) {
+      var result = folderBrowserDialog.ShowDialog(this);
+      if (result == DialogResult.OK)
+        Enemies.RobocodePath = robocodePathTextBox.Text = folderBrowserDialog.SelectedPath;
+    }
+
+    private void runInRobocodeButton_Click(object sender, System.EventArgs e) {
+      DialogResult = DialogResult.OK;
+      Close();
+    }
+
+    private void robocodePathTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      string robocodePath = robocodePathTextBox.Text;
+      if (string.IsNullOrEmpty(robocodePath)) {
+        e.Cancel = true;
+        errorProvider.SetError(robocodePathTextBox, "Robocode directory has to be set");
+        robocodePathTextBox.SelectAll();
+        return;
+      }
+      var info = new DirectoryInfo(robocodePath);
+      if (!info.Exists) {
+        e.Cancel = true;
+        errorProvider.SetError(robocodePathTextBox, "This directory does not exist");
+        robocodePathTextBox.SelectAll();
+        return;
+      }
+      Enemies.RobocodePath = robocodePathTextBox.Text;
+    }
+
+    private void robocodePathTextBox_Validated(object sender, System.EventArgs e) {
+      errorProvider.SetError(robocodePathTextBox, string.Empty);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.Designer.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.Designer.cs	(revision 13312)
@@ -0,0 +1,149 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  partial class CodeNodeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.prefixCode = new System.Windows.Forms.TextBox();
+      this.prefixLabel = new System.Windows.Forms.Label();
+      this.suffixLabel = new System.Windows.Forms.Label();
+      this.suffixCode = new System.Windows.Forms.TextBox();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // prefixCode
+      // 
+      this.prefixCode.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.prefixCode.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.prefixCode.Location = new System.Drawing.Point(6, 16);
+      this.prefixCode.Multiline = true;
+      this.prefixCode.Name = "prefixCode";
+      this.prefixCode.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+      this.prefixCode.Size = new System.Drawing.Size(573, 111);
+      this.prefixCode.TabIndex = 3;
+      this.prefixCode.Validated += new System.EventHandler(this.prefixCode_Validated);
+      // 
+      // prefixLabel
+      // 
+      this.prefixLabel.AutoSize = true;
+      this.prefixLabel.Location = new System.Drawing.Point(3, 0);
+      this.prefixLabel.Name = "prefixLabel";
+      this.prefixLabel.Size = new System.Drawing.Size(33, 13);
+      this.prefixLabel.TabIndex = 4;
+      this.prefixLabel.Text = "Prefix";
+      // 
+      // suffixLabel
+      // 
+      this.suffixLabel.AutoSize = true;
+      this.suffixLabel.Location = new System.Drawing.Point(3, 0);
+      this.suffixLabel.Name = "suffixLabel";
+      this.suffixLabel.Size = new System.Drawing.Size(33, 13);
+      this.suffixLabel.TabIndex = 5;
+      this.suffixLabel.Text = "Suffix";
+      // 
+      // suffixCode
+      // 
+      this.suffixCode.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.suffixCode.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.suffixCode.Location = new System.Drawing.Point(6, 16);
+      this.suffixCode.Multiline = true;
+      this.suffixCode.Name = "suffixCode";
+      this.suffixCode.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+      this.suffixCode.Size = new System.Drawing.Size(573, 108);
+      this.suffixCode.TabIndex = 6;
+      this.suffixCode.Validated += new System.EventHandler(this.suffixCode_Validated);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.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.splitContainer.Location = new System.Drawing.Point(6, 3);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.prefixCode);
+      this.splitContainer.Panel1.Controls.Add(this.prefixLabel);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.suffixCode);
+      this.splitContainer.Panel2.Controls.Add(this.suffixLabel);
+      this.splitContainer.Size = new System.Drawing.Size(582, 261);
+      this.splitContainer.SplitterDistance = 130;
+      this.splitContainer.TabIndex = 7;
+      // 
+      // CodeNodeView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "CodeNodeView";
+      this.Size = new System.Drawing.Size(591, 267);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.Panel2.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox prefixCode;
+    private System.Windows.Forms.Label prefixLabel;
+    private System.Windows.Forms.Label suffixLabel;
+    private System.Windows.Forms.TextBox suffixCode;
+    private System.Windows.Forms.SplitContainer splitContainer;
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/CodeSymbolView.cs	(revision 13312)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  [View("CodeSymbol View")]
+  [Content(typeof(CodeSymbol), IsDefaultView = true)]
+  public partial class CodeNodeView : ItemView {
+    public new CodeSymbol Content {
+      get { return (CodeSymbol)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public CodeNodeView()
+      : base() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        prefixCode.Text = string.Empty;
+        suffixCode.Text = string.Empty;
+      } else {
+        prefixCode.Text = Content.Prefix;
+        suffixCode.Text = Content.Suffix;
+      }
+    }
+
+    private void suffixCode_Validated(object sender, EventArgs e) {
+      Content.Suffix = suffixCode.Text;
+    }
+
+    private void prefixCode_Validated(object sender, EventArgs e) {
+      Content.Prefix = prefixCode.Text;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+
+      prefixCode.Enabled = Content != null && !Locked && !ReadOnly;
+      suffixCode.Enabled = Content != null && !Locked && !ReadOnly;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.Designer.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.Designer.cs	(revision 13312)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  partial class EnemyCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.reloadButton = new System.Windows.Forms.Button();
+      this.SuspendLayout();
+      // 
+      // reloadButton
+      // 
+      this.reloadButton.Location = new System.Drawing.Point(151, 3);
+      this.reloadButton.Name = "reloadButton";
+      this.reloadButton.Size = new System.Drawing.Size(24, 24);
+      this.reloadButton.TabIndex = 1;
+      this.reloadButton.UseVisualStyleBackColor = true;
+      this.reloadButton.Click += new System.EventHandler(this.reloadButton_Click);
+      this.reloadButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Refresh;
+      // 
+      // EnemyCollectionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      splitContainer.Panel1.Controls.Add(this.reloadButton);
+      this.Name = "EnemyCollectionView";
+      this.Size = new System.Drawing.Size(440, 275);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button reloadButton;
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/EnemyCollectionView.cs	(revision 13312)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  [View("EnemyCollection View")]
+  [Content(typeof(EnemyCollection), true)]
+  public partial class EnemyCollectionView : CheckedItemListView<StringValue> {
+    public new EnemyCollection Content {
+      get { return (EnemyCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public EnemyCollectionView() {
+      InitializeComponent();
+    }
+
+    private void reloadButton_Click(object sender, System.EventArgs e) {
+      Content.Clear();
+      Content.AddRange(EnemyCollection.ReloadEnemies(Content.RobocodePath));
+      foreach (var robot in Content) {
+        Content.SetItemCheckedState(robot, false);
+      }
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.Designer.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.Designer.cs	(revision 13312)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  partial class SolutionCodeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.programCode = new System.Windows.Forms.TextBox();
+      this.btnRunInRobocode = new System.Windows.Forms.Button();
+      this.btnSave = new System.Windows.Forms.Button();
+      this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+      this.SuspendLayout();
+      // 
+      // programCode
+      // 
+      this.programCode.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.programCode.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.programCode.Location = new System.Drawing.Point(3, 3);
+      this.programCode.Multiline = true;
+      this.programCode.Name = "programCode";
+      this.programCode.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+      this.programCode.Size = new System.Drawing.Size(345, 203);
+      this.programCode.TabIndex = 0;
+      // 
+      // btnRunInRobocode
+      // 
+      this.btnRunInRobocode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.btnRunInRobocode.AutoSize = true;
+      this.btnRunInRobocode.Location = new System.Drawing.Point(247, 212);
+      this.btnRunInRobocode.Name = "btnRunInRobocode";
+      this.btnRunInRobocode.Size = new System.Drawing.Size(101, 23);
+      this.btnRunInRobocode.TabIndex = 2;
+      this.btnRunInRobocode.Text = "Run in Robocode";
+      this.btnRunInRobocode.UseVisualStyleBackColor = true;
+      this.btnRunInRobocode.Click += new System.EventHandler(this.btnRunInRobocode_Click);
+      // 
+      // btnSave
+      // 
+      this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.btnSave.AutoSize = true;
+      this.btnSave.Location = new System.Drawing.Point(166, 212);
+      this.btnSave.Name = "btnSave";
+      this.btnSave.Size = new System.Drawing.Size(75, 23);
+      this.btnSave.TabIndex = 1;
+      this.btnSave.Text = "Save...";
+      this.btnSave.UseVisualStyleBackColor = true;
+      this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
+      // 
+      // saveFileDialog
+      // 
+      this.saveFileDialog.DefaultExt = "java";
+      this.saveFileDialog.Filter = "Java |*java";
+      // 
+      // SolutionCodeView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.btnSave);
+      this.Controls.Add(this.btnRunInRobocode);
+      this.Controls.Add(this.programCode);
+      this.Name = "SolutionCodeView";
+      this.Size = new System.Drawing.Size(351, 238);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox programCode;
+    private System.Windows.Forms.Button btnRunInRobocode;
+    private System.Windows.Forms.Button btnSave;
+    private System.Windows.Forms.SaveFileDialog saveFileDialog;
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionCodeView.cs	(revision 13312)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.IO;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  [View("Robocode Tank Code View")]
+  [Content(typeof(Solution), IsDefaultView = true)]
+  public partial class SolutionCodeView : ItemView {
+    private const string programName = "BestSolution";
+
+    public new Solution Content {
+      get { return (Solution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public SolutionCodeView()
+      : base() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      programCode.Text = Content == null ? string.Empty : Interpreter.InterpretProgramTree(Content.Tree.Root, programName);
+    }
+
+    private void btnSave_Click(object sender, EventArgs e) {
+      saveFileDialog.FileName = programName;
+      var result = saveFileDialog.ShowDialog(this);
+      if (result == DialogResult.OK)
+        File.WriteAllText(saveFileDialog.FileName, programCode.Text);
+    }
+
+    private void btnRunInRobocode_Click(object sender, EventArgs e) {
+      using (var battleRunnerDlg = new BattleRunnerDialog(Content)) {
+        var result = battleRunnerDlg.ShowDialog(this);
+        if (result == DialogResult.OK) {
+          var enemies = battleRunnerDlg.Enemies;
+          string path = enemies.RobocodePath;
+          int nrOfRounds = battleRunnerDlg.NrOfRounds;
+          Interpreter.EvaluateTankProgram(Content.Tree, path, enemies, programName, true, nrOfRounds);
+        }
+      }
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.Designer.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.Designer.cs	(revision 13312)
@@ -0,0 +1,55 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  partial class SolutionProgramView {
+    private void InitializeComponent() {
+      this.graphTreeView = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.GraphicalSymbolicExpressionTreeView();
+      this.SuspendLayout();
+      // 
+      // graphTreeView
+      // 
+      this.graphTreeView.AllowDrop = true;
+      this.graphTreeView.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.graphTreeView.Caption = "Graphical SymbolicExpressionTree View";
+      this.graphTreeView.Content = null;
+      this.graphTreeView.Location = new System.Drawing.Point(6, 3);
+      this.graphTreeView.Name = "graphTreeView";
+      this.graphTreeView.ReadOnly = false;
+      this.graphTreeView.Size = new System.Drawing.Size(342, 213);
+      this.graphTreeView.TabIndex = 0;
+      // 
+      // SolutionProgramView
+      // 
+      this.Controls.Add(this.graphTreeView);
+      this.Name = "SolutionProgramView";
+      this.Size = new System.Drawing.Size(351, 219);
+      this.ResumeLayout(false);
+
+    }
+
+    private GraphicalSymbolicExpressionTreeView graphTreeView;
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming.Views/3.3/Robocode/SolutionProgramView.cs	(revision 13312)
@@ -0,0 +1,44 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Views.Robocode {
+  [View("Robocode Tank Program Tree View")]
+  [Content(typeof(Solution), IsDefaultView = false)]
+  public sealed partial class SolutionProgramView : ItemView {
+    public new Solution Content {
+      get { return (Solution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public SolutionProgramView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      graphTreeView.Content = Content == null ? null : Content.Tree;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/HeuristicLab.Problems.GeneticProgramming-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/HeuristicLab.Problems.GeneticProgramming-3.3.csproj	(revision 13311)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/HeuristicLab.Problems.GeneticProgramming-3.3.csproj	(revision 13312)
@@ -104,4 +104,6 @@
     </Reference>
     <Reference Include="System.Drawing" />
+    <Reference Include="System.IO.Compression" />
+    <Reference Include="System.IO.Compression.FileSystem" />
   </ItemGroup>
   <ItemGroup>
@@ -117,4 +119,16 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="robocode\EnemyCollection.cs" />
+    <Compile Include="robocode\Grammar.cs" />
+    <Compile Include="robocode\Interpreter.cs" />
+    <Compile Include="robocode\Problem.cs" />
+    <Compile Include="robocode\Solution.cs" />
+    <Compile Include="robocode\Symbols\BooleanTreeNode.cs" />
+    <Compile Include="robocode\Symbols\BooleanValue.cs" />
+    <Compile Include="robocode\Symbols\CodeSymbol.cs" />
+    <Compile Include="robocode\Symbols\Number.cs" />
+    <Compile Include="robocode\Symbols\NumberTreeNode.cs" />
+    <Compile Include="robocode\Symbols\ShotPower.cs" />
+    <Compile Include="robocode\Symbols\ShotPowerTreeNode.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -122,4 +136,13 @@
     <None Include="Plugin.cs.frame" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
+    <None Include="robocode\BattleObserver.class">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="robocode\BattleRunner.class">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="robocode\robocode.zip">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
   <ItemGroup>
@@ -211,4 +234,7 @@
       <Install>true</Install>
     </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="robocode\BattleRunner.java" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/Plugin.cs.frame	(revision 13311)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/Plugin.cs.frame	(revision 13312)
@@ -21,6 +21,7 @@
 
 using System;
-using System.Collections.Generic;
-using System.Text;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
 using HeuristicLab.PluginInfrastructure;
 
@@ -28,4 +29,7 @@
   [Plugin("HeuristicLab.Problems.GeneticProgramming","Provides implementations for genetic programming problems such as the artificial ant problem.", "3.3.0.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.GeneticProgramming-3.3.dll", PluginFileType.Assembly)]
+  [PluginFile("Robocode/robocode.zip", PluginFileType.Data)]
+  [PluginFile("Robocode/BattleRunner.class", PluginFileType.Data)]
+  [PluginFile("Robocode/BattleObserver.class", PluginFileType.Data)]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
@@ -41,4 +45,10 @@
   [PluginDependency("HeuristicLab.Random", "3.3")]
   public class HeuristicLabProblemsGeneticProgrammingPlugin : PluginBase {
+    public override void OnLoad() {
+        base.OnLoad();
+        if (!Directory.EnumerateDirectories(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("Robocode", "libs"), SearchOption.TopDirectoryOnly).Any()) {
+          ZipFile.ExtractToDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("Robocode", "robocode.zip")), AppDomain.CurrentDomain.BaseDirectory);
+        }
+      }
   }
 }
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/BattleRunner.java
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/BattleRunner.java	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/BattleRunner.java	(revision 13312)
@@ -0,0 +1,117 @@
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import robocode.control.*;
+import robocode.control.events.*;
+import java.util.*;
+
+//
+// Add this file to the HL bin folder. Compile it with the following command:
+// javac -cp c:\robocode\libs\robocode.jar BattleRunner.java
+//
+public class BattleRunner {
+  public static String player = "Evaluation.output*";    
+  public static List<Double> score = new ArrayList<Double>();
+
+  // This program requires 5 arguments: 
+  // The first argument is the name of the robot.
+  // The second argument is the path to the robocode installation. If not give, c:\robocode is assumed. 
+  // The third argument: true if Robocode should be shown, otherwise it is hidden. 
+  // The fourth argument is the number of rounds. 
+  // The remaining arguments are the names of the opponents. At least 1 must be provided. 
+  public static void main(String[] args) {
+    if (args.length < 5)
+      System.exit(-1);  
+
+    String roboCodePath = "C:\\robocode";
+    Boolean visible = false;
+    String bots = "";
+    int numberOfRounds = 3;
+    String[] robots = new String[1 + args.length - 4];
+
+    player = robots[0] = args[0];
+    roboCodePath = args[1];
+    visible = Boolean.valueOf(args[2]);
+    numberOfRounds = Integer.valueOf(args[3]);
+    for (int i = 4; i < args.length; i++) {
+      robots[i - 3] = args[i];
+    }
+
+    RobocodeEngine.setLogMessagesEnabled(false);
+    RobocodeEngine engine = new RobocodeEngine(new java.io.File(roboCodePath));
+    engine.setVisible(visible);
+    engine.addBattleListener(new BattleObserver());
+
+    BattlefieldSpecification battlefield = new BattlefieldSpecification(800, 600);
+    RobotSpecification[] all = engine.getLocalRepository();
+    List<RobotSpecification> selectedRobots = new ArrayList<RobotSpecification>();
+    
+    for(RobotSpecification rs : all) {
+      for(String r : robots) {
+        if(r.equals(rs.getClassName())) {
+          selectedRobots.add(rs);
+        }
+      }
+    }
+
+    for (int i = 1; i < selectedRobots.size(); i++) {
+      BattleSpecification battleSpec = new BattleSpecification(numberOfRounds, battlefield, new RobotSpecification[] { selectedRobots.get(0), selectedRobots.get(i) });
+
+      // run our specified battle and wait till the battle finishes
+      engine.runBattle(battleSpec, true);
+    }
+    engine.close();
+
+    // print out result which is then parsed by HeuristicLab
+    System.out.println(avg(score));
+    System.exit(0);
+  }
+
+  private static double avg(List <Double> lst) {
+    double sum = 0;
+    for (double val : lst) {
+      sum += val;
+    }
+    return sum / lst.size();
+  }
+}
+
+//
+// The battle listener for handling the battle event we are interested in.
+//
+class BattleObserver extends BattleAdaptor {
+  public void onBattleCompleted(BattleCompletedEvent e) {
+    double robotScore = -1.0;
+    double opponentScore = -1.0;
+    
+        for (robocode.BattleResults result : e.getSortedResults()) {
+            if (result.getTeamLeaderName().contains(BattleRunner.player)) 
+                robotScore = result.getScore();
+            else
+                opponentScore = result.getScore();
+        }
+    
+    //prevent div / 0 which can happen if both robots do not score
+    if((robotScore + opponentScore) == 0) {
+      BattleRunner.score.add(0.0);
+    } else {
+      BattleRunner.score.add(robotScore / (robotScore + opponentScore));
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/EnemyCollection.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/EnemyCollection.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/EnemyCollection.cs	(revision 13312)
@@ -0,0 +1,85 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [Item("EnemyCollection", "A collection of enemy robots for the Robocode genetic programming problem.")]
+  [StorableClass]
+  public class EnemyCollection : CheckedItemList<StringValue> {
+    private const string sampleRobotToSelect = "sample.Crazy";
+
+    [Storable]
+    public string RobocodePath { get; set; }
+
+    [StorableConstructor]
+    protected EnemyCollection(bool deserializing) : base(deserializing) { }
+    protected EnemyCollection(EnemyCollection original, Cloner cloner)
+      : base(original, cloner) {
+      RobocodePath = original.RobocodePath;
+    }
+    public EnemyCollection() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EnemyCollection(this, cloner);
+    }
+
+    public static EnemyCollection ReloadEnemies(string robocodeDir) {
+      EnemyCollection robotList = new EnemyCollection();
+
+      try {
+        var robotsDir = new DirectoryInfo(Path.Combine(robocodeDir, "robots"));
+        var robotFiles = robotsDir.GetFiles("*", SearchOption.AllDirectories)
+          .Where(x => x.Extension == ".class" || x.Extension == ".jar");
+        var robotSet = new Dictionary<string, StringValue>();
+        foreach (var robot in robotFiles) {
+          string robotName = Path.Combine(robot.DirectoryName, Path.GetFileNameWithoutExtension(robot.FullName));
+          robotName = robotName.Remove(0, robotsDir.FullName.Length);
+          string[] nameParts = robotName.Split(new[] { Path.DirectorySeparatorChar },
+            StringSplitOptions.RemoveEmptyEntries);
+          robotName = string.Join(".", nameParts);
+          robotSet[robot.FullName] = new StringValue(robotName);
+        }
+        robotList.AddRange(robotSet.Values);
+
+        foreach (var robot in robotList) {
+          robotList.SetItemCheckedState(robot, false);
+        }
+      }
+      catch { }
+
+      //select one robot so that if a user tries out the Robocode problem it works with the default settings
+      if (robotList.Exists(x => x.Value == sampleRobotToSelect)) {
+        StringValue sampleRobot = robotList.Single(x => x.Value == sampleRobotToSelect);
+        robotList.SetItemCheckedState(sampleRobot, true);
+      }
+
+      return robotList;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Grammar.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Grammar.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Grammar.cs	(revision 13312)
@@ -0,0 +1,224 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  [Item("Robocode Grammar", "The grammar for the Robocode GP problem.")]
+  public class Grammar : SymbolicExpressionGrammar {
+    private const string EventsName = "Events";
+    private const string ExpressionsName = "Expressions";
+    private const string ControlStatementsName = "Control Statements";
+    private const string RobocodeFunctionsName = "Robocode Functions";
+    private const string RobocodeActionsName = "Robocode Actions";
+    private const string RelationalOperatorsName = "Relational Operators";
+    private const string LogicalOperators = "Logical Operators";
+    private const string NumericalOperatorsName = "Numerical Operators";
+
+    [StorableConstructor]
+    protected Grammar(bool deserializing) : base(deserializing) { }
+    protected Grammar(Grammar original, Cloner cloner) : base(original, cloner) { }
+
+    public Grammar()
+      : base("Robocode Grammar", "The grammar for the Robocode GP problem.") {
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Grammar(this, cloner);
+    }
+
+    // initialize set of allowed symbols and define 
+    // the allowed combinations of symbols
+    private void Initialize() {
+      #region Symbols
+      var block = new SimpleSymbol("Block", "A group of statements", 1, byte.MaxValue);
+      var stat = new SimpleSymbol("Statement", "A statement.", 1, 1);
+      var ifThenElseStat = new SimpleSymbol("IfThenElseStat", "An if statement.", 2, 3);
+      var whileStat = new SimpleSymbol("WhileStat", "A while statement.", 2, 2);
+      whileStat.Enabled = false;
+
+      var boolExpr = new SimpleSymbol("BooleanExpression", "A Boolean expression.", 1, 1);
+      var numericalExpr = new SimpleSymbol("NumericalExpression", "A numerical expression.", 1, 1);
+
+      var equal = new SimpleSymbol("Equal", "Equal comparator.", 2, 2);
+      var lessThan = new SimpleSymbol("LessThan", "LessThan comparator.", 2, 2);
+      var lessThanOrEqual = new SimpleSymbol("LessThanOrEqual", "LessThanOrEqual comparator.", 2, 2);
+      var greaterThan = new SimpleSymbol("GreaterThan", "GreaterThan comparator.", 2, 2);
+      var greaterThanOrEqual = new SimpleSymbol("GreaterThanOrEqual", "GreaterThanOrEqual comparator.", 2, 2);
+
+      var conjunction = new SimpleSymbol("ConditionalAnd", "Conjunction comparator.", 2, byte.MaxValue);
+      var disjunction = new SimpleSymbol("ConditionalOr", "Disjunction comparator.", 2, byte.MaxValue);
+      var negation = new SimpleSymbol("Negation", "A negation.", 1, 1);
+
+      var addition = new SimpleSymbol("Addition", "Addition operator.", 2, byte.MaxValue);
+      var subtraction = new SimpleSymbol("Subtraction", "Subtraction operator.", 2, byte.MaxValue);
+      var multiplication = new SimpleSymbol("Multiplication", "Multiplication operator.", 2, byte.MaxValue);
+      var division = new SimpleSymbol("Division", "Division operator.", 2, byte.MaxValue);
+      var modulus = new SimpleSymbol("Modulus", "Modulus operator.", 2, byte.MaxValue);
+
+      var number = new Number();
+      var logicalVal = new BooleanValue();
+
+      var ahead = new SimpleSymbol("Ahead", "Immediately moves your robot ahead (forward) by distance measured in pixels.", 1, 1);
+      var back = new SimpleSymbol("Back", "Immediately moves your robot backward by distance measured in pixels.", 1, 1);
+      var fire = new SimpleSymbol("Fire", "Immediately fires a bullet.", 1, 1);
+      var shotPower = new ShotPower();
+
+      var getEnergy = new SimpleSymbol("GetEnergy", "Returns the robot's current energy.", 0, 0);
+      var getHeading = new SimpleSymbol("GetHeading", "Returns the direction that the robot's body is facing, in degrees.", 0, 0);
+      var getGunHeading = new SimpleSymbol("GetGunHeading", "Returns the direction that the robot's gun is facing, in degrees.", 0, 0);
+      var getRadarHeading = new SimpleSymbol("GetRadarHeading", "Returns the direction that the robot's radar is facing, in degrees.", 0, 0);
+      var getX = new SimpleSymbol("GetX", "Returns the X position of the robot. (0,0) is at the bottom left of the battlefield.", 0, 0);
+      var getY = new SimpleSymbol("GetY", "Returns the Y position of the robot. (0,0) is at the bottom left of the battlefield.", 0, 0);
+
+      var turnLeft = new SimpleSymbol("TurnLeft", "Immediately turns the robot's body to the left by degrees.", 1, 1);
+      var turnRight = new SimpleSymbol("TurnRight", "Immediately turns the robot's body to the right by degrees.", 1, 1);
+      var turnGunLeft = new SimpleSymbol("TurnGunLeft", "Immediately turns the robot's gun to the left by degrees.", 1, 1);
+      var turnGunRight = new SimpleSymbol("TurnGunRight", "Immediately turns the robot's gun to the right by degrees.", 1, 1);
+      var turnRadarLeft = new SimpleSymbol("TurnRadarLeft", "Immediately turns the robot's radar to the left by degrees.", 1, 1);
+      var turnRadarRight = new SimpleSymbol("TurnRadarRight", "Immediately turns the robot's radar to the right by degrees.", 1, 1);
+
+      var onBulletHit = new SimpleSymbol("OnBulletHit", "This method is called when one of your bullets hits another robot.", 2, 10);
+      var onBulletMissed = new SimpleSymbol("OnBulletMissed", "This method is called when one of your bullets misses, i.e. hits a wall.", 2, 10);
+      var onHitByBullet = new SimpleSymbol("OnHitByBullet", "This method is called when your robot is hit by a bullet.", 2, 10);
+      var onHitRobot = new SimpleSymbol("OnHitRobot", "This method is called when your robot collides with another robot.", 2, 10);
+      var onHitWall = new SimpleSymbol("OnHitWall", "This method is called when your robot collides with a wall.", 2, 10);
+      var onScannedRobot = new SimpleSymbol("OnScannedRobot", "This method is called when your robot sees another robot, i.e. when the robot's radar scan \"hits\" another robot.", 2, 10);
+
+      var run = new SimpleSymbol("Run", "The main method in every robot.", 1, 10);
+      var tank = new SimpleSymbol("Tank", "The root of a Robocode Tank program.", 2, 7);
+
+      var doNothing = new SimpleSymbol("DoNothing", "Do nothing this turn, meaning that the robot will skip its turn.", 0, 0);
+      var emptyEvent = new SimpleSymbol("EmptyEvent", "This is a placeholder for an empty event.", 0, 0);
+      #endregion
+
+      #region Symbol Collections
+      var controlSymbols = new ISymbol[] { ifThenElseStat, whileStat };
+      var actionSymbols = new ISymbol[] {
+        ahead, back, fire, turnGunLeft, turnGunRight, turnLeft, turnRadarLeft, turnRadarRight, turnRight
+      };
+      var functionSymbols = new ISymbol[] {
+        getEnergy, getGunHeading, getHeading, getRadarHeading, getX, getY
+      };
+
+      var events = new GroupSymbol(EventsName, new ISymbol[] { run, onScannedRobot, onBulletHit, onBulletMissed, onHitByBullet, onHitRobot, onHitWall });
+      var controlStatements = new GroupSymbol(ControlStatementsName, controlSymbols);
+      var expressions = new GroupSymbol(ExpressionsName, new ISymbol[] { boolExpr, numericalExpr });
+      var robocodeFunctions = new GroupSymbol(RobocodeFunctionsName, functionSymbols);
+      var robocodeActions = new GroupSymbol(RobocodeActionsName, actionSymbols);
+      var relationalOperators = new GroupSymbol(RelationalOperatorsName, new ISymbol[] { equal, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual });
+      var logicalOperators = new GroupSymbol(LogicalOperators, new ISymbol[] { conjunction, disjunction, negation });
+      var numericalOperators = new GroupSymbol(NumericalOperatorsName, new ISymbol[] { addition, subtraction, multiplication, division, modulus });
+      #endregion
+
+      #region Adding Symbols
+      AddSymbol(tank);
+      AddSymbol(stat);
+      AddSymbol(block);
+      AddSymbol(shotPower);
+      AddSymbol(number);
+      AddSymbol(logicalVal);
+      AddSymbol(events);
+      AddSymbol(expressions);
+      AddSymbol(controlStatements);
+      AddSymbol(robocodeFunctions);
+      AddSymbol(robocodeActions);
+      AddSymbol(relationalOperators);
+      AddSymbol(logicalOperators);
+      AddSymbol(numericalOperators);
+      AddSymbol(emptyEvent);
+      AddSymbol(doNothing);
+      #endregion
+
+      #region Grammar Definition
+      // StartSymbol
+      AddAllowedChildSymbol(StartSymbol, tank);
+
+      // Tank
+      AddAllowedChildSymbol(tank, run, 0);
+      AddAllowedChildSymbol(tank, onScannedRobot, 1);
+      AddAllowedChildSymbol(tank, onBulletHit, 2);
+      AddAllowedChildSymbol(tank, onBulletMissed, 3);
+      AddAllowedChildSymbol(tank, onHitByBullet, 4);
+      AddAllowedChildSymbol(tank, onHitRobot, 5);
+      AddAllowedChildSymbol(tank, onHitWall, 6);
+
+      // Events
+      AddAllowedChildSymbol(events, stat);
+
+      // Block
+      AddAllowedChildSymbol(block, stat);
+
+      // Stat
+      AddAllowedChildSymbol(stat, stat);
+      AddAllowedChildSymbol(stat, block);
+      AddAllowedChildSymbol(stat, controlStatements);
+      AddAllowedChildSymbol(stat, robocodeFunctions);
+      AddAllowedChildSymbol(stat, robocodeActions);
+      AddAllowedChildSymbol(stat, emptyEvent);
+      AddAllowedChildSymbol(stat, doNothing);
+
+      // IfStat
+      AddAllowedChildSymbol(ifThenElseStat, boolExpr, 0);
+      AddAllowedChildSymbol(ifThenElseStat, stat, 1);
+      AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 1);
+      AddAllowedChildSymbol(ifThenElseStat, doNothing, 1);
+      AddAllowedChildSymbol(ifThenElseStat, stat, 2);
+      AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 2);
+      AddAllowedChildSymbol(ifThenElseStat, doNothing, 2);
+
+      // WhileStat
+      AddAllowedChildSymbol(whileStat, boolExpr, 0);
+      AddAllowedChildSymbol(whileStat, stat, 1);
+      AddAllowedChildSymbol(whileStat, emptyEvent, 1);
+      AddAllowedChildSymbol(whileStat, doNothing, 1);
+
+      // Numerical Expressions
+      AddAllowedChildSymbol(numericalExpr, number);
+      AddAllowedChildSymbol(numericalExpr, robocodeFunctions);
+      AddAllowedChildSymbol(numericalExpr, numericalOperators);
+      AddAllowedChildSymbol(numericalOperators, number);
+      AddAllowedChildSymbol(numericalOperators, robocodeFunctions);
+      AddAllowedChildSymbol(numericalOperators, numericalOperators);
+
+      // Logical Expressions
+      AddAllowedChildSymbol(boolExpr, logicalVal);
+      AddAllowedChildSymbol(boolExpr, logicalOperators);
+      AddAllowedChildSymbol(logicalOperators, logicalVal);
+      AddAllowedChildSymbol(logicalOperators, logicalOperators);
+      AddAllowedChildSymbol(logicalOperators, relationalOperators);
+      AddAllowedChildSymbol(relationalOperators, numericalExpr);
+
+      // Functions and Actions
+      AddAllowedChildSymbol(robocodeFunctions, numericalExpr);
+      foreach (var a in robocodeActions.Symbols) {
+        if (a.Name == fire.Name) AddAllowedChildSymbol(a, shotPower);
+        else AddAllowedChildSymbol(a, numericalExpr);
+      }
+      #endregion
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Interpreter.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Interpreter.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Interpreter.cs	(revision 13312)
@@ -0,0 +1,404 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  public static class Interpreter {
+
+    // necessary for synchronization to guarantee that only one robocode program is executed at the same time
+    // NOTE: this does not guarantee OS-wide mutual exclusion, but we ignore that for now
+    private static readonly object syncRoot = new object();
+
+    // TODO performance: it would probably be useful to implement the BattleRunner in such a way that we don't have to restart the java process each time, e.g. using console IO to load & run robots 
+    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3) {
+      if (robotName == null)
+        robotName = GenerateRobotName();
+
+      string interpretedProgram = InterpretProgramTree(tree.Root, robotName);
+      string battleRunnerPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "robocode");
+      string roboCodeLibPath = Path.Combine(path, "libs");
+      string robocodeJar = Path.Combine(roboCodeLibPath, "robocode.jar");
+      string robocodeCoreJar = GetFileName(roboCodeLibPath, "robocode.core*");
+      string picocontainerJar = GetFileName(roboCodeLibPath, "picocontainer*");
+      string robotsPath = Path.Combine(path, "robots", "Evaluation");
+      string srcRobotPath = Path.Combine(robotsPath, robotName + ".java");
+
+      File.WriteAllText(srcRobotPath, interpretedProgram, System.Text.Encoding.Default);
+
+      // compile java source to class file
+      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
+      javaCompileInfo.FileName = "cmd.exe";
+      javaCompileInfo.Arguments = "/C javac -cp " + robocodeJar + "; " + srcRobotPath;
+      javaCompileInfo.RedirectStandardOutput = true;
+      javaCompileInfo.RedirectStandardError = true;
+      javaCompileInfo.UseShellExecute = false;
+      javaCompileInfo.CreateNoWindow = true;
+
+      // it's ok to compile multiple robocode programs concurrently
+      using (Process javaCompile = new Process()) {
+        javaCompile.StartInfo = javaCompileInfo;
+        javaCompile.Start();
+
+        string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
+        cmdOutput += javaCompile.StandardError.ReadToEnd();
+
+        javaCompile.WaitForExit();
+        if (javaCompile.ExitCode != 0) {
+          DeleteRobotFiles(path, robotName);
+          throw new Exception("Compile Error: " + cmdOutput);
+        }
+      }
+
+      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
+
+      // execute a battle with numberOfRounds against a number of enemies
+      // TODO: seems there is a bug when selecting multiple enemies
+      evaluateCodeInfo.FileName = "cmd.exe";
+      var classpath = string.Join(";", new[] { battleRunnerPath, robocodeCoreJar, robocodeJar, picocontainerJar });
+      var enemyRobotNames = string.Join(" ", enemies.CheckedItems.Select(i => i.Value));
+      evaluateCodeInfo.Arguments = string.Format("/C java -cp {0} BattleRunner Evaluation.{1} {2} {3} {4} {5}", classpath, robotName, path, showUI, nrOfRounds, enemyRobotNames);
+
+      evaluateCodeInfo.RedirectStandardOutput = true;
+      evaluateCodeInfo.RedirectStandardError = true;
+      evaluateCodeInfo.UseShellExecute = false;
+      evaluateCodeInfo.CreateNoWindow = true;
+
+      // the robocode framework writes state to a file therefore parallel evaluation of multiple robocode programs is not possible yet.
+      double evaluation;
+      lock (syncRoot) {
+        using (Process evaluateCode = new Process()) {
+          evaluateCode.StartInfo = evaluateCodeInfo;
+          evaluateCode.Start();
+          evaluateCode.WaitForExit();
+
+          if (evaluateCode.ExitCode != 0) {
+            DeleteRobotFiles(path, robotName);
+            throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd() +
+                                Environment.NewLine +
+                                evaluateCode.StandardOutput.ReadToEnd());
+          }
+
+          try {
+            string scoreString =
+              evaluateCode.StandardOutput.ReadToEnd()
+                .Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
+                .Last();
+            evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
+          }
+          catch (Exception ex) {
+            throw new Exception("Error parsing score string: " + ex);
+          }
+          finally {
+            DeleteRobotFiles(path, robotName);
+          }
+        }
+      }
+
+      return evaluation;
+    }
+
+    private static void DeleteRobotFiles(string path, string outputname) {
+      File.Delete(path + @"\robots\Evaluation\" + outputname + ".java");
+      File.Delete(path + @"\robots\Evaluation\" + outputname + ".class");
+    }
+
+    private static string GetFileName(string path, string pattern) {
+      string fileName = string.Empty;
+      try {
+        fileName = Directory.GetFiles(path, pattern).First();
+      }
+      catch {
+        throw new Exception("Error finding required Robocode files.");
+      }
+      return fileName;
+    }
+
+    private static string GenerateRobotName() {
+      // Robocode class names are 32 char max and 
+      // Java class names have to start with a letter
+      string outputname = Guid.NewGuid().ToString();
+      outputname = outputname.Remove(8, 1);
+      outputname = outputname.Remove(12, 1);
+      outputname = outputname.Remove(16, 1);
+      outputname = outputname.Remove(20, 1);
+      outputname = outputname.Remove(0, 1);
+      outputname = outputname.Insert(0, "R");
+      return outputname;
+    }
+
+    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) {
+      var tankNode = node;
+      while (tankNode.Symbol.Name != "Tank")
+        tankNode = tankNode.GetSubtree(0);
+
+      string result = Interpret(tankNode);
+      result = result.Replace("class output", "class " + robotName);
+      return result;
+    }
+
+    private static string Interpret(ISymbolicExpressionTreeNode node) {
+      switch (node.Symbol.Name) {
+        case "Block": return InterpretBlock(node);
+        case "Statement": return InterpretStat(node);
+        case "DoNothing": return string.Empty;
+        case "EmptyEvent": return string.Empty;
+
+        case "GetEnergy": return "getEnergy()";
+        case "GetHeading": return "getHeading()";
+        case "GetGunHeading": return "getGunHeading()";
+        case "GetRadarHeading": return "getRadarHeading()";
+        case "GetX": return "getX()";
+        case "GetY": return "getY()";
+
+        case "Addition": return InterpretBinaryOperator(" + ", node);
+        case "Subtraction": return InterpretBinaryOperator(" - ", node);
+        case "Multiplication": return InterpretBinaryOperator(" * ", node);
+        case "Division": return InterpretBinaryOperator(" / ", node);
+        case "Modulus": return InterpretBinaryOperator(" % ", node);
+
+        case "Equal": return InterpretComparison(" == ", node);
+        case "LessThan": return InterpretComparison(" < ", node);
+        case "LessThanOrEqual": return InterpretComparison(" <= ", node);
+        case "GreaterThan": return InterpretComparison("  >", node);
+        case "GreaterThanOrEqual": return InterpretComparison(" >= ", node);
+        case "ConditionalAnd": return InterpretBinaryOperator(" && ", node);
+        case "ConditionalOr": return InterpretBinaryOperator(" || ", node);
+        case "Negation": return InterpretFunc1("!", node);
+
+        case "IfThenElseStat": return InterpretIf(node);
+        case "WhileStat": return InterpretWhile(node);
+        case "BooleanExpression": return InterpretChild(node);
+        case "NumericalExpression": return InterpretChild(node);
+        case "Number": return InterpretNumber(node);
+        case "BooleanValue": return InterpretBoolValue(node);
+
+
+        case "Ahead": return InterpretFunc1("setAhead", node);
+        case "Back": return InterpretFunc1("setBack", node);
+        case "Fire": return InterpretFunc1("setFire", node);
+        case "TurnLeft": return InterpretFunc1("setTurnLeft", node);
+        case "TurnRight": return InterpretFunc1("setTurnRight", node);
+        case "TurnGunLeft": return InterpretFunc1("setTurnGunLeft", node);
+        case "TurnGunRight": return InterpretFunc1("setTurnGunRight", node);
+        case "TurnRadarLeft": return InterpretFunc1("setTurnRadarLeft", node);
+        case "TurnRadarRight": return InterpretFunc1("setTurnRadarRight", node);
+        case "ShotPower": return InterpetShotPower(node);
+
+        case "OnBulletHit": return InterpretOnBulletHit(node);
+        case "OnBulletMissed": return InterpretOnBulletMissed(node);
+        case "OnHitByBullet": return InterpretOnHitByBullet(node);
+        case "OnHitRobot": return InterpretOnHitRobot(node);
+        case "OnHitWall": return InterpretOnHitWall(node);
+        case "OnScannedRobot": return InterpretOnScannedRobot(node);
+
+        case "Run": return InterpretRun(node);
+        case "Tank": return InterpretTank(node);
+        case "CodeSymbol": return InterpretCodeSymbol(node);
+
+        default: throw new ArgumentException(string.Format("Found an unknown symbol {0} in a robocode solution", node.Symbol.Name));
+      }
+    }
+
+    private static string InterpretCodeSymbol(ISymbolicExpressionTreeNode node) {
+      var sy = (CodeSymbol)node.Symbol;
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return sy.Prefix + Environment.NewLine + code + Environment.NewLine + sy.Suffix;
+    }
+
+    private static string InterpretBoolValue(ISymbolicExpressionTreeNode node) {
+      var boolNode = (BooleanTreeNode)node;
+      return string.Format(NumberFormatInfo.InvariantInfo, "{0}", boolNode.Value).ToLower();
+    }
+
+    private static string InterpretNumber(ISymbolicExpressionTreeNode node) {
+      var numberNode = (NumberTreeNode)node;
+      return string.Format(NumberFormatInfo.InvariantInfo, "{0}", numberNode.Value);
+    }
+
+    private static string InterpetShotPower(ISymbolicExpressionTreeNode node) {
+      var shotPowerNode = (ShotPowerTreeNode)node;
+      return string.Format(NumberFormatInfo.InvariantInfo, "{0:E}", shotPowerNode.Value);
+    }
+
+
+    internal static string InterpretBlock(ISymbolicExpressionTreeNode node) {
+      string result = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format("{{ {0} }}", result + Environment.NewLine);
+    }
+
+    internal static string InterpretStat(ISymbolicExpressionTreeNode node) {
+      // must only have one sub-tree
+      Contract.Assert(node.SubtreeCount == 1);
+      return Interpret(node.GetSubtree(0)) + " ;" + Environment.NewLine;
+    }
+
+    internal static string InterpretIf(ISymbolicExpressionTreeNode node) {
+      ISymbolicExpressionTreeNode condition = null, truePart = null, falsePart = null;
+      string[] parts = new string[3];
+
+      if (node.SubtreeCount < 2 || node.SubtreeCount > 3)
+        throw new Exception("Unexpected number of children. Expected 2 or 3 children.");
+
+      condition = node.GetSubtree(0);
+      truePart = node.GetSubtree(1);
+      if (node.SubtreeCount == 3)
+        falsePart = node.GetSubtree(2);
+
+      parts[0] = Interpret(condition);
+      parts[1] = Interpret(truePart);
+      if (falsePart != null) parts[2] = Interpret(falsePart);
+
+      return string.Format("if ({0}) {{ {1} }} else {{ {2} }}", Interpret(condition), Interpret(truePart),
+        falsePart == null ? string.Empty : Interpret(falsePart));
+    }
+
+    internal static string InterpretWhile(ISymbolicExpressionTreeNode node) {
+      var cond = Interpret(node.GetSubtree(0));
+      var body = Interpret(node.GetSubtree(1));
+      return string.Format("while ({0}) {{ {2} {1} {2} }} {2}", cond, body, Environment.NewLine);
+    }
+
+    public static string InterpretBinaryOperator(string opSy, ISymbolicExpressionTreeNode node) {
+      if (node.SubtreeCount < 2)
+        throw new ArgumentException(string.Format("Expected at least two children in {0}.", node.Symbol), "node");
+
+      string result = string.Join(opSy, node.Subtrees.Select(Interpret));
+      return "(" + result + ")";
+    }
+
+    public static string InterpretChild(ISymbolicExpressionTreeNode node) {
+      if (node.SubtreeCount != 1)
+        throw new ArgumentException(string.Format("Expected exactly one child in {0}.", node.Symbol), "node");
+
+      return Interpret(node.GetSubtree(0));
+    }
+
+    public static string InterpretComparison(string compSy, ISymbolicExpressionTreeNode node) {
+      ISymbolicExpressionTreeNode lhs = null, rhs = null;
+      if (node.SubtreeCount != 2)
+        throw new ArgumentException(string.Format("Expected exactly two children in {0}.", node.Symbol), "node");
+
+      lhs = node.GetSubtree(0);
+      rhs = node.GetSubtree(1);
+
+      return Interpret(lhs) + compSy + Interpret(rhs);
+    }
+
+    public static string InterpretFunc1(string functionId, ISymbolicExpressionTreeNode node) {
+      if (node.SubtreeCount != 1)
+        throw new ArgumentException(string.Format("Expected 1 child in {0}.", node.Symbol.Name), "node");
+
+      return string.Format("{0}({1})", functionId, Interpret(node.GetSubtree(0)));
+    }
+
+    public static string InterpretOnScannedRobot(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void onScannedRobot(ScannedRobotEvent e) {{
+  double absoluteBearing = getHeading() + e.getBearing();
+  double bearingFromGun = normalRelativeAngleDegrees(absoluteBearing - getGunHeading());
+  setTurnGunRight(bearingFromGun);
+{0}
+  execute();
+}}", code);
+    }
+
+
+    public static string InterpretOnHitWall(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void onHitWall(HitWallEvent e) {{
+{0}
+execute();
+}}", code);
+    }
+
+    public static string InterpretOnHitRobot(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void onHitRobot(HitRobotEvent e) {{
+{0}
+execute();
+}}", code);
+    }
+
+    public static string InterpretOnHitByBullet(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void onHitByBullet(HitByBulletEvent e) {{
+{0}
+execute();
+}}", code);
+    }
+
+    public static string InterpretOnBulletMissed(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void onBulletMissed(BulletMissedEvent e) {{
+{0}
+execute();
+}}", code);
+    }
+
+    public static string InterpretOnBulletHit(ISymbolicExpressionTreeNode node) {
+      var Prefix = "public void onBulletHit(BulletHitEvent e) {";
+      var Suffix =
+@"execute();
+}";
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return Prefix + code + Environment.NewLine + Suffix;
+    }
+
+    public static string InterpretRun(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"public void run() {{
+  setAdjustGunForRobotTurn(true);
+  turnRadarRightRadians(Double.POSITIVE_INFINITY);
+{0}
+  execute();
+}}", code);
+    }
+
+    public static string InterpretTank(ISymbolicExpressionTreeNode node) {
+      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
+      return string.Format(
+@"package Evaluation;
+import robocode.*;
+import robocode.Robot;
+import robocode.util.*;
+import static robocode.util.Utils.normalRelativeAngleDegrees;
+import java.awt.*;
+
+public class output extends AdvancedRobot {{ 
+{0}
+}}", code);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Problem.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Problem.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Problem.cs	(revision 13312)
@@ -0,0 +1,140 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 360)]
+  [Item("Robocode Problem", "Evolution of a robocode program in java using genetic programming.")]
+  public class Problem : SymbolicExpressionTreeProblem {
+    #region Parameter Names
+    private const string RobocodePathParamaterName = "RobocodePath";
+    private const string NrOfRoundsParameterName = "NrOfRounds";
+    private const string EnemiesParameterName = "Enemies";
+    #endregion
+
+    #region Parameters
+    public IFixedValueParameter<DirectoryValue> RobocodePathParameter {
+      get { return (IFixedValueParameter<DirectoryValue>)Parameters[RobocodePathParamaterName]; }
+    }
+    public IFixedValueParameter<IntValue> NrOfRoundsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[NrOfRoundsParameterName]; }
+    }
+    public IValueParameter<EnemyCollection> EnemiesParameter {
+      get { return (IValueParameter<EnemyCollection>)Parameters[EnemiesParameterName]; }
+    }
+
+    public string RobocodePath {
+      get { return RobocodePathParameter.Value.Value; }
+      set { RobocodePathParameter.Value.Value = value; }
+    }
+
+    public int NrOfRounds {
+      get { return NrOfRoundsParameter.Value.Value; }
+      set { NrOfRoundsParameter.Value.Value = value; }
+    }
+
+    public EnemyCollection Enemies {
+      get { return EnemiesParameter.Value; }
+      set { EnemiesParameter.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected Problem(bool deserializing) : base(deserializing) { }
+    protected Problem(Problem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+
+    public Problem()
+      : base() {
+      DirectoryValue robocodeDir = new DirectoryValue { Value = @"robocode" };
+
+      var robotList = EnemyCollection.ReloadEnemies(robocodeDir.Value);
+      robotList.RobocodePath = robocodeDir.Value;
+
+
+      Parameters.Add(new FixedValueParameter<DirectoryValue>(RobocodePathParamaterName, "Path of the Robocode installation.", robocodeDir));
+      Parameters.Add(new FixedValueParameter<IntValue>(NrOfRoundsParameterName, "Number of rounds a robot has to fight against each opponent.", new IntValue(3)));
+      Parameters.Add(new ValueParameter<EnemyCollection>(EnemiesParameterName, "The enemies that should be battled.", robotList));
+
+      Encoding = new SymbolicExpressionTreeEncoding(new Grammar(), 1000, 10);
+      Encoding.FunctionArguments = 0;
+      Encoding.FunctionDefinitions = 0;
+
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Problem(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { RegisterEventHandlers(); }
+
+    public override double Evaluate(ISymbolicExpressionTree tree, IRandom random) {
+      return Interpreter.EvaluateTankProgram(tree, RobocodePath, Enemies, null, false, NrOfRounds);
+    }
+
+    public override void Analyze(ISymbolicExpressionTree[] trees, double[] qualities, ResultCollection results, IRandom random) {
+      // find the tree with the best quality
+      double maxQuality = double.NegativeInfinity;
+      ISymbolicExpressionTree bestTree = null;
+      for (int i = 0; i < qualities.Length; i++) {
+        if (qualities[i] > maxQuality) {
+          maxQuality = qualities[i];
+          bestTree = trees[i];
+        }
+      }
+
+      // create a solution instance
+      var bestSolution = new Solution(bestTree, RobocodePath, NrOfRounds, Enemies);
+
+      // also add the best solution as a result to the result collection
+      // or alternatively update the existing result
+      if (!results.ContainsKey("BestSolution")) {
+        results.Add(new Result("BestSolution", "The best tank program", bestSolution));
+      } else {
+        results["BestSolution"].Value = bestSolution;
+      }
+    }
+
+    public override bool Maximization {
+      get { return true; }
+    }
+
+    private void RegisterEventHandlers() {
+      RobocodePathParameter.Value.StringValue.ValueChanged += RobocodePathParameter_ValueChanged;
+    }
+
+    void RobocodePathParameter_ValueChanged(object sender, System.EventArgs e) {
+      EnemiesParameter.Value.RobocodePath = RobocodePathParameter.Value.Value;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Solution.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Solution.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Solution.cs	(revision 13312)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  [Item("Solution", "Robocode program and configuration.")]
+  public sealed class Solution : Item {
+    [Storable]
+    public ISymbolicExpressionTree Tree { get; set; }
+
+    [Storable]
+    public string Path { get; set; }
+
+    [Storable]
+    public int NrOfRounds { get; set; }
+
+    [Storable]
+    public EnemyCollection Enemies { get; set; }
+
+    [StorableConstructor]
+    private Solution(bool deserializing) : base(deserializing) { }
+    private Solution(Solution original, Cloner cloner)
+      : base(original, cloner) {
+      Tree = cloner.Clone(original.Tree);
+      Path = (string)original.Path.Clone();
+      NrOfRounds = original.NrOfRounds;
+      Enemies = cloner.Clone(original.Enemies);
+    }
+
+    public Solution(ISymbolicExpressionTree tree, string path, int nrOfRounds, EnemyCollection enemies)
+      : base() {
+      this.Tree = tree;
+      this.Path = path;
+      this.NrOfRounds = nrOfRounds;
+      this.Enemies = enemies;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Solution(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanTreeNode.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanTreeNode.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanTreeNode.cs	(revision 13312)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class BooleanTreeNode : SymbolicExpressionTreeTerminalNode {
+    private bool value;
+    [Storable]
+    public bool Value {
+      get { return value; }
+      private set { this.value = value; }
+    }
+
+    [StorableConstructor]
+    protected BooleanTreeNode(bool deserializing) : base(deserializing) { }
+    protected BooleanTreeNode(BooleanTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      value = original.value;
+    }
+
+    public BooleanTreeNode(BooleanValue boolValueSy) : base(boolValueSy) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BooleanTreeNode(this, cloner);
+    }
+
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
+    public override void ResetLocalParameters(IRandom random) {
+      // initialization
+      value = random.NextDouble() > 0.5;
+    }
+
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      // mutation: flip value with 5% probability
+      if (random.NextDouble() < 0.05) value = !value;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanValue.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanValue.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/BooleanValue.cs	(revision 13312)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class BooleanValue : Symbol {
+    public override int MinimumArity { get { return 0; } }
+    public override int MaximumArity { get { return 0; } }
+
+    [StorableConstructor]
+    protected BooleanValue(bool deserializing) : base(deserializing) { }
+    protected BooleanValue(BooleanValue original, Cloner cloner) : base(original, cloner) { }
+
+    public BooleanValue() : base("BooleanValue", "A Boolean value.") { }
+
+    public override ISymbolicExpressionTreeNode CreateTreeNode() {
+      return new BooleanTreeNode(this);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BooleanValue(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/CodeSymbol.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/CodeSymbol.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/CodeSymbol.cs	(revision 13312)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  // a symbol that can represent any user-defined fragment of code
+  public sealed class CodeSymbol : Symbol {
+    public override int MinimumArity { get { return 1; } }
+    public override int MaximumArity { get { return 10; } }
+
+    public string Prefix { get; set; }
+    public string Suffix { get; set; }
+
+    public override bool CanChangeName { get { return false; } } // cannot change, otherwise we cannot detect these symbols in the interpreter
+    public override bool CanChangeDescription { get { return false; } }
+
+    [StorableConstructor]
+    private CodeSymbol(bool deserializing) : base(deserializing) { }
+    private CodeSymbol(CodeSymbol original, Cloner cloner)
+      : base(original, cloner) {
+      Prefix = original.Prefix;
+      Suffix = original.Suffix;
+    }
+    public CodeSymbol()
+      : base("CodeSymbol", "The CodeSymbol symbol can represent any user-defined fragment of code.") {
+      Prefix = string.Empty;
+      Suffix = string.Empty;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CodeSymbol(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/Number.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/Number.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/Number.cs	(revision 13312)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Globalization;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class Number : Symbol {
+    public override int MinimumArity { get { return 0; } }
+    public override int MaximumArity { get { return 0; } }
+
+    [StorableConstructor]
+    protected Number(bool deserializing) : base(deserializing) { }
+    protected Number(Number original, Cloner cloner) : base(original, cloner) { }
+
+    public Number() : base("Number", "A number.") { }
+
+    public override ISymbolicExpressionTreeNode CreateTreeNode() {
+      return new NumberTreeNode(this);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Number(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/NumberTreeNode.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/NumberTreeNode.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/NumberTreeNode.cs	(revision 13312)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class NumberTreeNode : SymbolicExpressionTreeTerminalNode {
+    private int value;
+    [Storable]
+    public int Value {
+      get { return value; }
+      private set { this.value = value; }
+    }
+
+    [StorableConstructor]
+    protected NumberTreeNode(bool deserializing) : base(deserializing) { }
+    protected NumberTreeNode(NumberTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value;
+    }
+
+    public NumberTreeNode(Number numberSy) : base(numberSy) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NumberTreeNode(this, cloner);
+    }
+
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
+    public override void ResetLocalParameters(IRandom random) {
+      // random initialization
+      value = random.Next(-360, 360);
+    }
+
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      // random mutation (cyclic)
+      value = value + random.Next(-20, 20);
+      if (value < -360) value += 2 * 360;
+      else if (value > 359) value -= 2 * 360;
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPower.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPower.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPower.cs	(revision 13312)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Globalization;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class ShotPower : Symbol {
+    public override int MinimumArity { get { return 0; } }
+    public override int MaximumArity { get { return 0; } }
+
+    [StorableConstructor]
+    protected ShotPower(bool deserializing) : base(deserializing) { }
+    protected ShotPower(ShotPower original, Cloner cloner) : base(original, cloner) { }
+
+    public ShotPower() : base("ShotPower", "The power of a shot between 0.1 and 3.") { }
+
+    public override ISymbolicExpressionTreeNode CreateTreeNode() {
+      return new ShotPowerTreeNode(this);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShotPower(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPowerTreeNode.cs
===================================================================
--- /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPowerTreeNode.cs	(revision 13312)
+++ /stable/HeuristicLab.Problems.GeneticProgramming/3.3/robocode/Symbols/ShotPowerTreeNode.cs	(revision 13312)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
+  [StorableClass]
+  public class ShotPowerTreeNode : SymbolicExpressionTreeTerminalNode {
+    private double value;
+    [Storable]
+    public double Value {
+      get { return value; }
+      private set { this.value = value; }
+    }
+
+    [StorableConstructor]
+    protected ShotPowerTreeNode(bool deserializing) : base(deserializing) { }
+    protected ShotPowerTreeNode(ShotPowerTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value;
+    }
+
+    public ShotPowerTreeNode(ShotPower powerSy) : base(powerSy) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShotPowerTreeNode(this, cloner);
+    }
+
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
+    public override void ResetLocalParameters(IRandom random) {
+      // random initialization
+      value = Math.Max(0.1, random.NextDouble() * 3);
+    }
+
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      // mutation
+      var d = random.NextDouble() * 2.0 - 1.0;
+      value += shakingFactor * d;
+      if (value < 0.1) value = 0.1;
+      if (value > 3) value = 3;
+    }
+  }
+}
Index: /stable/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPRobocodeSampleTest.cs
===================================================================
--- /stable/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPRobocodeSampleTest.cs	(revision 13312)
+++ /stable/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPRobocodeSampleTest.cs	(revision 13312)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.IO;
+using System.Linq;
+using HeuristicLab.Algorithms.GeneticAlgorithm;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Problems.GeneticProgramming.Robocode;
+using HeuristicLab.Selection;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace HeuristicLab.Tests {
+  [TestClass]
+  public class GPRobocodeSampleTest {
+    private const string SampleFileName = "SGP_Robocode";
+
+    [TestMethod]
+    [TestCategory("Samples.Create")]
+    [TestProperty("Time", "medium")]
+    public void CreateGpRobocodeSampleTest() {
+      var ga = CreateGpRobocodeSample();
+      string path = Path.Combine(SamplesUtils.SamplesDirectory, SampleFileName + SamplesUtils.SampleFileExtension);
+      XmlGenerator.Serialize(ga, path);
+    }
+
+    // there is no unit test for running the sample because a JDK installation would be necessary (and this is not the case on our build server)
+
+    public GeneticAlgorithm CreateGpRobocodeSample() {
+      GeneticAlgorithm ga = new GeneticAlgorithm();
+
+      #region Problem Configuration
+      Problem antProblem = new Problem();
+      #endregion
+      #region Algorithm Configuration
+      ga.Name = "Genetic Programming - Robocode Java Source";
+      ga.Description = "A standard genetic programming algorithm to evolve the java source code for a robocode bot (see http://robocode.sourceforge.net/). An installation of Java SE Developmen Kit (JDK) >= 1.6 is necessary to run this sample.";
+      ga.Problem = antProblem;
+      SamplesUtils.ConfigureGeneticAlgorithmParameters<TournamentSelector, SubtreeCrossover, MultiSymbolicExpressionTreeArchitectureManipulator>(
+        ga, 50, 1, 50, 0.15, 2);
+
+      ga.Engine = new SequentialEngine.SequentialEngine();
+      #endregion
+
+      return ga;
+    }
+  }
+}
Index: /stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- /stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 13311)
+++ /stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 13312)
@@ -440,4 +440,5 @@
     <Compile Include="HeuristicLab-3.3\PluginLoader.cs" />
     <Compile Include="HeuristicLab-3.3\Samples\AlpsSampleTest.cs" />
+    <Compile Include="HeuristicLab-3.3\Samples\GPRobocodeSampleTest.cs" />
     <Compile Include="HeuristicLab-3.3\Samples\OSESGriewankSampleTest.cs" />
     <Compile Include="HeuristicLab-3.3\Samples\GAGroupingProblemSampleTest.cs" />
