Index: /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Expression.cs
===================================================================
--- /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Expression.cs	(revision 14479)
+++ /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Expression.cs	(revision 14480)
@@ -29,121 +29,162 @@
 
 namespace HeuristicLab.ExpressionGenerator {
-  public class Expression : IExpression {
-    public string Name { get; set; }
+    public class Expression : IExpression {
+        // unique name for each expression 
+        public string Name { get; set; }
+        // optional label (non-unique) - useful for string (infix) representations
+        public string Label { get; set; }
 
-    public ExpressionType Type { get; }
+        public ExpressionType Type { get; private set; }
 
-    private readonly List<Expression> arguments;
-    public IEnumerable<Expression> Arguments {
-      get { return arguments ?? Enumerable.Empty<Expression>(); }
+        private readonly List<Expression> arguments;
+        public IEnumerable<Expression> Arguments {
+            get { return arguments ?? Enumerable.Empty<Expression>(); }
+        }
+
+        public IRandom Distribution { get; private set; }
+
+        public Func<IEnumerable<double>, double> Transform { get; private set; }
+
+        public double Value { get; private set; }
+
+        public Expression(string name, double value) {
+            Type = ExpressionType.Constant;
+            Value = value;
+            Name = name;
+        }
+
+        public Expression(string name, IRandom distribution) {
+            Type = ExpressionType.RandomVariable;
+            Distribution = distribution;
+            Name = name;
+        }
+
+        public Expression(string name, Func<IEnumerable<double>, double> transform, IEnumerable<Expression> arguments) {
+            Type = ExpressionType.Function;
+            Transform = transform;
+            this.arguments = this.arguments ?? new List<Expression>();
+            this.arguments.AddRange(arguments);
+            Name = name;
+        }
+
+        public static Expression Constant(string name, double value) {
+            return new Expression(name, value);
+        }
+
+        public static Expression RandomVariable(string name, IRandom distribution) {
+            return new Expression(name, distribution);
+        }
+
+        public static Expression Function(string name, Func<IEnumerable<double>, double> transform, IEnumerable<Expression> arguments) {
+            return new Expression(name, transform, arguments);
+        }
+
+        public override string ToString() {
+            var sb = new StringBuilder();
+
+            switch (Type) {
+                case ExpressionType.Constant:
+                    sb.Append(Value.ToString("0.000", CultureInfo.CurrentCulture));
+                    break;
+                case ExpressionType.RandomVariable:
+                    sb.Append(string.Format("{0} ~ {1}", Name, GetStringDescription(Distribution)));
+                    break;
+                case ExpressionType.Function:
+                    sb.Append(string.Format("{0} = f(", Name));
+                    if (Arguments.Any()) {
+                        for (int i = 0; i < arguments.Count - 1; ++i)
+                            sb.Append(string.Format("{0}, ", arguments[i].Name));
+                        sb.Append(string.Format("{0})", arguments.Last().Name));
+                    }
+                    break;
+            }
+
+            return sb.ToString();
+        }
+
+        public string PrintInfix() {
+            var sb = new StringBuilder();
+            switch (Type) {
+                case ExpressionType.Constant:
+                    sb.Append(Value < 0
+                        ? string.Format("(- {0})", Math.Abs(Value).ToString("0.000", CultureInfo.CurrentCulture))
+                        : Value.ToString("0.000", CultureInfo.CurrentCulture));
+                    break;
+                case ExpressionType.RandomVariable:
+                    sb.Append(Name);
+                    break;
+                case ExpressionType.Function:
+                    if (!Arguments.Any())
+                        break;
+                    var args = Arguments.ToList();
+                    sb.Append("(");
+                    // the Label should be known to the infix parser
+                    if (Label == "+" || Label == "-" || Label == "*" || Label == "/") {
+                        if (args.Count == 1) {
+                            sb.Append(string.Format("{0}", args[0].PrintInfix()));
+                        } else {
+                            sb.Append("(");
+                            var last = args.Last();
+                            for (int i = 0; i < args.Count - 1; ++i) {
+                                var arg = args[i];
+                                sb.Append(string.Format("{0} {1}", arg.PrintInfix(), Label));
+                            }
+                            sb.Append(string.Format(" {0})", last.PrintInfix()));
+                        }
+                    } else {
+                        sb.Append(string.Format("{0}(", Label));
+                        var last = args.Last();
+                        for (int i = 0; i < args.Count - 1; ++i) {
+                            var arg = args[i];
+                            sb.Append(string.Format("{0}, ", arg.PrintInfix(), Label));
+                        }
+                        sb.Append(string.Format("{0})", last.PrintInfix()));
+                    }
+                    sb.Append(")");
+                    break;
+            }
+            return sb.ToString();
+        }
+
+        public string PrintDot() {
+            var stack = new Stack<Expression>();
+            stack.Push(this);
+
+            var sb = new StringBuilder();
+            sb.AppendLine("digraph g {");
+
+            while (stack.Count > 0) {
+                var top = stack.Pop();
+
+                if (!top.Arguments.Any())
+                    continue;
+
+                foreach (var arg in top.Arguments) {
+                    var from = top.Arguments.Any() ? top.Name : top.ToString();
+                    var to = arg.Arguments.Any() ? arg.Name : arg.ToString();
+                    sb.AppendLine(string.Format("\"{0}\" -> \"{1}\";", from, to));
+                    stack.Push(arg);
+                }
+            }
+
+            sb.AppendLine("}");
+            return sb.ToString();
+        }
+
+        private static string GetStringDescription(IRandom random) {
+            var normal = random as NormalDistributedRandom;
+            if (normal != null)
+                return string.Format("N({0}, {1})", normal.Mu, normal.Sigma);
+
+            var uniform = random as UniformDistributedRandom;
+            if (uniform != null)
+                return string.Format("U({0}, {1})", uniform.Min, uniform.Max);
+
+            var gamma = random as GammaDistributedRandom;
+            if (gamma != null)
+                return string.Format("G({0}, {1})", gamma.Shape, gamma.Rate);
+
+            return random.ToString();
+        }
     }
-
-    public IRandom Distribution { get; }
-
-    public Func<IEnumerable<double>, double> Transform { get; }
-
-    public double Value { get; }
-
-    public Expression(string name, double value) {
-      Type = ExpressionType.Constant;
-      Value = value;
-      Name = name;
-    }
-
-    public Expression(string name, IRandom distribution) {
-      Type = ExpressionType.RandomVariable;
-      Distribution = distribution;
-      Name = name;
-    }
-
-    public Expression(string name, Func<IEnumerable<double>, double> transform, IEnumerable<Expression> arguments) {
-      Type = ExpressionType.Function;
-      Transform = transform;
-      this.arguments = this.arguments ?? new List<Expression>();
-      this.arguments.AddRange(arguments);
-      Name = name;
-    }
-
-    public static Expression Constant(string label, double value) {
-      return new Expression(label, value);
-    }
-
-    public static Expression RandomVariable(string label, IRandom distribution) {
-      return new Expression(label, distribution);
-    }
-
-    public static Expression Function(string label, Func<IEnumerable<double>, double> transform, IEnumerable<Expression> arguments) {
-      return new Expression(label, transform, arguments);
-    }
-
-    public override string ToString() {
-      var sb = new StringBuilder();
-
-      switch (Type) {
-        case ExpressionType.Constant:
-          sb.Append(Value.ToString("0.000", CultureInfo.CurrentCulture));
-          break;
-        case ExpressionType.RandomVariable:
-          sb.Append(string.Format("{0} ~ {1}", Name, GetStringDescription(Distribution)));
-          break;
-        case ExpressionType.Function:
-          sb.Append(string.Format("{0} = f(", Name));
-          if (Arguments.Any()) {
-            for (int i = 0; i < arguments.Count - 1; ++i)
-              sb.Append(string.Format("{0}, ", arguments[i].Name));
-            sb.Append(string.Format("{0})", arguments.Last().Name));
-          }
-          break;
-      }
-
-      return sb.ToString();
-    }
-
-    public string PrintInfix() {
-      var sb = new StringBuilder();
-
-      return sb.ToString();
-    }
-
-    public string PrintDot() {
-      var stack = new Stack<Expression>();
-      stack.Push(this);
-
-      var sb = new StringBuilder();
-      sb.AppendLine("digraph g {");
-
-      while (stack.Count > 0) {
-        var top = stack.Pop();
-
-        if (!top.Arguments.Any())
-          continue;
-
-        foreach (var arg in top.Arguments) {
-          var from = top.Arguments.Any() ? top.Name : top.ToString();
-          var to = arg.Arguments.Any() ? arg.Name : arg.ToString();
-          sb.AppendLine(string.Format("\"{0}\" -> \"{1}\";", from, to));
-          stack.Push(arg);
-        }
-      }
-
-      sb.AppendLine("}");
-      return sb.ToString();
-    }
-
-    private static string GetStringDescription(IRandom random) {
-      var normal = random as NormalDistributedRandom;
-      if (normal != null)
-        return string.Format("N({0}, {1})", normal.Mu, normal.Sigma);
-
-      var uniform = random as UniformDistributedRandom;
-      if (uniform != null)
-        return string.Format("U({0}, {1})", uniform.Min, uniform.Max);
-
-      var gamma = random as GammaDistributedRandom;
-      if (gamma != null)
-        return string.Format("G({0}, {1})", gamma.Shape, gamma.Rate);
-
-      return random.ToString();
-    }
-  }
 }
Index: /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionTemplate.cs
===================================================================
--- /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionTemplate.cs	(revision 14479)
+++ /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionTemplate.cs	(revision 14480)
@@ -30,11 +30,14 @@
     private List<Tuple<Expression, double>> arguments;
     private readonly Func<IEnumerable<double>, double> transform;
+    public string Label { get; set; }
 
-    protected Expression Instantiate(string label, IRandom random, int n, bool sampleWithRepetition = false) {
+    protected Expression Instantiate(string name, IRandom random, int n, bool sampleWithRepetition = false) {
       var weights = arguments.Select(x => x.Item2);
       var args = sampleWithRepetition
        ? arguments.SampleProportional(random, n, weights).Select(x => x.Item1)
        : arguments.SampleProportionalWithoutRepetition(random, n, weights).Select(x => x.Item1);
-      return Expression.Function(label, transform, args);
+      var func = Expression.Function(name, transform, args);
+      func.Label = Label;
+      return func;
     }
 
Index: /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/HeuristicLab.ExpressionGenerator.csproj
===================================================================
--- /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/HeuristicLab.ExpressionGenerator.csproj	(revision 14479)
+++ /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/HeuristicLab.ExpressionGenerator.csproj	(revision 14480)
@@ -22,4 +22,5 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <LangVersion>4</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -76,5 +77,7 @@
     <Compile Include="Interfaces\IExpression.cs" />
     <Compile Include="Plugin.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Properties\AssemblyInfo.cs.frame" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@@ -83,4 +86,6 @@
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
 call PreBuildEvent.cmd</PreBuildEvent>
   </PropertyGroup>
Index: /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Properties/AssemblyInfo.cs.frame	(revision 14480)
+++ /branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/Properties/AssemblyInfo.cs.frame	(revision 14480)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.ExpressionGenerator")]
+[assembly: AssemblyDescription("Provides methods to automatically generate mathematical expressions")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2016 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("13c7216b-bd02-4f3f-9ebc-2aa8a14ae12c")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.10.$WCREV$")]
