diff --git a/ConsoleLogger.cs b/ConsoleLogger.cs
index 0e322ca939632d33f1b3e1698b00bf7e98530e48..e0a232174c18ea0d63a24ee2e2a01352bebff703 100644
--- a/ConsoleLogger.cs
+++ b/ConsoleLogger.cs
@@ -10,9 +10,26 @@ namespace compiler
         {
             if (verbosity <= ConsoleLogger.Verbosity)
             {
-                Console.WriteLine(msg);
+                var color = ConsoleColor.White;
+                switch (verbosity)
+                {
+                    case Verbosity.Debugging: color = ConsoleColor.Gray; break;
+                    case Verbosity.Info: color = ConsoleColor.Cyan; break;
+                    case Verbosity.Warning: color = ConsoleColor.Yellow; break;
+                    case Verbosity.Error: color = ConsoleColor.Red; break;
+                }
+
+                DoInColor(color, () => Console.WriteLine(msg));
             }
         }
+
+        private static void DoInColor(ConsoleColor color, Action action)
+        {
+            var currentColor = Console.ForegroundColor;
+            Console.ForegroundColor = color;
+            action();
+            Console.ForegroundColor = currentColor;
+        }
     }
 
     public enum Verbosity
diff --git a/LinkedListEnumerator.cs b/LinkedListEnumerator.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9c4f3f400b4dd1b775d14ba6626223b18e8b3daa
--- /dev/null
+++ b/LinkedListEnumerator.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace compiler
+{
+    public class LinkedListEnumerator<T> : IEnumerator<T>
+    {
+        private Func<T, T> Next { get; }
+
+        public LinkedListEnumerator(T element, Func<T, T> next)
+        {
+            this.First = element;
+            this.Next = next;
+        }
+
+        public T First { get; }
+
+        public T Current { get; set; }
+
+        object IEnumerator.Current => throw new NotImplementedException();
+
+        public void Dispose()
+        {
+            GC.SuppressFinalize(this);
+        }
+
+        public bool MoveNext()
+        {
+            if (this.Current == null)
+            {
+                this.Current = this.First;
+            }
+            else
+            {
+                this.Current = this.Next(this.Current);
+            }
+
+            return this.Current != null;
+        }
+
+        public void Reset()
+        {
+            this.Current = this.First;
+        }
+    }
+}
diff --git a/MonitorPyWriter.cs b/MonitorPyWriter.cs
index 73ab9336de5b8b5905fdc5798b859210edb8fc71..6e379ad38c607e8c86ebe4c7408c8a7d661be8a0 100644
--- a/MonitorPyWriter.cs
+++ b/MonitorPyWriter.cs
@@ -1,4 +1,8 @@
-using System.IO;
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
 
 namespace compiler
 {
@@ -6,13 +10,57 @@ namespace compiler
     {
         public void Write(string path, TestParser.Node rootNode)
         {
-            var targetFile = Path.Combine(path, "monitor.py");
-            File.WriteAllText(targetFile, $@"
-# ToDo: Add Python Code
+            var sb = new StringBuilder();
+            sb.AppendLine($@"# ToDo: Add Python Code");
+
+            foreach (var node in rootNode)
+            {
+                if (node.Text.StartsWith("constraint:", StringComparison.InvariantCultureIgnoreCase))
+                {
+                    sb.AppendLine();
+
+                    if (node.Data.Length != 1)
+                    {
+                        ConsoleLogger.WriteLine("For constraints only 1 t=-Parameter is supportted", Verbosity.Error);
+                        throw new ProcessingException();
+                    }
 
+                    var time = double.Parse(node.Data[0].Split('=')[1], CultureInfo.InvariantCulture);
+                    sb.AppendLine($"# For time t={time:N} check...");
 
+                    var text = node.Text.Substring("constraint:".Length).Trim();
+                    var parts = text.Split("in");
+                    var valueToEvaluate = parts[0].Trim();
+                    var rangeString = parts[1].Trim();
 
-");
+                    var range = rangeString.TrimStart('[').TrimEnd(']').Split(',').Select(x => x.Trim()).ToList();
+                    if (range.Count != 2)
+                    {
+                        ConsoleLogger.WriteLine("Not exact 2 arguments in range", Verbosity.Error);
+                        throw new ProcessingException();
+                    }
+
+                    if (valueToEvaluate.StartsWith("Distance", StringComparison.InvariantCultureIgnoreCase))
+                    {
+                        var elements = valueToEvaluate.Substring("Distance(".Length).TrimEnd(')').Split(',').Select(x => x.Trim()).ToList();
+                        if (elements.Count != 2)
+                        {
+                            ConsoleLogger.WriteLine("Not exact 2 arguments in 'Distance'-Function", Verbosity.Error);
+                            throw new ProcessingException();
+                        }
+                        sb.AppendLine($"# checking constraint for distance between {elements[0]} and {elements[1]}");
+                        sb.AppendLine($"# it should be in range of {range[0]} to {range[1]}");
+                    }
+                    else
+                    {
+                        sb.AppendLine($"# checking constraint for value of {valueToEvaluate}");
+                        sb.AppendLine($"# it should be in range of {range[0]} to {range[1]}");
+                    }
+                }
+            }
+
+            var targetFile = Path.Combine(path, "monitor.py");
+            File.WriteAllText(targetFile, sb.ToString());
         }
     }
 }
diff --git a/Obstacle.cs b/Obstacle.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5ee857d965bbc54ab65aea80ae575c413690860b
--- /dev/null
+++ b/Obstacle.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace compiler
+{
+    public class Obstacle
+    {
+        public Obstacle(string s)
+        {
+            if (!s.StartsWith("Obstacle", StringComparison.InvariantCultureIgnoreCase))
+            {
+                throw new ArgumentException();
+            }
+
+            s = s.Substring("Obstacle".Length).Trim();
+            var splitted = s.Split(' ', 2);
+
+            this.Name = splitted[0];
+            s = splitted[1];
+            s = s.Split('=', 2)[1].Trim();
+            splitted = s.Split('(', 2);
+            this.Type = splitted[0].Trim().ToLower();
+            this.Parameter = splitted[1].TrimEnd(')').Split(',').Select(x => x.Split('=', 2)).ToDictionary(x => x[0].Trim(), x => x[1].Trim());
+        }
+
+        public string Name { get; }
+        public string Type { get; }
+        public Dictionary<string, string> Parameter { get; }
+    }
+
+    public enum ObstacleType
+    {
+
+    }
+}
diff --git a/ProcessingException.cs b/ProcessingException.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c13d6e102e6fbfabcc0310195071af9adc46699d
--- /dev/null
+++ b/ProcessingException.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace compiler
+{
+    public class ProcessingException : Exception
+    {
+    }
+}
diff --git a/Program.cs b/Program.cs
index 97dfc5ff824e2c6bb5bd5399cf50f7d165cc7856..037e8c502f03b6a1f6fed7d0f152f61f8ed798c3 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Globalization;
 using System.IO;
 using System.Linq;
 
@@ -9,6 +10,7 @@ namespace compiler
         static void Main(string[] args)
         {
             ConsoleLogger.Verbosity = Verbosity.Debugging;
+            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
 
             if (args.Length != 2)
             {
@@ -34,10 +36,21 @@ namespace compiler
 
                 for (var i = 0; i < rootNodes.Count; i++)
                 {
-                    var rootNode = rootNodes[i];
-                    var path = Path.Combine(targetDirectory, @$"{baseName}-{i}");
-                    Directory.CreateDirectory(path);
-                    TestWriter.WriteAll(path, rootNode);
+                    try
+                    {
+                        var rootNode = rootNodes[i];
+                        var path = Path.Combine(targetDirectory, @$"{baseName}-{i}");
+                        Directory.CreateDirectory(path);
+                        TestWriter.WriteAll(path, rootNode);
+                    }
+                    catch (ProcessingException)
+                    {
+                        ConsoleLogger.WriteLine("An error occured. See above for details.", Verbosity.Error);
+                    }
+                    catch (Exception ex)
+                    {
+                        ConsoleLogger.WriteLine("An unexpected error occured: \n" + ex.Message + "\nStacktrac:" + ex.StackTrace, Verbosity.Error);
+                    }
                 }
             }
         }
diff --git a/TestParser.cs b/TestParser.cs
index bf99d2633b676616ba99960babbf05513120b6e6..64ef580b246bf6ec78c11a93ef52dca4d9806826 100644
--- a/TestParser.cs
+++ b/TestParser.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections;
+using System.Collections.Generic;
 using System.Linq;
 using System.Xml.Linq;
 
@@ -91,13 +92,23 @@ namespace compiler
         }
 
 
-        public class Node
+        public class Node: IEnumerable<Node>
         {
             public string Text { get; set; }
 
             public string[] Data { get; set; }
 
             public Node Next { get; set; }
+
+            public IEnumerator<Node> GetEnumerator()
+            {
+                return new LinkedListEnumerator<Node>(this, x => x.Next);
+            }
+
+            IEnumerator IEnumerable.GetEnumerator()
+            {
+                return this.GetEnumerator();
+            }
         }
     }
 }
diff --git a/WorldWriter.cs b/WorldWriter.cs
index f410760f6d6376a25d14750080efdd6741a95fdd..187c39f694031c6cb270b515a7ab705423f3f0d5 100644
--- a/WorldWriter.cs
+++ b/WorldWriter.cs
@@ -1,4 +1,6 @@
-using System.IO;
+using System;
+using System.IO;
+using System.Xml.Linq;
 
 namespace compiler
 {
@@ -6,12 +8,187 @@ namespace compiler
     {
         public void Write(string path, TestParser.Node rootNode)
         {
+            var world = CreateBaseWorld();
+
+            bool vehicleFound = false;
+            foreach (var node in rootNode)
+            {
+                if (node.Text.StartsWith("spawn:", StringComparison.CurrentCultureIgnoreCase))
+                {
+                    var text = node.Text.Substring("spawn:".Length).Trim();
+                    if (text.StartsWith("Vehicle", StringComparison.CurrentCultureIgnoreCase))
+                    {
+                        if (vehicleFound)
+                        {
+                            ConsoleLogger.WriteLine("Multiple Vehicles found", Verbosity.Error);
+                            throw new ProcessingException();
+                        }
+                        vehicleFound = true;//spawn the vehicle always at 0 0 0
+                    }
+                    else if (text.StartsWith("Obstacle", StringComparison.CurrentCultureIgnoreCase))
+                    {
+                        var obstacle = this.CreateObstacle(new Obstacle(text));
+                        world.Add(obstacle);
+                    }
+                    else
+                    {
+                        ConsoleLogger.WriteLine("Unknown spawn-Type: " + text, Verbosity.Error);
+                        throw new ProcessingException();
+                    }
+                }
+            }
+
+            if (!vehicleFound)
+            {
+                ConsoleLogger.WriteLine("No Vehicles found", Verbosity.Error);
+                throw new ProcessingException();
+            }
+
+            var doc = this.CreateDocumentFromWorld(world);
             var targetFile = Path.Combine(path, "test.world");
-            File.WriteAllText(targetFile, $@"
+            doc.Save(targetFile);
+        }
+
+        private XDocument CreateDocumentFromWorld(XElement world)
+        {
+            var doc = new XDocument(XElement.Parse("<sdf version='1.4'></sdf>"));
+            doc.Root.Add(world);
+            return doc;
+        }
 
+        private XElement CreateBaseWorld()
+        {
+            return XElement.Parse(@"
+<world name='default'>
+<!-- A global light source -->
+<include>
+    <uri>model://sun</uri>
+</include>
+
+<!-- A ground plane -->
+<include>
+    <uri>model://ground_plane</uri>
+</include>
+
+<physics type='ode'>
+    <real_time_update_rate>1000.0</real_time_update_rate>
+    <max_step_size>0.001</max_step_size>
+    <real_time_factor>1</real_time_factor>
+    <ode>
+    <solver>
+        <type>quick</type>
+        <iters>150</iters>
+        <precon_iters>0</precon_iters>
+        <sor>1.400000</sor>
+        <use_dynamic_moi_rescaling>1</use_dynamic_moi_rescaling>
+    </solver>
+    <constraints>
+        <cfm>0.00001</cfm>
+        <erp>0.2</erp>
+        <contact_max_correcting_vel>2000.000000</contact_max_correcting_vel>
+        <contact_surface_layer>0.01000</contact_surface_layer>
+    </constraints>
+    </ode>
+</physics>
+
+<scene>
+    <ambient>0.4 0.4 0.4 1</ambient>
+    <background>0.7 0.7 0.7 1</background>
+    <shadows>true</shadows>
+</scene>
 
+<gui fullscreen='0'>
+    <camera name='user_camera'>
+    <pose>0.0 0.0 17.0 0 1.5708 0</pose>
+    <view_controller>orbit</view_controller>
+    </camera>
+</gui>
+</world>");
+        }
+
+        private XElement CreateObstacle(Obstacle obstacle)
+        {
+            switch (obstacle.Type)
+            {
+                case "box":
+                    return XElement.Parse(@$"<model name='obstacle_{obstacle.Name}'>
+<pose frame=''>{obstacle.Parameter["x"]} {obstacle.Parameter["y"]} 0 0 0 0</pose>
+<link name='link'>
+<inertial>
+    <mass>1</mass>
+    <inertia>
+    <ixx>0.166667</ixx>
+    <ixy>0</ixy>
+    <ixz>0</ixz>
+    <iyy>0.166667</iyy>
+    <iyz>0</iyz>
+    <izz>0.166667</izz>
+    </inertia>
+</inertial>
+<collision name='collision'>
+    <geometry>
+    <box>
+        <size>{obstacle.Parameter["cx"]} {obstacle.Parameter["cy"]} {obstacle.Parameter["cz"]}</size>
+    </box>
+    </geometry>
+    <max_contacts>10</max_contacts>
+    <surface>
+    <contact>
+        <ode/>
+    </contact>
+    <bounce/>
+    <friction>
+        <torsional>
+        <ode/>
+        </torsional>
+        <ode/>
+    </friction>
+    </surface>
+</collision>
+<visual name='visual'>
+    <geometry>
+    <box>
+        <size>{obstacle.Parameter["cx"]} {obstacle.Parameter["cy"]} {obstacle.Parameter["cz"]}</size>
+    </box>
+    </geometry>
+    <material>
+    <script>
+        <name>Gazebo/Grey</name>
+        <uri>file://media/materials/scripts/gazebo.material</uri>
+    </script>
+    </material>
+</visual>
+<self_collide>0</self_collide>
+<enable_wind>0</enable_wind>
+<kinematic>0</kinematic>
+</link>
+</model>");
+                case "cylinder":
+                    return XElement.Parse($@"<model name='obstacle_1'>
+<pose>{obstacle.Parameter["x"]} {obstacle.Parameter["y"]} 0 0 0 0</pose>
+<link name='link'>
+<collision name='collision'>
+    <geometry>
+    <cylinder>
+        <radius>{obstacle.Parameter["r"]}</radius>
+        <length>{obstacle.Parameter["h"]}</length>
+    </cylinder>
+    </geometry>
+</collision>
+<visual name='visual'>
+    <geometry>
+    <cylinder>
+        <radius>{obstacle.Parameter["r"]}</radius>
+        <length>{obstacle.Parameter["h"]}</length>
+    </cylinder>
+    </geometry>
+</visual>
+</link>
+</model>");
+            }
 
-");
+            ConsoleLogger.WriteLine("Unknown Obstacle Type '" + obstacle.Type + "'", Verbosity.Error);
+            throw new ProcessingException();
         }
     }
 }
diff --git a/compiler.csproj b/compiler.csproj
index 70f7e771d51d1508362c40ba6db4d0e538478793..d41a57c7cff781687ddf00e71122f0fa24979433 100644
--- a/compiler.csproj
+++ b/compiler.csproj
@@ -16,6 +16,10 @@
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
+    <PackageReference Include="Microsoft.NetCore.Analyzers" Version="2.9.8">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
   </ItemGroup>
 
 </Project>