diff --git a/examples/pgcl/coupon/coupon10-classic.pgcl b/examples/pgcl/coupon/coupon10-classic.pgcl
new file mode 100644
index 000000000..d1c3cd015
--- /dev/null
+++ b/examples/pgcl/coupon/coupon10-classic.pgcl
@@ -0,0 +1,58 @@
+function coupon10() {
+	int coup0  := 0;
+	int coup1  := 0;
+	int coup2  := 0;
+	int coup3  := 0;
+	int coup4  := 0;
+	int coup5  := 0;
+	int coup6  := 0;
+	int coup7  := 0;
+	int coup8  := 0;
+	int coup9  := 0;
+	int coup10 := 0;
+
+	int draw := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1) | !(coup7 = 1) | !(coup8 = 1) | !(coup9 = 1) | !(coup10 = 1)) {
+		draw := unif(0,10);
+		draw2 := unif(0,10);
+		draw3 := unif(0,10);
+		numberDraws := numberDraws + 1;
+
+		if(draw = 0) {
+			coup0 := 1;
+		}
+		if(draw = 1) {
+			coup1 := 1;
+		}
+		if(draw = 2) {
+			coup2 := 1;
+		}
+		if(draw = 3) {
+			coup3 := 1;
+		}
+		if(draw = 4) {
+			coup4 := 1;
+		}
+		if(draw = 5) {
+			coup5 := 1;
+		}
+		if(draw = 6) {
+			coup6 := 1;
+		}
+		if(draw = 7) {
+			coup7 := 1;
+		}
+		if(draw = 8) {
+			coup8 := 1;
+		}
+		if(draw = 9) {
+			coup9 := 1;
+		}
+		if(draw = 10) {
+			coup10 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon10-cost.pgcl b/examples/pgcl/coupon/coupon10-cost.pgcl
new file mode 100644
index 000000000..740da760c
--- /dev/null
+++ b/examples/pgcl/coupon/coupon10-cost.pgcl
@@ -0,0 +1,60 @@
+function coupon10() {
+	int coup0  := 0;
+	int coup1  := 0;
+	int coup2  := 0;
+	int coup3  := 0;
+	int coup4  := 0;
+	int coup5  := 0;
+	int coup6  := 0;
+	int coup7  := 0;
+	int coup8  := 0;
+	int coup9  := 0;
+	int coup10 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int cost := 1;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1) | !(coup7 = 1) | !(coup8 = 1) | !(coup9 = 1) | !(coup10 = 1)) {
+		draw1 := unif(0,10);
+		draw2 := unif(0,10);
+		draw3 := unif(0,10);
+		cost := ceil(1.02 * cost);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+		if (draw1 = 7 | draw2 = 7 | draw3 = 7) {
+			coup7 := 1;
+		}
+		if (draw1 = 8 | draw2 = 8 | draw3 = 8) {
+			coup8 := 1;
+		}
+		if (draw1 = 9 | draw2 = 9 | draw3 = 9) {
+			coup9 := 1;
+		}
+		if (draw1 = 10 | draw2 = 10 | draw3 = 10) {
+			coup10 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon10-observe.pgcl b/examples/pgcl/coupon/coupon10-observe.pgcl
new file mode 100644
index 000000000..0ccdfb6f7
--- /dev/null
+++ b/examples/pgcl/coupon/coupon10-observe.pgcl
@@ -0,0 +1,62 @@
+function coupon10() {
+	int coup0  := 0;
+	int coup1  := 0;
+	int coup2  := 0;
+	int coup3  := 0;
+	int coup4  := 0;
+	int coup5  := 0;
+	int coup6  := 0;
+	int coup7  := 0;
+	int coup8  := 0;
+	int coup9  := 0;
+	int coup10 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1) | !(coup7 = 1) | !(coup8 = 1) | !(coup9 = 1) | !(coup10 = 1)) {
+		draw1 := unif(0,10);
+		draw2 := unif(0,10);
+		draw3 := unif(0,10);
+		numberDraws := numberDraws + 1;
+
+		observe (draw1 != draw2 & draw1 != draw3 & draw2 != draw3);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+		if (draw1 = 7 | draw2 = 7 | draw3 = 7) {
+			coup7 := 1;
+		}
+		if (draw1 = 8 | draw2 = 8 | draw3 = 8) {
+			coup8 := 1;
+		}
+		if (draw1 = 9 | draw2 = 9 | draw3 = 9) {
+			coup9 := 1;
+		}
+		if (draw1 = 10 | draw2 = 10 | draw3 = 10) {
+			coup10 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon10.pgcl b/examples/pgcl/coupon/coupon10.pgcl
new file mode 100644
index 000000000..95c9eae1e
--- /dev/null
+++ b/examples/pgcl/coupon/coupon10.pgcl
@@ -0,0 +1,60 @@
+function coupon10() {
+	int coup0  := 0;
+	int coup1  := 0;
+	int coup2  := 0;
+	int coup3  := 0;
+	int coup4  := 0;
+	int coup5  := 0;
+	int coup6  := 0;
+	int coup7  := 0;
+	int coup8  := 0;
+	int coup9  := 0;
+	int coup10 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1) | !(coup7 = 1) | !(coup8 = 1) | !(coup9 = 1) | !(coup10 = 1)) {
+		draw1 := unif(0,10);
+		draw2 := unif(0,10);
+		draw3 := unif(0,10);
+		numberDraws := numberDraws + 1;
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+		if (draw1 = 7 | draw2 = 7 | draw3 = 7) {
+			coup7 := 1;
+		}
+		if (draw1 = 8 | draw2 = 8 | draw3 = 8) {
+			coup8 := 1;
+		}
+		if (draw1 = 9 | draw2 = 9 | draw3 = 9) {
+			coup9 := 1;
+		}
+		if (draw1 = 10 | draw2 = 10 | draw3 = 10) {
+			coup10 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon3-classic.pgcl b/examples/pgcl/coupon/coupon3-classic.pgcl
new file mode 100644
index 000000000..b7c7d5b0d
--- /dev/null
+++ b/examples/pgcl/coupon/coupon3-classic.pgcl
@@ -0,0 +1,24 @@
+function coupon3() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+
+	int draw := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1)) {
+		draw := unif(0,2);
+		numberDraws := numberDraws + 1;
+
+		if(draw = 0) {
+			coup0 := 1;
+		}
+		if(draw = 1) {
+			coup1 := 1;
+		}
+		if(draw = 2) {
+			coup2 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon3-cost.pgcl b/examples/pgcl/coupon/coupon3-cost.pgcl
new file mode 100644
index 000000000..6f474942a
--- /dev/null
+++ b/examples/pgcl/coupon/coupon3-cost.pgcl
@@ -0,0 +1,28 @@
+function coupon3() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int cost := 1;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1)) {
+		draw1 := unif(0,2);
+		draw2 := unif(0,2);
+		draw3 := unif(0,2);
+		cost := ceil(1.02 * cost);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon3-observe.pgcl b/examples/pgcl/coupon/coupon3-observe.pgcl
new file mode 100644
index 000000000..6f41e7caf
--- /dev/null
+++ b/examples/pgcl/coupon/coupon3-observe.pgcl
@@ -0,0 +1,30 @@
+function coupon3() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1)) {
+		draw1 := unif(0,2);
+		draw2 := unif(0,2);
+		draw3 := unif(0,2);
+		numberDraws := numberDraws + 1;
+
+		observe (draw1 != draw2 & draw1 != draw3 & draw2 != draw3);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon3.pgcl b/examples/pgcl/coupon/coupon3.pgcl
new file mode 100644
index 000000000..1d4e4e7c6
--- /dev/null
+++ b/examples/pgcl/coupon/coupon3.pgcl
@@ -0,0 +1,28 @@
+function coupon3() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1)) {
+		draw1 := unif(0,2);
+		draw2 := unif(0,2);
+		draw3 := unif(0,2);
+		numberDraws := numberDraws + 1;
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon4-observe.pgcl b/examples/pgcl/coupon/coupon4-observe.pgcl
new file mode 100644
index 000000000..fb6d5bcf6
--- /dev/null
+++ b/examples/pgcl/coupon/coupon4-observe.pgcl
@@ -0,0 +1,34 @@
+function coupon4() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1)) {
+		draw1 := unif(0,4);
+		draw2 := unif(0,4);
+		draw3 := unif(0,4);
+		numberDraws := numberDraws + 1;
+
+		observe (draw1 != draw2 & draw1 != draw3 & draw2 != draw3);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon5-classic.pgcl b/examples/pgcl/coupon/coupon5-classic.pgcl
new file mode 100644
index 000000000..b27c381cf
--- /dev/null
+++ b/examples/pgcl/coupon/coupon5-classic.pgcl
@@ -0,0 +1,32 @@
+function coupon5() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+
+	int draw := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1)) {
+		draw := unif(0,4);
+		numberDraws := numberDraws + 1;
+
+		if(draw = 0) {
+			coup0 := 1;
+		}
+		if(draw = 1) {
+			coup1 := 1;
+		}
+		if(draw = 2) {
+			coup2 := 1;
+		}
+		if(draw = 3) {
+			coup3 := 1;
+		}
+		if(draw = 4) {
+			coup4 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon5-cost.pgcl b/examples/pgcl/coupon/coupon5-cost.pgcl
new file mode 100644
index 000000000..84779cad1
--- /dev/null
+++ b/examples/pgcl/coupon/coupon5-cost.pgcl
@@ -0,0 +1,36 @@
+function coupon5() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int cost := 1;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1)) {
+		draw1 := unif(0,4);
+		draw2 := unif(0,4);
+		draw3 := unif(0,4);
+		cost := ceil(1.02 * cost);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon5-observe.pgcl b/examples/pgcl/coupon/coupon5-observe.pgcl
new file mode 100644
index 000000000..734ccd127
--- /dev/null
+++ b/examples/pgcl/coupon/coupon5-observe.pgcl
@@ -0,0 +1,38 @@
+function coupon5() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1)) {
+		draw1 := unif(0,4);
+		draw2 := unif(0,4);
+		draw3 := unif(0,4);
+		numberDraws := numberDraws + 1;
+
+		observe (draw1 != draw2 & draw1 != draw3 & draw2 != draw3);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon5.pgcl b/examples/pgcl/coupon/coupon5.pgcl
new file mode 100644
index 000000000..aede63e50
--- /dev/null
+++ b/examples/pgcl/coupon/coupon5.pgcl
@@ -0,0 +1,36 @@
+function coupon5() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1)) {
+		draw1 := unif(0,4);
+		draw2 := unif(0,4);
+		draw3 := unif(0,4);
+		numberDraws := numberDraws + 1;
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon7-classic.pgcl b/examples/pgcl/coupon/coupon7-classic.pgcl
new file mode 100644
index 000000000..af9156ff1
--- /dev/null
+++ b/examples/pgcl/coupon/coupon7-classic.pgcl
@@ -0,0 +1,40 @@
+function coupon7() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+	int coup5 := 0;
+	int coup6 := 0;
+
+	int draw := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1)) {
+		draw := unif(0,6);
+		numberDraws := numberDraws + 1;
+
+		if(draw = 0) {
+			coup0 := 1;
+		}
+		if(draw = 1) {
+			coup1 := 1;
+		}
+		if(draw = 2) {
+			coup2 := 1;
+		}
+		if(draw = 3) {
+			coup3 := 1;
+		}
+		if(draw = 4) {
+			coup4 := 1;
+		}
+		if(draw = 5) {
+			coup5 := 1;
+		}
+		if(draw = 6) {
+			coup6 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon7-cost.pgcl b/examples/pgcl/coupon/coupon7-cost.pgcl
new file mode 100644
index 000000000..d71b367ca
--- /dev/null
+++ b/examples/pgcl/coupon/coupon7-cost.pgcl
@@ -0,0 +1,44 @@
+function coupon7() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+	int coup5 := 0;
+	int coup6 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int cost := 1;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1)) {
+		draw1 := unif(0,6);
+		draw2 := unif(0,6);
+		draw3 := unif(0,6);
+		cost := ceil(1.02 * cost);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon7-observe.pgcl b/examples/pgcl/coupon/coupon7-observe.pgcl
new file mode 100644
index 000000000..89f74bcd9
--- /dev/null
+++ b/examples/pgcl/coupon/coupon7-observe.pgcl
@@ -0,0 +1,46 @@
+function coupon7() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+	int coup5 := 0;
+	int coup6 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1)) {
+		draw1 := unif(0,6);
+		draw2 := unif(0,6);
+		draw3 := unif(0,6);
+		numberDraws := numberDraws + 1;
+
+		observe (draw1 != draw2 & draw1 != draw3 & draw2 != draw3);
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/coupon/coupon7.pgcl b/examples/pgcl/coupon/coupon7.pgcl
new file mode 100644
index 000000000..43bb38e99
--- /dev/null
+++ b/examples/pgcl/coupon/coupon7.pgcl
@@ -0,0 +1,44 @@
+function coupon7() {
+	int coup0 := 0;
+	int coup1 := 0;
+	int coup2 := 0;
+	int coup3 := 0;
+	int coup4 := 0;
+	int coup5 := 0;
+	int coup6 := 0;
+
+	int draw1 := 0;
+	int draw2 := 0;
+	int draw3 := 0;
+
+	int numberDraws := 0;
+
+	while (!(coup0 = 1) | !(coup1 = 1) | !(coup2 = 1) | !(coup3 = 1) | !(coup4 = 1) | !(coup5= 1) | !(coup6 = 1)) {
+		draw1 := unif(0,6);
+		draw2 := unif(0,6);
+		draw3 := unif(0,6);
+		numberDraws := numberDraws + 1;
+
+		if(draw1 = 0 | draw2 = 0 | draw3 = 0) {
+			coup0 := 1;
+		}
+		if(draw1 = 1 | draw2 = 1 | draw3 = 1) {
+			coup1 := 1;
+		}
+		if(draw1 = 2 | draw2 = 2 | draw3 = 2) {
+			coup2 := 1;
+		}
+		if (draw1 = 3 | draw2 = 3 | draw3 = 3) {
+			coup3 := 1;
+		}
+		if (draw1 = 4 | draw2 = 4 | draw3 = 4) {
+			coup4 := 1;
+		}
+		if (draw1 = 5 | draw2 = 5 | draw3 = 5) {
+			coup5 := 1;
+		}
+		if (draw1 = 6 | draw2 = 6 | draw3 = 6) {
+			coup6 := 1;
+		}
+	}
+}
diff --git a/examples/pgcl/crowds/crowds100-100-observeOther.pgcl b/examples/pgcl/crowds/crowds100-100-observeOther.pgcl
new file mode 100644
index 000000000..042b1d232
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-100-observeOther.pgcl
@@ -0,0 +1,35 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 100;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+	observe(observeOther > 25);
+}
diff --git a/examples/pgcl/crowds/crowds100-100.pgcl b/examples/pgcl/crowds/crowds100-100.pgcl
new file mode 100644
index 000000000..384340bd2
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-100.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 100;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds100-60-observeOther.pgcl b/examples/pgcl/crowds/crowds100-60-observeOther.pgcl
new file mode 100644
index 000000000..0578344f0
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-60-observeOther.pgcl
@@ -0,0 +1,35 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 60;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+	observe(observeOther > 15);
+}
diff --git a/examples/pgcl/crowds/crowds100-60-param.pgcl b/examples/pgcl/crowds/crowds100-60-param.pgcl
new file mode 100644
index 000000000..92bd1d051
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-60-param.pgcl
@@ -0,0 +1,34 @@
+function crowds(double PF, double bad) {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 60;
+	int observeSender := 0; // in [0, TotalRuns]
+	int observeOther := 0; // in [0, TotalRuns]
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [bad] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[PF]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds100-60.pgcl b/examples/pgcl/crowds/crowds100-60.pgcl
new file mode 100644
index 000000000..5e3ccd71e
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-60.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 60;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds100-80-observeOther.pgcl b/examples/pgcl/crowds/crowds100-80-observeOther.pgcl
new file mode 100644
index 000000000..62a412425
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-80-observeOther.pgcl
@@ -0,0 +1,36 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 80;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					// lastSender := unif(0, 24);
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+	observe(observeOther > 20);
+}
diff --git a/examples/pgcl/crowds/crowds100-80.pgcl b/examples/pgcl/crowds/crowds100-80.pgcl
new file mode 100644
index 000000000..f9fa42758
--- /dev/null
+++ b/examples/pgcl/crowds/crowds100-80.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 80;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/100] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds3-3-param.pgcl b/examples/pgcl/crowds/crowds3-3-param.pgcl
new file mode 100644
index 000000000..8486d0a75
--- /dev/null
+++ b/examples/pgcl/crowds/crowds3-3-param.pgcl
@@ -0,0 +1,34 @@
+function crowds(double PF, double bad) {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 3;
+	int observeSender := 0; // in [0, TotalRuns]
+	int observeOther := 0; // in [0, TotalRuns]
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [bad] {
+				{
+					{ lastSender:=0; } [1/3] { lastSender := 1; }
+				}
+				[PF]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds3-3.pgcl b/examples/pgcl/crowds/crowds3-3.pgcl
new file mode 100644
index 000000000..3106f70ca
--- /dev/null
+++ b/examples/pgcl/crowds/crowds3-3.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 3;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/3] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds3-5-param.pgcl b/examples/pgcl/crowds/crowds3-5-param.pgcl
new file mode 100644
index 000000000..177e73cf4
--- /dev/null
+++ b/examples/pgcl/crowds/crowds3-5-param.pgcl
@@ -0,0 +1,33 @@
+function crowds(double PF, double bad) {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 5;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [bad] {
+					{ lastSender:=0; } [1/3] { lastSender := 1; }
+				}
+				[PF]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds3-5.pgcl b/examples/pgcl/crowds/crowds3-5.pgcl
new file mode 100644
index 000000000..f43bb6505
--- /dev/null
+++ b/examples/pgcl/crowds/crowds3-5.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 5;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/3] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds5-20-param.pgcl b/examples/pgcl/crowds/crowds5-20-param.pgcl
new file mode 100644
index 000000000..121c29ace
--- /dev/null
+++ b/examples/pgcl/crowds/crowds5-20-param.pgcl
@@ -0,0 +1,34 @@
+function crowds(double PF, double bad) {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 20;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [bad] {
+				{
+					{ lastSender:=0; } [1/5] { lastSender := 1; }
+				}
+				[PF]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		// Set up new run.
+		delivered := 0;
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/crowds/crowds5-20.pgcl b/examples/pgcl/crowds/crowds5-20.pgcl
new file mode 100644
index 000000000..c27eae6ff
--- /dev/null
+++ b/examples/pgcl/crowds/crowds5-20.pgcl
@@ -0,0 +1,34 @@
+function crowds() {
+	int delivered := 0;
+	int lastSender := 0;
+	int remainingRuns := 20;
+	int observeSender := 0;
+	int observeOther := 0;
+
+	while(remainingRuns > 0) {
+		while(delivered = 0) {
+			{
+				if(lastSender = 0) {
+					observeSender := observeSender + 1;
+				} else {
+					observeOther := observeOther + 1;
+				}
+				lastSender := 0;
+				delivered := 1;
+			} [0.091] {
+				{
+					{ lastSender:=0; } [1/5] { lastSender := 1; }
+				}
+				[0.8]
+				{
+					lastSender := 0;
+					// When not forwarding, the message is delivered here.
+					delivered := 1;
+				}
+			}
+		}
+		delivered := 0;
+		// Set up new run.
+		remainingRuns := remainingRuns - 1;
+	}
+}
diff --git a/examples/pgcl/herman/herman10-det.pgcl b/examples/pgcl/herman/herman10-det.pgcl
new file mode 100644
index 000000000..5c38402aa
--- /dev/null
+++ b/examples/pgcl/herman/herman10-det.pgcl
@@ -0,0 +1,108 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [0.5] {x1 := 1;}
+	{x2  := 0;} [0.5] {x2 := 1;}
+	{x3  := 0;} [0.5] {x3 := 1;}
+	{x4  := 0;} [0.5] {x4 := 1;}
+	{x5  := 0;} [0.5] {x5 := 1;}
+	{x6  := 0;} [0.5] {x6 := 1;}
+	{x7  := 0;} [0.5] {x7 := 1;}
+	{x8  := 0;} [0.5] {x8 := 1;}
+	{x9  := 0;} [0.5] {x9 := 1;}
+	{x10  := 0;} [0.5] {x10 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		if(x1 = oldx10) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx10;
+		}
+		oldx10 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman10.pgcl b/examples/pgcl/herman/herman10.pgcl
new file mode 100644
index 000000000..a2bb9563e
--- /dev/null
+++ b/examples/pgcl/herman/herman10.pgcl
@@ -0,0 +1,108 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [] {x1 := 1;}
+	{x2  := 0;} [] {x2 := 1;}
+	{x3  := 0;} [] {x3 := 1;}
+	{x4  := 0;} [] {x4 := 1;}
+	{x5  := 0;} [] {x5 := 1;}
+	{x6  := 0;} [] {x6 := 1;}
+	{x7  := 0;} [] {x7 := 1;}
+	{x8  := 0;} [] {x8 := 1;}
+	{x9  := 0;} [] {x9 := 1;}
+	{x10  := 0;} [] {x10 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		if(x1 = oldx10) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx10;
+		}
+		oldx10 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman13-det.pgcl b/examples/pgcl/herman/herman13-det.pgcl
new file mode 100644
index 000000000..744c0361e
--- /dev/null
+++ b/examples/pgcl/herman/herman13-det.pgcl
@@ -0,0 +1,138 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [0.5] {x1 := 1;}
+	{x2  := 0;} [0.5] {x2 := 1;}
+	{x3  := 0;} [0.5] {x3 := 1;}
+	{x4  := 0;} [0.5] {x4 := 1;}
+	{x5  := 0;} [0.5] {x5 := 1;}
+	{x6  := 0;} [0.5] {x6 := 1;}
+	{x7  := 0;} [0.5] {x7 := 1;}
+	{x8  := 0;} [0.5] {x8 := 1;}
+	{x9  := 0;} [0.5] {x9 := 1;}
+	{x10  := 0;} [0.5] {x10 := 1;}
+	{x11  := 0;} [0.5] {x11 := 1;}
+	{x12  := 0;} [0.5] {x12 := 1;}
+	{x13  := 0;} [0.5] {x13 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		if(x1 = oldx13) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx13;
+		}
+		oldx13 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman13.pgcl b/examples/pgcl/herman/herman13.pgcl
new file mode 100644
index 000000000..057cf9568
--- /dev/null
+++ b/examples/pgcl/herman/herman13.pgcl
@@ -0,0 +1,138 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [] {x1 := 1;}
+	{x2  := 0;} [] {x2 := 1;}
+	{x3  := 0;} [] {x3 := 1;}
+	{x4  := 0;} [] {x4 := 1;}
+	{x5  := 0;} [] {x5 := 1;}
+	{x6  := 0;} [] {x6 := 1;}
+	{x7  := 0;} [] {x7 := 1;}
+	{x8  := 0;} [] {x8 := 1;}
+	{x9  := 0;} [] {x9 := 1;}
+	{x10  := 0;} [] {x10 := 1;}
+	{x11  := 0;} [] {x11 := 1;}
+	{x12  := 0;} [] {x12 := 1;}
+	{x13  := 0;} [] {x13 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		if(x1 = oldx13) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx13;
+		}
+		oldx13 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman17-det.pgcl b/examples/pgcl/herman/herman17-det.pgcl
new file mode 100644
index 000000000..f572bf2a6
--- /dev/null
+++ b/examples/pgcl/herman/herman17-det.pgcl
@@ -0,0 +1,178 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int x14  := 0;
+	int x15  := 0;
+	int x16  := 0;
+	int x17  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+	int oldx14 := 0;
+	int oldx15 := 0;
+	int oldx16 := 0;
+	int oldx17 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [0.5] {x1 := 1;}
+	{x2  := 0;} [0.5] {x2 := 1;}
+	{x3  := 0;} [0.5] {x3 := 1;}
+	{x4  := 0;} [0.5] {x4 := 1;}
+	{x5  := 0;} [0.5] {x5 := 1;}
+	{x6  := 0;} [0.5] {x6 := 1;}
+	{x7  := 0;} [0.5] {x7 := 1;}
+	{x8  := 0;} [0.5] {x8 := 1;}
+	{x9  := 0;} [0.5] {x9 := 1;}
+	{x10  := 0;} [0.5] {x10 := 1;}
+	{x11  := 0;} [0.5] {x11 := 1;}
+	{x12  := 0;} [0.5] {x12 := 1;}
+	{x13  := 0;} [0.5] {x13 := 1;}
+	{x14  := 0;} [0.5] {x14 := 1;}
+	{x15  := 0;} [0.5] {x15 := 1;}
+	{x16  := 0;} [0.5] {x16 := 1;}
+	{x17  := 0;} [0.5] {x17 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		oldx14  := x14;
+		oldx15  := x15;
+		oldx16  := x16;
+		oldx17  := x17;
+		if(x1 = oldx17) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx17;
+		}
+		oldx17 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+		if(x14 = oldx13) {
+			{x14 := 0;} [0.5] {x14 := 1;}
+		} else {
+			x14 := oldx13;
+		}
+		oldx13 := 0;
+		if(x15 = oldx14) {
+			{x15 := 0;} [0.5] {x15 := 1;}
+		} else {
+			x15 := oldx14;
+		}
+		oldx14 := 0;
+		if(x16 = oldx15) {
+			{x16 := 0;} [0.5] {x16 := 1;}
+		} else {
+			x16 := oldx15;
+		}
+		oldx15 := 0;
+		if(x17 = oldx16) {
+			{x17 := 0;} [0.5] {x17 := 1;}
+		} else {
+			x17 := oldx16;
+		}
+		oldx16 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman17.pgcl b/examples/pgcl/herman/herman17.pgcl
new file mode 100644
index 000000000..b8cb86176
--- /dev/null
+++ b/examples/pgcl/herman/herman17.pgcl
@@ -0,0 +1,178 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int x14  := 0;
+	int x15  := 0;
+	int x16  := 0;
+	int x17  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+	int oldx14 := 0;
+	int oldx15 := 0;
+	int oldx16 := 0;
+	int oldx17 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [] {x1 := 1;}
+	{x2  := 0;} [] {x2 := 1;}
+	{x3  := 0;} [] {x3 := 1;}
+	{x4  := 0;} [] {x4 := 1;}
+	{x5  := 0;} [] {x5 := 1;}
+	{x6  := 0;} [] {x6 := 1;}
+	{x7  := 0;} [] {x7 := 1;}
+	{x8  := 0;} [] {x8 := 1;}
+	{x9  := 0;} [] {x9 := 1;}
+	{x10  := 0;} [] {x10 := 1;}
+	{x11  := 0;} [] {x11 := 1;}
+	{x12  := 0;} [] {x12 := 1;}
+	{x13  := 0;} [] {x13 := 1;}
+	{x14  := 0;} [] {x14 := 1;}
+	{x15  := 0;} [] {x15 := 1;}
+	{x16  := 0;} [] {x16 := 1;}
+	{x17  := 0;} [] {x17 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		oldx14  := x14;
+		oldx15  := x15;
+		oldx16  := x16;
+		oldx17  := x17;
+		if(x1 = oldx17) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx17;
+		}
+		oldx17 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+		if(x14 = oldx13) {
+			{x14 := 0;} [0.5] {x14 := 1;}
+		} else {
+			x14 := oldx13;
+		}
+		oldx13 := 0;
+		if(x15 = oldx14) {
+			{x15 := 0;} [0.5] {x15 := 1;}
+		} else {
+			x15 := oldx14;
+		}
+		oldx14 := 0;
+		if(x16 = oldx15) {
+			{x16 := 0;} [0.5] {x16 := 1;}
+		} else {
+			x16 := oldx15;
+		}
+		oldx15 := 0;
+		if(x17 = oldx16) {
+			{x17 := 0;} [0.5] {x17 := 1;}
+		} else {
+			x17 := oldx16;
+		}
+		oldx16 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman21-det.pgcl b/examples/pgcl/herman/herman21-det.pgcl
new file mode 100644
index 000000000..a59482d9e
--- /dev/null
+++ b/examples/pgcl/herman/herman21-det.pgcl
@@ -0,0 +1,218 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int x14  := 0;
+	int x15  := 0;
+	int x16  := 0;
+	int x17  := 0;
+	int x18  := 0;
+	int x19  := 0;
+	int x20  := 0;
+	int x21  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+	int oldx14 := 0;
+	int oldx15 := 0;
+	int oldx16 := 0;
+	int oldx17 := 0;
+	int oldx18 := 0;
+	int oldx19 := 0;
+	int oldx20 := 0;
+	int oldx21 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [0.5] {x1 := 1;}
+	{x2  := 0;} [0.5] {x2 := 1;}
+	{x3  := 0;} [0.5] {x3 := 1;}
+	{x4  := 0;} [0.5] {x4 := 1;}
+	{x5  := 0;} [0.5] {x5 := 1;}
+	{x6  := 0;} [0.5] {x6 := 1;}
+	{x7  := 0;} [0.5] {x7 := 1;}
+	{x8  := 0;} [0.5] {x8 := 1;}
+	{x9  := 0;} [0.5] {x9 := 1;}
+	{x10  := 0;} [0.5] {x10 := 1;}
+	{x11  := 0;} [0.5] {x11 := 1;}
+	{x12  := 0;} [0.5] {x12 := 1;}
+	{x13  := 0;} [0.5] {x13 := 1;}
+	{x14  := 0;} [0.5] {x14 := 1;}
+	{x15  := 0;} [0.5] {x15 := 1;}
+	{x16  := 0;} [0.5] {x16 := 1;}
+	{x17  := 0;} [0.5] {x17 := 1;}
+	{x18  := 0;} [0.5] {x18 := 1;}
+	{x19  := 0;} [0.5] {x19 := 1;}
+	{x20  := 0;} [0.5] {x20 := 1;}
+	{x21  := 0;} [0.5] {x21 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		oldx14  := x14;
+		oldx15  := x15;
+		oldx16  := x16;
+		oldx17  := x17;
+		oldx18  := x18;
+		oldx19  := x19;
+		oldx20 := x20;
+		oldx21 := x21;
+		if(x1 = oldx21) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx21;
+		}
+		oldx21 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+		if(x14 = oldx13) {
+			{x14 := 0;} [0.5] {x14 := 1;}
+		} else {
+			x14 := oldx13;
+		}
+		oldx13 := 0;
+		if(x15 = oldx14) {
+			{x15 := 0;} [0.5] {x15 := 1;}
+		} else {
+			x15 := oldx14;
+		}
+		oldx14 := 0;
+		if(x16 = oldx15) {
+			{x16 := 0;} [0.5] {x16 := 1;}
+		} else {
+			x16 := oldx15;
+		}
+		oldx15 := 0;
+		if(x17 = oldx16) {
+			{x17 := 0;} [0.5] {x17 := 1;}
+		} else {
+			x17 := oldx16;
+		}
+		oldx16 := 0;
+		if(x18 = oldx17) {
+			{x18 := 0;} [0.5] {x18 := 1;}
+		} else {
+			x18 := oldx17;
+		}
+		oldx17 := 0;
+		if(x19 = oldx18) {
+			{x19 := 0;} [0.5] {x19 := 1;}
+		} else {
+			x19 := oldx18;
+		}
+		oldx18 := 0;
+		if(x20 = oldx19) {
+			{x20 := 0;} [0.5] {x20 := 1;}
+		} else {
+			x20 := oldx19;
+		}
+		oldx19 := 0;
+		if(x21 = oldx20) {
+			{x21 := 0;} [0.5] {x21 := 1;}
+		} else {
+			x21 := oldx20;
+		}
+		oldx20 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman21.pgcl b/examples/pgcl/herman/herman21.pgcl
new file mode 100644
index 000000000..ccc00ca3f
--- /dev/null
+++ b/examples/pgcl/herman/herman21.pgcl
@@ -0,0 +1,218 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int x8  := 0;
+	int x9  := 0;
+	int x10  := 0;
+	int x11  := 0;
+	int x12  := 0;
+	int x13  := 0;
+	int x14  := 0;
+	int x15  := 0;
+	int x16  := 0;
+	int x17  := 0;
+	int x18  := 0;
+	int x19  := 0;
+	int x20  := 0;
+	int x21  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+	int oldx8 := 0;
+	int oldx9 := 0;
+	int oldx10 := 0;
+	int oldx11 := 0;
+	int oldx12 := 0;
+	int oldx13 := 0;
+	int oldx14 := 0;
+	int oldx15 := 0;
+	int oldx16 := 0;
+	int oldx17 := 0;
+	int oldx18 := 0;
+	int oldx19 := 0;
+	int oldx20 := 0;
+	int oldx21 := 0;
+
+	// determine starting token setup on the ring.
+	{x1  := 0;} [] {x1 := 1;}
+	{x2  := 0;} [] {x2 := 1;}
+	{x3  := 0;} [] {x3 := 1;}
+	{x4  := 0;} [] {x4 := 1;}
+	{x5  := 0;} [] {x5 := 1;}
+	{x6  := 0;} [] {x6 := 1;}
+	{x7  := 0;} [] {x7 := 1;}
+	{x8  := 0;} [] {x8 := 1;}
+	{x9  := 0;} [] {x9 := 1;}
+	{x10  := 0;} [] {x10 := 1;}
+	{x11  := 0;} [] {x11 := 1;}
+	{x12  := 0;} [] {x12 := 1;}
+	{x13  := 0;} [] {x13 := 1;}
+	{x14  := 0;} [] {x14 := 1;}
+	{x15  := 0;} [] {x15 := 1;}
+	{x16  := 0;} [] {x16 := 1;}
+	{x17  := 0;} [] {x17 := 1;}
+	{x18  := 0;} [] {x18 := 1;}
+	{x19  := 0;} [] {x19 := 1;}
+	{x20  := 0;} [] {x20 := 1;}
+	{x21  := 0;} [] {x21 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		oldx8  := x8;
+		oldx9  := x9;
+		oldx10 := x10;
+		oldx11  := x11;
+		oldx12  := x12;
+		oldx13  := x13;
+		oldx14  := x14;
+		oldx15  := x15;
+		oldx16  := x16;
+		oldx17  := x17;
+		oldx18  := x18;
+		oldx19  := x19;
+		oldx20 := x20;
+		oldx21 := x21;
+		if(x1 = oldx21) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx21;
+		}
+		oldx21 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+		if(x8 = oldx7) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x8 := oldx7;
+		}
+		oldx7 := 0;
+		if(x9 = oldx8) {
+			{x9 := 0;} [0.5] {x9 := 1;}
+		} else {
+			x9 := oldx8;
+		}
+		oldx8 := 0;
+		if(x10 = oldx9) {
+			{x10 := 0;} [0.5] {x10 := 1;}
+		} else {
+			x10 := oldx9;
+		}
+		oldx9 := 0;
+		if(x11 = oldx10) {
+			{x11 := 0;} [0.5] {x11 := 1;}
+		} else {
+			x11 := oldx10;
+		}
+		oldx10 := 0;
+		if(x12 = oldx11) {
+			{x12 := 0;} [0.5] {x12 := 1;}
+		} else {
+			x12 := oldx11;
+		}
+		oldx11 := 0;
+		if(x13 = oldx12) {
+			{x13 := 0;} [0.5] {x13 := 1;}
+		} else {
+			x13 := oldx12;
+		}
+		oldx12 := 0;
+		if(x14 = oldx13) {
+			{x14 := 0;} [0.5] {x14 := 1;}
+		} else {
+			x14 := oldx13;
+		}
+		oldx13 := 0;
+		if(x15 = oldx14) {
+			{x15 := 0;} [0.5] {x15 := 1;}
+		} else {
+			x15 := oldx14;
+		}
+		oldx14 := 0;
+		if(x16 = oldx15) {
+			{x16 := 0;} [0.5] {x16 := 1;}
+		} else {
+			x16 := oldx15;
+		}
+		oldx15 := 0;
+		if(x17 = oldx16) {
+			{x17 := 0;} [0.5] {x17 := 1;}
+		} else {
+			x17 := oldx16;
+		}
+		oldx16 := 0;
+		if(x18 = oldx17) {
+			{x18 := 0;} [0.5] {x18 := 1;}
+		} else {
+			x18 := oldx17;
+		}
+		oldx17 := 0;
+		if(x19 = oldx18) {
+			{x19 := 0;} [0.5] {x19 := 1;}
+		} else {
+			x19 := oldx18;
+		}
+		oldx18 := 0;
+		if(x20 = oldx19) {
+			{x20 := 0;} [0.5] {x20 := 1;}
+		} else {
+			x20 := oldx19;
+		}
+		oldx19 := 0;
+		if(x21 = oldx19) {
+			{x21 := 0;} [0.5] {x21 := 1;}
+		} else {
+			x21 := oldx20;
+		}
+		oldx20 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman7-det.pgcl b/examples/pgcl/herman/herman7-det.pgcl
new file mode 100644
index 000000000..4374e28b0
--- /dev/null
+++ b/examples/pgcl/herman/herman7-det.pgcl
@@ -0,0 +1,77 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+
+	{x1  := 0;} [0.5] {x1 := 1;}
+	{x2  := 0;} [0.5] {x2 := 1;}
+	{x3  := 0;} [0.5] {x3 := 1;}
+	{x4  := 0;} [0.5] {x4 := 1;}
+	{x5  := 0;} [0.5] {x5 := 1;}
+	{x6  := 0;} [0.5] {x6 := 1;}
+	{x7  := 0;} [0.5] {x7 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		if(x1 = oldx7) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx7;
+		}
+		oldx7 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+	}
+}
diff --git a/examples/pgcl/herman/herman7.pgcl b/examples/pgcl/herman/herman7.pgcl
new file mode 100644
index 000000000..aca00ece3
--- /dev/null
+++ b/examples/pgcl/herman/herman7.pgcl
@@ -0,0 +1,77 @@
+function herman() {
+	int x1  := 0;
+	int x2  := 0;
+	int x3  := 0;
+	int x4  := 0;
+	int x5  := 0;
+	int x6  := 0;
+	int x7  := 0;
+	int oldx1 := 0;
+	int oldx2 := 0;
+	int oldx3 := 0;
+	int oldx4 := 0;
+	int oldx5 := 0;
+	int oldx6 := 0;
+	int oldx7 := 0;
+
+	{x1  := 0;} [] {x1 := 1;}
+	{x2  := 0;} [] {x2 := 1;}
+	{x3  := 0;} [] {x3 := 1;}
+	{x4  := 0;} [] {x4 := 1;}
+	{x5  := 0;} [] {x5 := 1;}
+	{x6  := 0;} [] {x6 := 1;}
+	{x7  := 0;} [] {x7 := 1;}
+
+	// finds a ring configuration with exactly one token in the ring.
+	while((x1 + x2 + x3 + x4 + x5 + x6 + x7) != 1) {
+		oldx1  := x1;
+		oldx2  := x2;
+		oldx3  := x3;
+		oldx4  := x4;
+		oldx5  := x5;
+		oldx6  := x6;
+		oldx7  := x7;
+		if(x1 = oldx7) {
+			{x1 := 0;} [0.5] {x1 := 1;}
+		} else {
+			x1 := oldx7;
+		}
+		oldx7 := 0;
+		if(x2 = oldx1) {
+			{x2 := 0;} [0.5] {x2 := 1;}
+		} else {
+			x2 := oldx1;
+		}
+		oldx1 := 0;
+		if(x3 = oldx2) {
+			{x3 := 0;} [0.5] {x3 := 1;}
+		} else {
+			x3 := oldx2;
+		}
+		oldx2 := 0;
+		if(x4 = oldx3) {
+			{x4 := 0;} [0.5] {x4 := 1;}
+		} else {
+			x4 := oldx3;
+		}
+		oldx3 := 0;
+		if(x5 = oldx4) {
+			{x5 := 0;} [0.5] {x5 := 1;}
+		} else {
+			x5 := oldx4;
+		}
+		oldx4 := 0;
+		if(x6 = oldx5) {
+			{x6 := 0;} [0.5] {x6 := 1;}
+		} else {
+			x6 := oldx5;
+		}
+		oldx5 := 0;
+		if(x7 = oldx6) {
+			{x7 := 0;} [0.5] {x7 := 1;}
+		} else {
+			x7 := oldx6;
+		}
+		oldx6 := 0;
+	}
+}
diff --git a/examples/pgcl/lotkavolterra.pgcl b/examples/pgcl/lotkavolterra.pgcl
new file mode 100644
index 000000000..0397f0cac
--- /dev/null
+++ b/examples/pgcl/lotkavolterra.pgcl
@@ -0,0 +1,49 @@
+function lotkavolterra() {
+
+	int goats     := 100;
+	int tigers    := 4;
+	int dwellTime := 0;
+	int curTime   := 0;
+	int b         := 0;
+
+	while(tigers > 0 & goats > 0) {
+
+		dwellTime := 0;
+		b := 1;
+
+		if(goats > 0 & tigers > 0) {
+
+			// geometric distribution with p = 0.5
+			while (b >= 1) {
+				{b := 1;} [0.5] {b := 0;}
+				dwellTime := dwellTime + 1;
+			}
+			curTime := curTime + dwellTime;
+			{tigers := tigers + 1;} [0.2] {{goats := goats - 1;} [0.1] {tigers := tigers - 1;}}
+
+		} else { if(goats > 0) {
+
+			// geometric distribution with p = 0.5
+			while (b >= 1) {
+				{b := 1;} [0.5] {b := 0;}
+				dwellTime := dwellTime + 1;
+			}
+			curTime := curTime + dwellTime;
+			goats   := goats + 1;
+
+		} else { if(tigers > 0) {
+
+			// geometric distribution with p = 0.5
+			while (b >= 1) {
+				{b := 1;} [0.5] {b := 0;}
+				dwellTime := dwellTime + 1;
+			}
+			curTime := curTime + dwellTime;
+			tigers  := tigers - 1;
+
+		} } }
+
+	}
+
+}
+
diff --git a/examples/pgcl/robot.pgcl b/examples/pgcl/robot.pgcl
new file mode 100644
index 000000000..ad320ccac
--- /dev/null
+++ b/examples/pgcl/robot.pgcl
@@ -0,0 +1,26 @@
+function robotOnGrid() {
+	
+	// robot starts in the lower left corner
+	int robotX := 1; int robotY := 20;
+
+	// janitor starts in the grid middle
+	int janitorX := ceil(20 / 2); int janitorY := ceil(20 / 2);
+
+	// iterates as long as the robot is not in the upper right corner
+	while(!(robotX = 20 & robotY = 1)) {
+
+		// robot perfoms one step at max each iteration
+		// checks whether we can go to the right and the janitor is not there
+		if(robotX < 20 & !((janitorX = robotX + 1) & (janitorY = robotY))) {
+			robotX := robotX + 1;
+		}
+		// checks whether we can go up and the janitor is not there
+		if(robotX = 20 & !((janitorX = robotX) & (janitorY = robotY - 1))) {
+			robotY := robotY - 1;
+		}
+
+		// moves the janitor randomly in one direction, not limited by any borders
+		{janitorX := janitorX + 1;}[0.25]{{janitorX := janitorX - 1;}[1/3]{{janitorY := janitorY + 1;}[0.375]{janitorY := janitorY - 1;}}}
+
+	}
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1a46888ae..7ca492152 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,7 @@ file(GLOB_RECURSE STORM_SOURCES_WITHOUT_MAIN ${PROJECT_SOURCE_DIR}/src/*/*.cpp)
 file(GLOB_RECURSE STORM_SOURCES_CLI ${PROJECT_SOURCE_DIR}/src/cli/*.cpp)
 file(GLOB_RECURSE STORM_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm.cpp)
 file(GLOB_RECURSE STORM_DFT_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm-dyftee.cpp)
+file(GLOB_RECURSE STORM_PGCL_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm-pgcl.cpp)
 
 
 # Additional include files like the storm-config.h
@@ -21,6 +22,7 @@ set(STORM_LIB_HEADERS ${STORM_HEADERS})
 list(REMOVE_ITEM STORM_LIB_HEADERS ${STORM_HEADERS_CLI})
 set(STORM_MAIN_SOURCES ${STORM_SOURCES_CLI} ${STORM_MAIN_FILE})
 set(STORM_DFT_MAIN_SOURCES ${STORM_SOURCES_CLI} ${STORM_DFT_MAIN_FILE})
+set(STORM_PGCL_MAIN_SOURCES ${STORM_SOURCES_CLI} ${STORM_PGCL_MAIN_FILE})
 set(STORM_MAIN_HEADERS ${STORM_HEADERS_CLI})
 
 file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/*.h ${PROJECT_SOURCE_DIR}/src/*.cpp)
@@ -53,6 +55,10 @@ add_executable(storm-dft-main ${STORM_DFT_MAIN_SOURCES} ${STORM_MAIN_HEADERS})
 target_link_libraries(storm-dft-main storm) # Adding headers for xcode
 set_target_properties(storm-dft-main PROPERTIES OUTPUT_NAME "storm-dft")
 
+add_executable(storm-pgcl-main ${STORM_PGCL_MAIN_SOURCES} ${STORM_MAIN_HEADERS})
+target_link_libraries(storm-pgcl-main storm)
+set_target_properties(storm-pgcl-main PROPERTIES OUTPUT_NAME "storm-pgcl")
+
 target_link_libraries(storm ${STORM_LINK_LIBRARIES})
 
 
diff --git a/src/parser/PgclParser.cpp b/src/parser/PgclParser.cpp
new file mode 100755
index 000000000..24a10e62f
--- /dev/null
+++ b/src/parser/PgclParser.cpp
@@ -0,0 +1,315 @@
+/* 
+ * File:   PgclParser.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 1. April 2015, 19:12
+ */
+
+#include "src/parser/PgclParser.h"
+// If the parser fails due to ill-formed data, this exception is thrown.
+#include "src/exceptions/WrongFormatException.h"
+
+namespace storm {
+    namespace parser {
+        storm::pgcl::PgclProgram PgclParser::parse(std::string const& filename) {
+            // Create empty program.
+            storm::pgcl::PgclProgram result;
+
+            // Open file and initialize result.
+            std::ifstream inputFileStream(filename, std::ios::in);
+            STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
+            
+            // Now try to parse the contents of the file.
+            try {
+                std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
+                result = parseFromString(fileContent, filename);
+            } catch(std::exception& e) {
+                // In case of an exception properly close the file before passing exception.
+                inputFileStream.close();
+                throw e;
+            }
+            
+            // Close the stream in case everything went smoothly and return result.
+            inputFileStream.close();
+            return result;
+        }
+        
+        storm::pgcl::PgclProgram PgclParser::parseFromString(std::string const& input, std::string const& filename) {
+            PositionIteratorType first(input.begin());
+            PositionIteratorType iter = first;
+            PositionIteratorType last(input.end());
+
+            // Create empty program.
+            storm::pgcl::PgclProgram result;
+            
+            // Create grammar.
+            storm::parser::PgclParser grammar(filename, first);
+            try {
+                // Start the parsing run.
+                bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
+                STORM_LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing of PGCL program failed.");
+                STORM_LOG_DEBUG("Parse of PGCL program finished.");
+            } catch(qi::expectation_failure<PositionIteratorType> const& e) {
+                // If the parser expected content different than the one provided, display information about the location of the error.
+                std::size_t lineNumber = boost::spirit::get_line(e.first);
+                // Now propagate exception.
+                STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
+            }
+
+            return result;
+        }
+        
+        PgclParser::PgclParser(std::string const& filename, Iterator first) :
+            PgclParser::base_type(program, "PGCL grammar"),
+            annotate(first),
+            expressionManager(std::shared_ptr<storm::expressions::ExpressionManager>(new storm::expressions::ExpressionManager())),
+            expressionParser(*expressionManager, invalidIdentifiers) {
+            this->enableExpressions();
+            /*
+             * PGCL grammar is defined here
+             */
+            // Rough program structure
+            program               = (qi::lit("function ") >> programName >> qi::lit("(") >> -(doubleDeclaration % qi::lit(",")) >> qi::lit(")") >> qi::lit("{") >>
+                                        sequenceOfStatements >>
+                                    qi::lit("}"))
+                                    [qi::_val = phoenix::bind(&PgclParser::createProgram, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
+            sequenceOfStatements %= +(statement);
+            
+            // Statements
+            statement         %= simpleStatement | compoundStatement;
+            simpleStatement   %= assignmentStatement | integerDeclarationStatement | observeStatement;
+            compoundStatement %= ifElseStatement | loopStatement | branchStatement;
+
+            // Simple statements
+            doubleDeclaration           = (qi::lit("double ") >> variableName)[qi::_val = phoenix::bind(&PgclParser::declareDoubleVariable, phoenix::ref(*this), qi::_1)];
+            integerDeclarationStatement = (qi::lit("int ") >> variableName >> qi::lit(":=") >> expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PgclParser::createIntegerDeclarationStatement, phoenix::ref(*this), qi::_1, qi::_2)];
+
+            assignmentStatement         = (variableName >> qi::lit(":=") >> (expression | uniformExpression) >> qi::lit(";"))[qi::_val = phoenix::bind(&PgclParser::createAssignmentStatement, phoenix::ref(*this), qi::_1, qi::_2)];
+            observeStatement            = (qi::lit("observe") >> qi::lit("(") >> booleanCondition >> qi::lit(")") >> qi::lit(";"))[qi::_val = phoenix::bind(&PgclParser::createObserveStatement, phoenix::ref(*this), qi::_1)];
+
+            // Compound statements
+            ifElseStatement        = (qi::lit("if") >> qi::lit("(") >> booleanCondition >> qi::lit(")") >> qi::lit("{") >>
+                                         sequenceOfStatements >>
+                                     qi::lit("}") >> -(qi::lit("else") >> qi::lit("{") >>
+                                         sequenceOfStatements >>
+                                     qi::lit("}")))
+                                     [qi::_val = phoenix::bind(&PgclParser::createIfElseStatement, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
+            branchStatement        = nondeterministicBranch | probabilisticBranch;
+            loopStatement          = (qi::lit("while") >> qi::lit("(") >> booleanCondition >> qi::lit(")") >> qi::lit("{") >>
+                                         sequenceOfStatements >>
+                                     qi::lit("}"))
+                                     [qi::_val = phoenix::bind(&PgclParser::createLoopStatement, phoenix::ref(*this), qi::_1, qi::_2)];
+            nondeterministicBranch = (qi::lit("{") >> sequenceOfStatements >> qi::lit("}") >> qi::lit("[]") >> qi::lit("{") >> sequenceOfStatements>> qi::lit("}"))[qi::_val = phoenix::bind(&PgclParser::createNondeterministicBranch, phoenix::ref(*this), qi::_1, qi::_2)];
+            probabilisticBranch    = (qi::lit("{") >> sequenceOfStatements >> qi::lit("}") >> qi::lit("[") >> expression >> qi::lit("]") >> qi::lit("{") >> sequenceOfStatements >> qi::lit("}"))[qi::_val = phoenix::bind(&PgclParser::createProbabilisticBranch, phoenix::ref(*this), qi::_2, qi::_1, qi::_3)];
+
+            // Expression and condition building, and basic identifiers
+            expression       %= expressionParser;
+            booleanCondition  = expressionParser[qi::_val = phoenix::bind(&PgclParser::createBooleanExpression, phoenix::ref(*this), qi::_1)];
+            uniformExpression = (qi::lit("unif") >> qi::lit("(") >> qi::int_ >> qi::lit(",") >> qi::int_ >> qi::lit(")"))[qi::_val = phoenix::bind(&PgclParser::createUniformExpression, phoenix::ref(*this), qi::_1, qi::_2)];
+            variableName     %= (+(qi::alnum | qi::lit("_"))) - (qi::lit("int") >> +(qi::alnum | qi::lit("_")));
+            programName      %= +(qi::alnum | qi::lit("_"));
+
+            // Enables location tracking for important entities
+            auto setLocationInfoFunction = this->annotate(*qi::_val, qi::_1, qi::_3);
+            qi::on_success(assignmentStatement, setLocationInfoFunction);
+            qi::on_success(observeStatement, setLocationInfoFunction);
+            qi::on_success(nondeterministicBranch, setLocationInfoFunction);
+            qi::on_success(probabilisticBranch, setLocationInfoFunction);
+            qi::on_success(loopStatement, setLocationInfoFunction);
+            qi::on_success(ifElseStatement, setLocationInfoFunction);
+            qi::on_success(integerDeclarationStatement, setLocationInfoFunction);
+
+            // Adds dummy to the 0-th location.
+            std::shared_ptr<storm::pgcl::AssignmentStatement> dummy(new storm::pgcl::AssignmentStatement());
+            this->locationToStatement.insert(this->locationToStatement.begin(), dummy);
+        } // PgclParser()
+
+        void PgclParser::enableExpressions() {
+            (this->expressionParser).setIdentifierMapping(&this->identifiers_);
+        }
+
+        /*
+         * Creators for various program parts. They all follow the basic scheme 
+         * to retrieve the subparts of the program part and mold them together 
+         * into one new statement. They wrap the statement constructors and
+         * throw excpetions in case something unexpected was parsed, e.g.
+         * (x+5) as a boolean expression, or types of assignments don't match.
+         */
+        storm::pgcl::PgclProgram PgclParser::createProgram(std::string const& programName, boost::optional<std::vector<storm::expressions::Variable> > parameters, std::vector<std::shared_ptr<storm::pgcl::Statement> > statements) {
+            // Creates an empty paramter list in case no parameters were given.
+            std::vector<storm::expressions::Variable> params;
+            if(parameters != boost::none) {
+                params = *parameters;
+            }
+            // Creates the actual program.
+            std::shared_ptr<storm::pgcl::PgclProgram> result(
+                    new storm::pgcl::PgclProgram(statements, this->locationToStatement, params, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, true)
+            );
+            result->back()->setLast(true);
+            // Sets the current program as a parent to all its direct children statements.
+            for(storm::pgcl::iterator it = result->begin(); it != result->end(); ++it) {
+                (*it)->setParentProgram(result);
+            }
+            return *result;
+        }
+
+        storm::expressions::Variable PgclParser::declareDoubleVariable(std::string const& variableName) {
+            storm::expressions::Variable variable = expressionManager->declareRationalVariable(variableName);
+            this->identifiers_.add(variableName, variable.getExpression());
+            return variable;
+        }
+
+        std::shared_ptr<storm::pgcl::AssignmentStatement> PgclParser::createAssignmentStatement(std::string const& variableName, boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& assignedExpression) {
+            storm::expressions::Variable variable;
+            if(!(*expressionManager).hasVariable(variableName)) {
+                variable = (*expressionManager).declareIntegerVariable(variableName);
+            } else {
+                variable = (*expressionManager).getVariable(variableName);
+                // Checks if assignment types match.
+                if(assignedExpression.which() == 0 && !(variable.getType() == boost::get<storm::expressions::Expression>(assignedExpression).getType())) {
+                    STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Wrong type when assigning to " << variableName << ".");
+                }
+            }
+            std::shared_ptr<storm::pgcl::AssignmentStatement> newAssignment(new storm::pgcl::AssignmentStatement(variable, assignedExpression));
+            newAssignment->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, newAssignment);
+            currentLocationNumber++;
+            return newAssignment;
+        }
+
+        std::shared_ptr<storm::pgcl::AssignmentStatement> PgclParser::createIntegerDeclarationStatement(std::string const& variableName, storm::expressions::Expression const& assignedExpression) {
+            storm::expressions::Variable variable;
+            if(!(*expressionManager).hasVariable(variableName)) {
+                variable = (*expressionManager).declareIntegerVariable(variableName);
+                this->identifiers_.add(variableName, variable.getExpression());
+            } else {
+                // In case that a declaration already happened.
+                variable = (*expressionManager).getVariable(variableName);
+                STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Declaration of integer variable " << variableName << " which was already declared previously.");
+            }
+            std::shared_ptr<storm::pgcl::AssignmentStatement> newAssignment(new storm::pgcl::AssignmentStatement(variable, assignedExpression));
+            newAssignment->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, newAssignment);
+            currentLocationNumber++;
+            return newAssignment;
+        }
+
+        std::shared_ptr<storm::pgcl::ObserveStatement> PgclParser::createObserveStatement(storm::pgcl::BooleanExpression const& condition) {
+            std::shared_ptr<storm::pgcl::ObserveStatement> observe(new storm::pgcl::ObserveStatement(condition));
+            this->observeCreated = true;
+            observe->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, observe);
+            currentLocationNumber++;
+            return observe;
+        }
+
+        std::shared_ptr<storm::pgcl::IfStatement> PgclParser::createIfElseStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& ifBody, boost::optional<std::vector<std::shared_ptr<storm::pgcl::Statement> > > const& elseBody) {
+            std::shared_ptr<storm::pgcl::PgclProgram> ifBodyProgram(new storm::pgcl::PgclProgram(ifBody, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::IfStatement> ifElse;
+            if(elseBody) {
+                std::shared_ptr<storm::pgcl::PgclProgram> elseBodyProgram(new storm::pgcl::PgclProgram(*elseBody, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+                ifElse = std::shared_ptr<storm::pgcl::IfStatement>(new storm::pgcl::IfStatement(condition, ifBodyProgram, elseBodyProgram));
+                (*(ifElse->getIfBody()->back())).setLast(true);
+                (*(ifElse->getElseBody()->back())).setLast(true);
+                // Sets the current program as a parent to all its children statements.
+                for(storm::pgcl::iterator it = ifElse->getElseBody()->begin(); it != ifElse->getElseBody()->end(); ++it) {
+                    (*it)->setParentProgram(ifElse->getElseBody());
+                    (*it)->setParentStatement(ifElse);
+                }
+                for(storm::pgcl::iterator it = ifElse->getIfBody()->begin(); it != ifElse->getIfBody()->end(); ++it) {
+                    (*it)->setParentProgram(ifElse->getIfBody());
+                    (*it)->setParentStatement(ifElse);
+                }
+            } else {
+                ifElse = std::shared_ptr<storm::pgcl::IfStatement>(new storm::pgcl::IfStatement(condition, ifBodyProgram));
+                (*(ifElse->getIfBody()->back())).setLast(true);
+                // Sets the current program as a parent to all its children statements.
+                for(storm::pgcl::iterator it = ifElse->getIfBody()->begin(); it != ifElse->getIfBody()->end(); ++it) {
+                    (*it)->setParentProgram(ifElse->getIfBody());
+                    (*it)->setParentStatement(ifElse);
+                }
+            }
+            ifElse->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, ifElse);
+            currentLocationNumber++;
+            return ifElse;
+        }
+
+        std::shared_ptr<storm::pgcl::LoopStatement> PgclParser::createLoopStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& body) {
+            std::shared_ptr<storm::pgcl::PgclProgram> bodyProgram(new storm::pgcl::PgclProgram(body, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::LoopStatement> loop(new storm::pgcl::LoopStatement(condition, bodyProgram));
+            this->loopCreated = true;
+            // Sets the current program as a parent to all its children statements.
+            for(storm::pgcl::iterator it = loop->getBody()->begin(); it != loop->getBody()->end(); ++it) {
+                (*it)->setParentProgram(loop->getBody());
+                (*it)->setParentStatement(loop);
+            }
+            (*(loop->getBody()->back())).setLast(true);
+            loop->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, loop);
+            currentLocationNumber++;
+            return loop;
+        }
+
+        std::shared_ptr<storm::pgcl::NondeterministicBranch> PgclParser::createNondeterministicBranch(std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right) {
+            std::shared_ptr<storm::pgcl::PgclProgram> leftProgram(new storm::pgcl::PgclProgram(left, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::PgclProgram> rightProgram(new storm::pgcl::PgclProgram(right, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::NondeterministicBranch> branch(new storm::pgcl::NondeterministicBranch(leftProgram, rightProgram));
+            this->nondetCreated = true;
+            // Sets the left program as a parent to all its children statements.
+            for(storm::pgcl::iterator it = branch->getLeftBranch()->begin(); it != branch->getLeftBranch()->end(); ++it) {
+                (*it)->setParentProgram(branch->getLeftBranch());
+                (*it)->setParentStatement(branch);
+            }
+            // Sets the right program as a parent to all its children statements.
+            for(storm::pgcl::iterator it = branch->getRightBranch()->begin(); it != branch->getRightBranch()->end(); ++it) {
+                (*it)->setParentProgram(branch->getRightBranch());
+                (*it)->setParentStatement(branch);
+            }
+            (*(branch->getLeftBranch()->back())).setLast(true);
+            (*(branch->getRightBranch()->back())).setLast(true);
+            branch->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, branch);
+            currentLocationNumber++;
+            return branch;
+        }
+
+        std::shared_ptr<storm::pgcl::ProbabilisticBranch> PgclParser::createProbabilisticBranch(storm::expressions::Expression const& probability, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right) {
+            std::shared_ptr<storm::pgcl::PgclProgram> leftProgram(new storm::pgcl::PgclProgram(left, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::PgclProgram> rightProgram(new storm::pgcl::PgclProgram(right, this->expressionManager, this->loopCreated, this->nondetCreated, this->observeCreated, false));
+            std::shared_ptr<storm::pgcl::ProbabilisticBranch> branch(new storm::pgcl::ProbabilisticBranch(probability, leftProgram, rightProgram));
+            // Sets the left program as a parent to all its children statements.
+            for(storm::pgcl::iterator it = branch->getLeftBranch()->begin(); it != branch->getLeftBranch()->end(); ++it) {
+                (*it)->setParentProgram(branch->getLeftBranch());
+                (*it)->setParentStatement(branch);
+            }
+            // Sets the right program as a parent to all its children statements.
+            for(storm::pgcl::iterator it = branch->getRightBranch()->begin(); it != branch->getRightBranch()->end(); ++it) {
+                (*it)->setParentProgram(branch->getRightBranch());
+                (*it)->setParentStatement(branch);
+            }
+            (*(branch->getLeftBranch()->back())).setLast(true);
+            (*(branch->getRightBranch()->back())).setLast(true);
+            branch->setLocationNumber(this->currentLocationNumber);
+            this->locationToStatement.insert(this->locationToStatement.begin() + this->currentLocationNumber, branch);
+            currentLocationNumber++;
+            return branch;
+        }
+
+        storm::pgcl::BooleanExpression PgclParser::createBooleanExpression(storm::expressions::Expression const& expression) {
+            if(expression.hasBooleanType()) {
+                storm::pgcl::BooleanExpression booleanExpression = storm::pgcl::BooleanExpression(expression);
+                return booleanExpression;
+            } else {
+                // In case that a non-boolean expression was used (e.g. (x+5)).
+                STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Non boolean expression was used in a condition.");
+            }
+        }
+
+        storm::pgcl::UniformExpression PgclParser::createUniformExpression(int const& begin, int const& end) {
+            return storm::pgcl::UniformExpression(begin, end);
+        }
+
+    } // namespace parser
+} // namespace storm
+
diff --git a/src/parser/PgclParser.h b/src/parser/PgclParser.h
new file mode 100755
index 000000000..0ef0db7af
--- /dev/null
+++ b/src/parser/PgclParser.h
@@ -0,0 +1,154 @@
+/* 
+ * File:   PgclParser.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 1. April 2015, 19:12
+ */
+
+#ifndef PGCLPARSER_H
+#define	PGCLPARSER_H
+
+// Includes files for file input.
+#include <fstream>
+#include <memory>
+#include <iomanip>
+// Includes files for building and parsing the PGCL program
+#include "src/parser/SpiritParserDefinitions.h"
+#include "src/parser/ExpressionParser.h"
+#include "src/storage/expressions/ExpressionManager.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/pgcl/PgclProgram.h"
+#include "src/storage/pgcl/AssignmentStatement.h"
+#include "src/storage/pgcl/BooleanExpression.h"
+#include "src/storage/pgcl/UniformExpression.h"
+#include "src/storage/pgcl/IfStatement.h"
+#include "src/storage/pgcl/LoopStatement.h"
+#include "src/storage/pgcl/NondeterministicBranch.h"
+#include "src/storage/pgcl/ObserveStatement.h"
+#include "src/storage/pgcl/ProbabilisticBranch.h"
+#include "src/storage/pgcl/Statement.h"
+
+namespace storm {
+    namespace parser {
+        
+        class PgclParser : public qi::grammar<Iterator, storm::pgcl::PgclProgram(), Skipper> {
+        public:
+            /*!
+             * Parses the given file into the PGCL storage classes in case it
+             * complies with the PGCL syntax.
+             *
+             * @param filename the name of the file to parse.
+             * @return The resulting PGCL program.
+             */
+            static storm::pgcl::PgclProgram parse(std::string const& filename);
+            
+            /*!
+             * Parses the given input stream into the PGCL storage classes in
+             * case it complies with the PGCL syntax.
+             *
+             * @param input The input string to parse.
+             * @param filename Name of the file from which the input was read.
+             * @return The resulting PGCL program.
+             */
+            static storm::pgcl::PgclProgram parseFromString(std::string const& input, std::string const& filename);
+        private:
+            // Internal constructor used by the parseFromString function.
+            PgclParser(std::string const& filename, Iterator first);
+            // Nonterminals (and their semantic types) of the PGCL grammar.
+            qi::rule<Iterator, storm::pgcl::PgclProgram(), Skipper> program;
+            qi::rule<Iterator, std::vector<std::shared_ptr<storm::pgcl::Statement> >(), Skipper> sequenceOfStatements;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::Statement>(), Skipper> statement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::SimpleStatement>(), Skipper> simpleStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::CompoundStatement>(), Skipper> compoundStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::IfStatement>(), Skipper> ifElseStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::BranchStatement>(), Skipper> branchStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::LoopStatement>(), Skipper> loopStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::NondeterministicBranch>(), Skipper> nondeterministicBranch;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::ProbabilisticBranch>(), Skipper> probabilisticBranch;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::AssignmentStatement>(), Skipper> assignmentStatement;
+            qi::rule<Iterator, storm::expressions::Variable(), Skipper> declaration;
+            qi::rule<Iterator, storm::expressions::Variable(), Skipper> doubleDeclaration;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::AssignmentStatement>(), Skipper> integerDeclarationStatement;
+            qi::rule<Iterator, std::shared_ptr<storm::pgcl::ObserveStatement>(), Skipper> observeStatement;
+            qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
+            qi::rule<Iterator, storm::pgcl::BooleanExpression(), Skipper> booleanCondition;
+            qi::rule<Iterator, storm::pgcl::UniformExpression(), Skipper> uniformExpression;
+            qi::rule<Iterator, std::string(), Skipper> variableName;
+            qi::rule<Iterator, std::string(), Skipper> programName;
+
+            /// Denotes the invalid identifiers, which are later passed to the expression parser.
+            struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
+                keywordsStruct() {
+                    add
+                    ("while", 1)
+                    ("if", 2)
+                    ("observe", 3)
+                    ("int", 4)
+                    ("function", 5);
+                }
+            };
+
+            /// Initializes the invalid identifier struct.
+            keywordsStruct invalidIdentifiers;
+            /// Is used to store the identifiers of the PGCL program that are found while parsing.
+            qi::symbols<char, storm::expressions::Expression> identifiers_;
+
+            /// Functor used for annotating entities with line number information.
+            class PositionAnnotation {
+            public:
+                typedef void result_type;
+
+                PositionAnnotation(Iterator first) : first(first) {
+                    // Intentionally left empty.
+                }
+
+                template<typename Entity, typename First, typename Last>
+                result_type operator()(Entity& entity, First f, Last l) const {
+                    entity.setLineNumber(get_line(f));
+                }
+            private:
+                std::string filename;
+                Iterator const first;
+            };
+
+            /// A function used for annotating the entities with their position.
+            phoenix::function<PositionAnnotation> annotate;
+
+            /// Manages the expressions and their parsing externally.
+            std::shared_ptr<storm::expressions::ExpressionManager> expressionManager;
+            storm::parser::ExpressionParser expressionParser;
+
+            /// Stores a mapping from location numbers to statements.
+            std::vector<std::shared_ptr<storm::pgcl::Statement> > locationToStatement;
+
+            /// Saves whether a loop statements was created.
+            bool loopCreated    = false;
+            /// Saves whether a nondet statements was created.
+            bool nondetCreated  = false;
+            /// Saves whether a observe statement was created.
+            bool observeCreated = false;
+
+            /// Stores the unique identifier of the currently parsed statement, starting at 1.
+            std::size_t currentLocationNumber = 1;
+
+            /// Sets the expression parser to a mode where it actually generates valid expressions.
+            void enableExpressions();
+
+            // Constructors for the single program parts. They just wrap the statement constructors and throw exceptions in case something unexpected was parsed.
+            storm::pgcl::PgclProgram createProgram(std::string const& programName, boost::optional<std::vector<storm::expressions::Variable> > parameters, std::vector<std::shared_ptr<storm::pgcl::Statement> > statements);
+            storm::expressions::Variable declareDoubleVariable(std::string const& variableName);
+            std::shared_ptr<storm::pgcl::AssignmentStatement> createAssignmentStatement(std::string const& variableName, boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& assignedExpression);
+            std::shared_ptr<storm::pgcl::AssignmentStatement> createIntegerDeclarationStatement(std::string const& variableName, storm::expressions::Expression const& assignedExpression);
+            std::shared_ptr<storm::pgcl::ObserveStatement> createObserveStatement(storm::pgcl::BooleanExpression const& condition);
+            std::shared_ptr<storm::pgcl::IfStatement> createIfElseStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& if_body, boost::optional<std::vector<std::shared_ptr<storm::pgcl::Statement> > > const& else_body);
+            std::shared_ptr<storm::pgcl::LoopStatement> createLoopStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& body);
+            std::shared_ptr<storm::pgcl::NondeterministicBranch> createNondeterministicBranch(std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right);
+            std::shared_ptr<storm::pgcl::ProbabilisticBranch> createProbabilisticBranch(storm::expressions::Expression const& probability, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right);
+            storm::pgcl::BooleanExpression createBooleanExpression(storm::expressions::Expression const& expression);
+            storm::pgcl::UniformExpression createUniformExpression(int const& begin, int const& end);
+        };
+    } // namespace parser
+} // namespace storm
+
+#endif	/* PGCLPARSER_H */
+
diff --git a/src/settings/modules/PGCLSettings.cpp b/src/settings/modules/PGCLSettings.cpp
new file mode 100644
index 000000000..75e388123
--- /dev/null
+++ b/src/settings/modules/PGCLSettings.cpp
@@ -0,0 +1,41 @@
+#include "src/settings/modules/PGCLSettings.h"
+
+#include "src/settings/SettingsManager.h"
+#include "src/settings/SettingMemento.h"
+#include "src/settings/Option.h"
+#include "src/settings/OptionBuilder.h"
+#include "src/settings/ArgumentBuilder.h"
+#include "src/settings/Argument.h"
+
+#include "src/exceptions/InvalidSettingsException.h"
+
+namespace storm {
+    namespace settings {
+        namespace modules {
+            const std::string PGCLSettings::moduleName = "pgcl";
+            
+            const std::string PGCLSettings::pgclFileOptionName = "pgclfile";
+            const std::string PGCLSettings::pgclFileOptionShortName = "pgcl";
+            
+            PGCLSettings::PGCLSettings() : ModuleSettings(moduleName) {
+                this->addOption(storm::settings::OptionBuilder(moduleName, pgclFileOptionName, false, "Parses the pgcl program.").setShortName(pgclFileOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build());
+            }
+            
+            bool PGCLSettings::isPgclFileSet() const {
+                return this->getOption(pgclFileOptionName).getHasOptionBeenSet();
+            }
+            
+            std::string PGCLSettings::getPgclFilename() const {
+                return this->getOption(pgclFileOptionName).getArgumentByName("filename").getValueAsString();
+            }
+            
+            void PGCLSettings::finalize() {
+                
+            }
+            
+            bool PGCLSettings::check() const {
+                return true;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/settings/modules/PGCLSettings.h b/src/settings/modules/PGCLSettings.h
new file mode 100644
index 000000000..211fc8dca
--- /dev/null
+++ b/src/settings/modules/PGCLSettings.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "storm-config.h"
+#include "src/settings/modules/ModuleSettings.h"
+
+
+namespace storm {
+    namespace settings {
+        namespace modules {
+            class PGCLSettings : public ModuleSettings {
+            public:
+                /*!
+                 * Creates a new PGCL setting
+                 */
+                PGCLSettings();
+                
+                /**
+                 * Retrievew whether the pgcl file option was set
+                 */
+                bool isPgclFileSet() const;
+                
+                /**
+                 * Retrieves the pgcl file name
+                 */
+                std::string getPgclFilename() const;
+                
+                bool check() const override;
+                void finalize() override;
+                
+                static const std::string moduleName;
+                
+            private:
+                static const std::string pgclFileOptionName;
+                static const std::string pgclFileOptionShortName;
+                
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/AbstractStatementVisitor.h b/src/storage/pgcl/AbstractStatementVisitor.h
new file mode 100755
index 000000000..9a8cec6d1
--- /dev/null
+++ b/src/storage/pgcl/AbstractStatementVisitor.h
@@ -0,0 +1,33 @@
+//
+// Created by Lukas Westhofen on 22.04.15.
+//
+
+#ifndef STORM_ABSTRACTSTATEVISITOR_H
+#define STORM_ABSTRACTSTATEVISITOR_H
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class implements the visitor part of the visitor pattern. Every
+         * statement accepts such a visitor which then again calls the
+         * corresponding visit method of the visitor object. In such a way
+         * double dynamic dispatching can be realized. Every structure or
+         * function that requires to differentiate between concrete statement
+         * instantiations (such as if statements, assignments statements, ...)
+         * should be handled by a concrete visitor implementation.
+         */
+        class AbstractStatementVisitor {
+        public:
+            // Those functions need to be implemented for every possible
+            // statement instantiation.
+            virtual void visit(class AssignmentStatement&) = 0;
+            virtual void visit(class ObserveStatement&) = 0;
+            virtual void visit(class IfStatement&) = 0;
+            virtual void visit(class LoopStatement&) = 0;
+            virtual void visit(class NondeterministicBranch&) = 0;
+            virtual void visit(class ProbabilisticBranch&) = 0;
+        };
+    }
+}
+
+#endif //STORM_ABSTRACTSTATEVISITOR_H
diff --git a/src/storage/pgcl/AssignmentStatement.cpp b/src/storage/pgcl/AssignmentStatement.cpp
new file mode 100755
index 000000000..ba9702f8f
--- /dev/null
+++ b/src/storage/pgcl/AssignmentStatement.cpp
@@ -0,0 +1,37 @@
+/* 
+ * File:   AssignmentStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:42
+ */
+
+#include "src/storage/pgcl/AssignmentStatement.h"
+
+namespace storm {
+    namespace pgcl {
+        AssignmentStatement::AssignmentStatement(storm::expressions::Variable const& variable, boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& expression) :
+            variable(variable), expression(expression) {
+        }
+        
+        boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& AssignmentStatement::getExpression() {
+            return this->expression;
+        }
+
+        storm::expressions::Variable const& AssignmentStatement::getVariable() {
+            return this->variable;
+        }
+
+        void AssignmentStatement::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+
+        std::size_t AssignmentStatement::getNumberOfOutgoingTransitions() {
+            if(this->expression.which() == 1) {
+                return boost::get<storm::pgcl::UniformExpression>(this->expression).getEnd() - boost::get<storm::pgcl::UniformExpression>(this->expression).getBegin() + 1;
+            } else {
+                return 1;
+            }
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/AssignmentStatement.h b/src/storage/pgcl/AssignmentStatement.h
new file mode 100755
index 000000000..a49b9033b
--- /dev/null
+++ b/src/storage/pgcl/AssignmentStatement.h
@@ -0,0 +1,59 @@
+/* 
+ * File:   AssignmentStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:42
+ */
+
+#ifndef ASSIGNMENTSTATEMENT_H
+#define	ASSIGNMENTSTATEMENT_H
+
+#include "src/storage/pgcl/SimpleStatement.h"
+#include "src/storage/pgcl/UniformExpression.h"
+#include "src/storage/expressions/Expression.h"
+#include "src/storage/expressions/Variable.h"
+#include <boost/variant/variant.hpp>
+#include <boost/variant/get.hpp>
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents a simple assignment statement of the form
+         * identifier := expression; where the expression is either handled by
+         * the expression manager or is a uniform distribution expression.
+         */
+        class AssignmentStatement : public SimpleStatement {
+        public:
+            AssignmentStatement() = default;
+            /**
+             * Constructs an assignment statement with the variable as the left
+             * side and the expression as the right side of the assignment.
+             * @param variable The left hand variable of the assignment.
+             * @param expression The right hand expression of the assignment.
+             */
+            AssignmentStatement(storm::expressions::Variable const& variable, boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& expression);
+            AssignmentStatement(const AssignmentStatement& orig) = default;
+            virtual ~AssignmentStatement() = default;
+            std::size_t getNumberOfOutgoingTransitions();
+            void accept(class AbstractStatementVisitor&);
+            /**
+             * Returns the right hand expression of the assignemnt.
+             * @return The expression of the assignment.
+             */
+            boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& getExpression();
+            /**
+             * Returns the left hand variable of the assignemnt.
+             * @return The variable to which the expression is assigned.
+             */
+            storm::expressions::Variable const& getVariable();
+        private:
+            /// Represents the variable of our assignment statement.
+            storm::expressions::Variable variable;
+            /// Represents the right hand side of our assignment statement.
+            boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> expression;
+        };
+    }
+}
+
+#endif	/* ASSIGNMENTSTATEMENT_H */
+
diff --git a/src/storage/pgcl/BooleanExpression.cpp b/src/storage/pgcl/BooleanExpression.cpp
new file mode 100755
index 000000000..c60031ae9
--- /dev/null
+++ b/src/storage/pgcl/BooleanExpression.cpp
@@ -0,0 +1,22 @@
+/* 
+ * File:   BooleanExpression.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:44
+ */
+
+#include "src/storage/pgcl/BooleanExpression.h"
+#include "src/storage/expressions/ExpressionManager.h"
+
+namespace storm {
+    namespace pgcl {
+        BooleanExpression::BooleanExpression(storm::expressions::Expression const& booleanExpression) :
+            booleanExpression(booleanExpression) {
+        }
+        
+        storm::expressions::Expression& BooleanExpression::getBooleanExpression() {
+            return this->booleanExpression;
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/BooleanExpression.h b/src/storage/pgcl/BooleanExpression.h
new file mode 100755
index 000000000..cb6241914
--- /dev/null
+++ b/src/storage/pgcl/BooleanExpression.h
@@ -0,0 +1,42 @@
+/* 
+ * File:   BooleanExpression.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:44
+ */
+
+#ifndef BOOLEANEXPRESSION_H
+#define	BOOLEANEXPRESSION_H
+
+#include "src/storage/expressions/Expression.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class wraps an ordinary expression but allows only for boolean
+         * expressions to be handled, e.g. expressions of the form (x < 4) or
+         * (x != y), but not (x + 5).
+         */
+        class BooleanExpression {
+        public:
+            BooleanExpression() = default;
+            /**
+             * Constructs a boolean expression if the given expression is of a
+             * boolean type. Note that it is not checked whether the expression
+             * has a boolean type.
+             * @param booleanExpression The expression of a boolean type.
+             */
+            BooleanExpression(storm::expressions::Expression const& booleanExpression);
+            /**
+             * Returns the expression.
+             * @return The expression of boolean type.
+             */
+            storm::expressions::Expression& getBooleanExpression();
+        private:
+            storm::expressions::Expression booleanExpression;
+        };
+    }
+}
+
+#endif	/* BOOLEANEXPRESSION_H */
+
diff --git a/src/storage/pgcl/BranchStatement.cpp b/src/storage/pgcl/BranchStatement.cpp
new file mode 100755
index 000000000..4acd6a55a
--- /dev/null
+++ b/src/storage/pgcl/BranchStatement.cpp
@@ -0,0 +1,25 @@
+/* 
+ * File:   BranchStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:42
+ */
+
+#include "src/storage/pgcl/BranchStatement.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        std::shared_ptr<storm::pgcl::PgclProgram> BranchStatement::getLeftBranch() {
+            return this->leftBranch;
+        }
+
+        std::shared_ptr<storm::pgcl::PgclProgram> BranchStatement::getRightBranch() {
+            return this->rightBranch;
+        }
+
+        std::size_t BranchStatement::getNumberOfOutgoingTransitions() {
+            return 2;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/BranchStatement.h b/src/storage/pgcl/BranchStatement.h
new file mode 100755
index 000000000..bd390e2f3
--- /dev/null
+++ b/src/storage/pgcl/BranchStatement.h
@@ -0,0 +1,46 @@
+/* 
+ * File:   BranchStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:42
+ */
+
+#ifndef BRANCHSTATEMENT_H
+#define	BRANCHSTATEMENT_H
+
+#include "src/storage/pgcl/PgclProgram.h"
+#include "src/storage/pgcl/CompoundStatement.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This abstract class handles the branching statements. Every branch
+         * statement has a right and a left branch. Since branch statements are
+         * compound statements, every branch is again a complete PGCL program
+         * itself.
+         */
+        class BranchStatement : public CompoundStatement {
+        public:
+            BranchStatement() = default;
+            BranchStatement(const BranchStatement& orig) = default;
+            virtual ~BranchStatement() = default;
+            virtual void accept(class AbstractStatementVisitor&) = 0;
+            std::size_t getNumberOfOutgoingTransitions();
+            /**
+             * Returns the left branch of the statement.
+             * @return The left branch PGCL program.
+             */
+            std::shared_ptr<storm::pgcl::PgclProgram> getLeftBranch();
+            /**
+             * Returns the right branch of the statement.
+             * @return The right branch PGCL program.
+             */
+            std::shared_ptr<storm::pgcl::PgclProgram> getRightBranch();
+        protected:
+            std::shared_ptr<storm::pgcl::PgclProgram> leftBranch;
+            std::shared_ptr<storm::pgcl::PgclProgram> rightBranch;
+        };
+    }
+}
+
+#endif	/* BRANCHSTATEMENT_H */
\ No newline at end of file
diff --git a/src/storage/pgcl/CompoundStatement.cpp b/src/storage/pgcl/CompoundStatement.cpp
new file mode 100755
index 000000000..c9ea40a4e
--- /dev/null
+++ b/src/storage/pgcl/CompoundStatement.cpp
@@ -0,0 +1,15 @@
+/* 
+ * File:   CompoundStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:41
+ */
+
+#include "src/storage/pgcl/CompoundStatement.h"
+
+namespace storm {
+    namespace pgcl {
+
+    }
+}
+
diff --git a/src/storage/pgcl/CompoundStatement.h b/src/storage/pgcl/CompoundStatement.h
new file mode 100755
index 000000000..bc075685c
--- /dev/null
+++ b/src/storage/pgcl/CompoundStatement.h
@@ -0,0 +1,32 @@
+/* 
+ * File:   CompoundStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:41
+ */
+
+#ifndef COMPOUNDSTATEMENT_H
+#define	COMPOUNDSTATEMENT_H
+
+#include "src/storage/pgcl/Statement.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This abstract class represents compound statements. A compound
+         * statement is a statement which has again a PGCL program as a child.
+         * Examples are if and loop statements.
+         */
+        class CompoundStatement : public Statement {
+        public:
+            CompoundStatement() = default;
+            CompoundStatement(const CompoundStatement& orig) = default;
+            virtual ~CompoundStatement() = default;
+            virtual void accept(class AbstractStatementVisitor&) = 0;
+        private:
+        };
+    }
+}
+
+#endif	/* COMPOUNDSTATEMENT_H */
+
diff --git a/src/storage/pgcl/IfStatement.cpp b/src/storage/pgcl/IfStatement.cpp
new file mode 100755
index 000000000..7e62a96ab
--- /dev/null
+++ b/src/storage/pgcl/IfStatement.cpp
@@ -0,0 +1,50 @@
+/* 
+ * File:   IfStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:42
+ */
+
+#include "IfStatement.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        IfStatement::IfStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& body) :
+            ifBody(body), condition(condition) {
+        }
+
+        IfStatement::IfStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& ifBody, std::shared_ptr<storm::pgcl::PgclProgram> const& elseBody) :
+            ifBody(ifBody), elseBody(elseBody), condition(condition) {
+            this->hasElseBody = true;
+        }
+
+        std::shared_ptr<storm::pgcl::PgclProgram> IfStatement::getIfBody() {
+            return this->ifBody;
+        }
+
+        std::shared_ptr<storm::pgcl::PgclProgram> IfStatement::getElseBody() {
+            if(this->elseBody) {
+                return this->elseBody;
+            } else {
+                throw "Tried to access non-present else body of if statement.";
+            }
+        }
+        
+        bool IfStatement::hasElse() {
+            return this->hasElseBody;
+        }
+        
+        storm::pgcl::BooleanExpression& IfStatement::getCondition() {
+            return this->condition;
+        }
+
+        void IfStatement::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+
+        std::size_t IfStatement::getNumberOfOutgoingTransitions() {
+            return 1;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/IfStatement.h b/src/storage/pgcl/IfStatement.h
new file mode 100755
index 000000000..515fc7ecc
--- /dev/null
+++ b/src/storage/pgcl/IfStatement.h
@@ -0,0 +1,78 @@
+/* 
+ * File:   IfStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:42
+ */
+
+#ifndef IFSTATEMENT_H
+#define	IFSTATEMENT_H
+
+#include "src/storage/pgcl/CompoundStatement.h"
+#include "src/storage/pgcl/BooleanExpression.h"
+#include "src/storage/pgcl/PgclProgram.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents if statements. Any if statement has a condition
+         * which is saved as a boolean expression, and a statement body which is
+         * again a PGCL program. Thus, an if statement is a compound statement.
+         * It is possibly for if statements to have one else body, but not
+         * mandatory.
+         */
+        class IfStatement : public CompoundStatement {
+        public:
+            IfStatement() = default;
+            /**
+             * Creates an if statement which saves only an if body.
+             * @param condition The guard of the statement body.
+             * @param body The if body.
+             */
+            IfStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& body);
+            /**
+             * Creates an if statement with an if and an else body.
+             * @param condition The guard of the if body.
+             * @param ifBody The if body.
+             * @param elseBody The else body.
+             */
+            IfStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& ifBody, std::shared_ptr<storm::pgcl::PgclProgram> const& elseBody);
+            IfStatement(const IfStatement& orig) = default;
+            virtual ~IfStatement() = default;
+            std::size_t getNumberOfOutgoingTransitions();
+            void accept(class AbstractStatementVisitor&);
+            /**
+             * Returns the if body of the if statement.
+             * @return The if body.
+             */
+            std::shared_ptr<storm::pgcl::PgclProgram> getIfBody();
+            /**
+             * Returns the else body of the if statement, if present. Otherwise
+             * it throws an excpetion.
+             * @return The else body.
+             */
+            std::shared_ptr<storm::pgcl::PgclProgram> getElseBody();
+            /**
+             * Returns true iff the if statement has an else body.
+             */
+            bool hasElse();
+            /**
+             * Returns the guard of the if statement.
+             * @return The condition.
+             */
+            storm::pgcl::BooleanExpression& getCondition();
+        private:
+            /// The if body is again a PGCL program.
+            std::shared_ptr<storm::pgcl::PgclProgram> ifBody;
+            /// The else body is again a PGCL program.
+            std::shared_ptr<storm::pgcl::PgclProgram> elseBody;
+            /// Memorizes if an else body was set. Set to false by default.
+            bool hasElseBody = false;
+            /// Saves the guard of the if statement.
+            storm::pgcl::BooleanExpression condition;
+        };
+    }
+}
+
+#endif	/* IFSTATEMENT_H */
+
diff --git a/src/storage/pgcl/LoopStatement.cpp b/src/storage/pgcl/LoopStatement.cpp
new file mode 100755
index 000000000..b61b7cede
--- /dev/null
+++ b/src/storage/pgcl/LoopStatement.cpp
@@ -0,0 +1,34 @@
+/* 
+ * File:   LoopStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:42
+ */
+
+#include "src/storage/pgcl/LoopStatement.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        LoopStatement::LoopStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& body) :
+            body(body), condition(condition) {
+        }
+
+        std::shared_ptr<storm::pgcl::PgclProgram> LoopStatement::getBody() {
+            return this->body;
+        }
+        
+        storm::pgcl::BooleanExpression& LoopStatement::getCondition() {
+            return this->condition;
+        }
+
+        void LoopStatement::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+
+        std::size_t LoopStatement::getNumberOfOutgoingTransitions() {
+            return 1;
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/LoopStatement.h b/src/storage/pgcl/LoopStatement.h
new file mode 100755
index 000000000..57196021e
--- /dev/null
+++ b/src/storage/pgcl/LoopStatement.h
@@ -0,0 +1,55 @@
+/* 
+ * File:   LoopStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:42
+ */
+
+#ifndef LOOPSTATEMENT_H
+#define	LOOPSTATEMENT_H
+
+#include "src/storage/pgcl/PgclProgram.h"
+#include "src/storage/pgcl/CompoundStatement.h"
+#include "src/storage/pgcl/BooleanExpression.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents a guarded loop statement. The guard is saved as
+         * a boolean expression. The body of the loop is again a PGCL program.
+         */
+        class LoopStatement : public CompoundStatement {
+        public:
+            LoopStatement() = default;
+            /**
+             * Constructs a loop statement initialized with the given condition
+             * and loop body program.
+             * @param condition The guard of the loop.
+             * @param body The body of the loop.
+             */
+            LoopStatement(storm::pgcl::BooleanExpression const& condition, std::shared_ptr<storm::pgcl::PgclProgram> const& body);
+            LoopStatement(const LoopStatement& orig) = default;
+            virtual ~LoopStatement() = default;
+            std::size_t getNumberOfOutgoingTransitions();
+            void accept(class AbstractStatementVisitor&);
+            /**
+             * Returns the loop body program.
+             * @return The loop body program.
+             */
+            std::shared_ptr<storm::pgcl::PgclProgram> getBody();
+            /**
+             * Returns the guard of the loop.
+             * @return The boolean condition of the loop.
+             */
+            storm::pgcl::BooleanExpression& getCondition();
+        private:
+            /// Represents the loop body.
+            std::shared_ptr<storm::pgcl::PgclProgram> body;
+            /// Represents the loop guard.
+            storm::pgcl::BooleanExpression condition;
+        };
+    }
+}
+
+#endif	/* LOOPSTATEMENT_H */
+
diff --git a/src/storage/pgcl/NondeterministicBranch.cpp b/src/storage/pgcl/NondeterministicBranch.cpp
new file mode 100755
index 000000000..5080fde2e
--- /dev/null
+++ b/src/storage/pgcl/NondeterministicBranch.cpp
@@ -0,0 +1,27 @@
+/* 
+ * File:   NondeterministicBranch.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:44
+ */
+
+#include "src/storage/pgcl/NondeterministicBranch.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        NondeterministicBranch::NondeterministicBranch(std::shared_ptr<storm::pgcl::PgclProgram> const& left, std::shared_ptr<storm::pgcl::PgclProgram> const& right) {
+            leftBranch = left;
+            rightBranch = right;
+        }
+
+        void NondeterministicBranch::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+
+        bool NondeterministicBranch::isNondet() {
+            return true;
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/NondeterministicBranch.h b/src/storage/pgcl/NondeterministicBranch.h
new file mode 100755
index 000000000..18b8700d5
--- /dev/null
+++ b/src/storage/pgcl/NondeterministicBranch.h
@@ -0,0 +1,39 @@
+/* 
+ * File:   NondeterministicBranch.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:44
+ */
+
+#ifndef NONDETERMINISTICBRANCH_H
+#define	NONDETERMINISTICBRANCH_H
+
+#include "src/storage/pgcl/BranchStatement.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents a nondeterministic branch that allows for a
+         * nondeterministic path-taking between two subprograms.
+         */
+        class NondeterministicBranch : public BranchStatement {
+        public:
+            NondeterministicBranch() = default;
+            /**
+             * Constructs a nondeterministic branch initialized with the given
+             * left and right subprograms.
+             * @param left The left (first) subprogram of the branch.
+             * @param right The right (second) subprogram of the branch.
+             */
+            NondeterministicBranch(std::shared_ptr<storm::pgcl::PgclProgram> const& left, std::shared_ptr<storm::pgcl::PgclProgram> const& right);
+            NondeterministicBranch(const NondeterministicBranch& orig) = default;
+            virtual ~NondeterministicBranch() = default;
+            void accept(class AbstractStatementVisitor&);
+            bool isNondet();
+        private:
+        };
+    }
+}
+
+#endif	/* NONDETERMINISTICBRANCH_H */
+
diff --git a/src/storage/pgcl/ObserveStatement.cpp b/src/storage/pgcl/ObserveStatement.cpp
new file mode 100755
index 000000000..fcf4f2135
--- /dev/null
+++ b/src/storage/pgcl/ObserveStatement.cpp
@@ -0,0 +1,29 @@
+/* 
+ * File:   ObserveStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:42
+ */
+
+#include "src/storage/pgcl/ObserveStatement.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        ObserveStatement::ObserveStatement(storm::pgcl::BooleanExpression const& condition) : condition(condition) {
+        }
+
+        void ObserveStatement::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+
+        storm::pgcl::BooleanExpression& ObserveStatement::getCondition() {
+            return this->condition;
+        }
+
+        std::size_t ObserveStatement::getNumberOfOutgoingTransitions() {
+            return 1;
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/ObserveStatement.h b/src/storage/pgcl/ObserveStatement.h
new file mode 100755
index 000000000..96461aa6a
--- /dev/null
+++ b/src/storage/pgcl/ObserveStatement.h
@@ -0,0 +1,47 @@
+/* 
+ * File:   ObserveStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:42
+ */
+
+#ifndef OBSERVESTATEMENT_H
+#define	OBSERVESTATEMENT_H
+
+#include "src/storage/pgcl/SimpleStatement.h"
+#include "src/storage/pgcl/BooleanExpression.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents an observe statement. Observe statements
+         * include a condition. If this condition doesn't hold, the program
+         * stops at that point in its execution.
+         */
+        class ObserveStatement : public SimpleStatement {
+        public:
+            ObserveStatement() = default;
+            /**
+             * Constructs an observe statement initialized with the given
+             * condition.
+             * @param condition The condition of the observe statement.
+             */
+            ObserveStatement(storm::pgcl::BooleanExpression const& condition);
+            ObserveStatement(const ObserveStatement& orig) = default;
+            std::size_t getNumberOfOutgoingTransitions();
+            virtual ~ObserveStatement() = default;
+            /**
+             * Returns the condition of the observe statement.
+             * @return The boolean expression of the observe statement.
+             */
+            storm::pgcl::BooleanExpression& getCondition();
+            void accept(class AbstractStatementVisitor&);
+        private:
+            /// Represents the assigned condition.
+            storm::pgcl::BooleanExpression condition;
+        };
+    }
+}
+
+#endif	/* OBSERVESTATEMENT_H */
+
diff --git a/src/storage/pgcl/PgclProgram.cpp b/src/storage/pgcl/PgclProgram.cpp
new file mode 100755
index 000000000..1b9d6916a
--- /dev/null
+++ b/src/storage/pgcl/PgclProgram.cpp
@@ -0,0 +1,114 @@
+/* 
+ * File:   PgclProgram.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:39
+ */
+
+#include "PgclProgram.h"
+#include "StatementPrinterVisitor.h"
+#include <typeinfo>
+
+namespace storm {
+    namespace pgcl {
+        PgclProgram::PgclProgram(vector const& statements, vector const& locationToStatement, std::vector<storm::expressions::Variable> const& parameters, std::shared_ptr<storm::expressions::ExpressionManager> expressions, bool hasLoop, bool hasNondet, bool hasObserve, bool isTop) :
+            sequenceOfStatements(statements),
+            locationToStatement(locationToStatement),
+            parameters(parameters),
+            expressions(expressions),
+            loop(hasLoop),
+            nondet(hasNondet),
+            observe(hasObserve),
+            top(isTop) {
+        }
+
+        PgclProgram::PgclProgram(vector const &statements, std::shared_ptr<storm::expressions::ExpressionManager> expressions, bool hasLoop, bool hasNondet, bool hasObserve, bool isTop) :
+            sequenceOfStatements(statements),
+            expressions(expressions),
+            loop(hasLoop),
+            nondet(hasNondet),
+            observe(hasObserve),
+            top(isTop) {
+        }
+
+        iterator PgclProgram::begin() {
+            return this->sequenceOfStatements.begin();
+        }
+
+        iterator PgclProgram::end() {
+            return this->sequenceOfStatements.end();
+        }
+
+        bool PgclProgram::empty() {
+            return this->sequenceOfStatements.empty();
+        }
+        
+        element PgclProgram::front() {
+            return this->sequenceOfStatements.front();
+        }
+        
+        element PgclProgram::back() {
+            return this->sequenceOfStatements.back();
+        }
+
+        unsigned long PgclProgram::size() {
+            return this->sequenceOfStatements.size();
+        }
+        
+        element PgclProgram::at(size_type n) {
+            return this->sequenceOfStatements.at(n);
+        }
+        
+        iterator PgclProgram::insert(iterator position, const element& statement) {
+            return this->sequenceOfStatements.insert(position, statement);
+        }
+        
+        void PgclProgram::clear() {
+            this->sequenceOfStatements.clear();
+        }
+
+        std::shared_ptr<storm::expressions::ExpressionManager> PgclProgram::getExpressionManager() {
+            return this->expressions;
+        }
+
+        std::vector<storm::expressions::Variable> PgclProgram::getParameters() {
+            return this->parameters;
+        }
+
+        bool PgclProgram::hasParameters() const {
+            return !(this->parameters.empty());
+        }
+
+        bool PgclProgram::hasObserve() const {
+            return this->observe;
+        }
+
+        bool PgclProgram::hasNondet() const {
+            return this->nondet;
+        }
+
+        bool PgclProgram::hasLoop() const {
+            return this->loop;
+        }
+
+        vector PgclProgram::getLocationToStatementVector() {
+            return this->locationToStatement;
+        }
+
+        iterator PgclProgram::find(element &statement) {
+            return std::find(this->sequenceOfStatements.begin(), this->sequenceOfStatements.end(), statement);
+        }
+
+        bool PgclProgram::isTop() const {
+            return this->top;
+        }
+
+        std::ostream& operator<<(std::ostream& stream, PgclProgram& program) {
+            storm::pgcl::StatementPrinterVisitor printer(stream);
+            for(iterator statement = program.begin(); statement != program.end(); statement++) {
+                (*statement)->accept(printer);
+            }
+            return stream;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/PgclProgram.h b/src/storage/pgcl/PgclProgram.h
new file mode 100755
index 000000000..acff0c7e1
--- /dev/null
+++ b/src/storage/pgcl/PgclProgram.h
@@ -0,0 +1,170 @@
+/* 
+ * File:   PgclProgram.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:39
+ */
+
+#ifndef PGCLPROGRAM_H
+#define	PGCLPROGRAM_H
+
+#include <vector>
+#include "src/storage/pgcl/Statement.h"
+#include "src/storage/pgcl/StatementPrinterVisitor.h"
+#include "src/storage/expressions/ExpressionManager.h"
+
+namespace storm {
+    namespace pgcl {
+        
+        typedef std::shared_ptr<storm::pgcl::Statement> element;
+        typedef std::vector<element> vector;
+        typedef std::vector<element>::iterator iterator;
+        typedef std::vector<element>::const_iterator const_iterator;
+        typedef std::vector<element>::size_type size_type;
+
+        /**
+         * This class represents a complete and functional PGCL program. It
+         * contains an expression manager which keeps track of the current
+         * identifiers and variable valuations. Other than that, it basically
+         * wraps a std::vector of program statements and is intended to be used
+         * as such.
+         */
+        class PgclProgram {
+        public:
+            PgclProgram() = default;
+            /**
+             * Constructs the PGCL program with the given sequence of statements
+             * (they may contain other PGCL programs). The expression manager
+             * handles the expressions and variables of the PGCL program.
+             * @param statements The sequence of statements representing the
+             * program.
+             * @param locationToStatements A vector containing the statement
+             * with location number i at the i-th position.
+             * @param parameters The list of parameters of the program.
+             * @param expressions The manager responsible for the expressions
+             * and variables of the program.
+             * @param hasLoop Whether the program contains a loop
+             * @param hasNondet Whether the program contains a nondeterministic
+             * statement.
+             * @param hasParam Whether the program is parameterized.
+             */
+            PgclProgram(vector const& statements, vector const& locationToStatement, std::vector<storm::expressions::Variable> const& parameters, std::shared_ptr<storm::expressions::ExpressionManager> expressions, bool hasLoop, bool hasNondet, bool hasObserve, bool isTop);
+            /**
+             * Does the same as the beforementioned constructor, but sets the
+             * location to statement vector to the empty vector. This
+             * constructor should be used for sub-programs, for which the
+             * location to statement relation doesn't make much sense.
+             * @param statements The sequence of statements representing the
+             * program.
+             * @param expressions The manager responsible for the expressions
+             * and variables of the program.
+             * @param hasLoop Whether the program contains a loop
+             * @param hasNondet Whether the program contains a nondeterministic
+             * statement.
+             * @param hasParam Whether the program is parameterized.
+             */
+            PgclProgram(vector const& statements, std::shared_ptr<storm::expressions::ExpressionManager> expressions, bool hasLoop, bool hasNondet, bool hasObserve, bool isTop);
+            PgclProgram(const PgclProgram & orig) = default;
+            PgclProgram & operator=(PgclProgram const& other) = default;
+            iterator begin();
+            iterator end();
+            element front();
+            element back();
+            unsigned long size();
+            element at(size_type n);
+            iterator insert(iterator position, const element& statement);
+            iterator find(element& statement);
+            void clear();
+            bool empty();
+            /**
+             * Returns a vector that has the statement with location number i at
+             * its i-th position. This allows for O(1)-access of statements if
+             * only the location number is given.
+             */
+            vector getLocationToStatementVector();
+            /**
+             * Returns the list of parameters of the PGCL program.
+             */
+            std::vector<storm::expressions::Variable> getParameters();
+            /**
+             * Returns the expression manager of the PGCL program, which is
+             * responsible for managing all expressions and variables of the
+             * the program and all its subprograms.
+             * @return The expression manager of the program.
+             */
+            std::shared_ptr<storm::expressions::ExpressionManager> getExpressionManager();
+            /**
+             * Returns true if the program contains a loop statement.
+             * @return True if the program has a loop.
+             */
+            bool hasLoop() const;
+            /**
+             * Returns true if the program contains a nondeterministic
+             * statement.
+             * @return True if the program has a nondeterministic statement.
+             */
+            bool hasNondet() const;
+            /**
+             * Returns true if the program contains an observe statement.
+             * @return True if the program has an observe statement.
+             */
+            bool hasObserve() const;
+            /**
+             * Returns true if the program is parameterized.
+             * @return True if the program has at least one parameter.
+             */
+            bool hasParameters() const;
+            /**
+             * Returns whether the program is no subprogram.
+             * @return True if the program is no subprogram of another
+             * program.
+             */
+            bool isTop() const;
+        private:
+            /**
+             * We are basically wrapping a std::vector which represents the
+             * ordered single statements of the program.
+             */
+            vector sequenceOfStatements;
+            /**
+             * Contains the statement with location i at its i-th position.
+             * Imagine this as the "unrolled" sequence of statements, so the
+             * recursion is resolved here.
+             */
+            vector locationToStatement;
+            /**
+             * Stores the parameters a.k.a. free variables of the PGCL program.
+             */
+            std::vector<storm::expressions::Variable> parameters;
+            /**
+             * Handles the expressions and variables for the whole program.
+             * The expressions of every subprogram are also handled by this
+             * manager. We are using a shared pointer since all subprograms
+             * are referring to that expression manager, too.
+             */
+            std::shared_ptr<storm::expressions::ExpressionManager> expressions;
+            /**
+             * Boolean variables to save some properties of the PGCL program.
+             * They are later on used by the model builder to possibly
+             * construct simpler models (e.g. if no loops, params and nondets
+             * are used, a DTMC suffices).
+             * The values are set to true if the PGCL parser hits a loop resp.
+             * nondet resp. observe resp. parameter statement.
+             */
+            bool loop    = false;
+            bool nondet  = false;
+            bool observe = false;
+            bool top     = false;
+        };
+        /**
+         * Prints every statement of the program along with their location
+         * numbers.
+         * @param stream The stream to print the program to.
+         * @param program The program to print.
+         */
+        std::ostream& operator<<(std::ostream& stream, PgclProgram& program);
+    }
+}
+
+#endif	/* PGCLPROGRAM_H */
+
diff --git a/src/storage/pgcl/ProbabilisticBranch.cpp b/src/storage/pgcl/ProbabilisticBranch.cpp
new file mode 100755
index 000000000..795284932
--- /dev/null
+++ b/src/storage/pgcl/ProbabilisticBranch.cpp
@@ -0,0 +1,28 @@
+/* 
+ * File:   ProbabilisticBranch.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:43
+ */
+
+#include "src/storage/pgcl/ProbabilisticBranch.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        ProbabilisticBranch::ProbabilisticBranch(storm::expressions::Expression const& probability, std::shared_ptr<storm::pgcl::PgclProgram> const& left, std::shared_ptr<storm::pgcl::PgclProgram> const& right) :
+        probability(probability) {
+            rightBranch = right;
+            leftBranch = left;
+        }
+        
+        storm::expressions::Expression& ProbabilisticBranch::getProbability() {
+            return this->probability;
+        }
+
+        void ProbabilisticBranch::accept(storm::pgcl::AbstractStatementVisitor& visitor) {
+            visitor.visit(*this);
+        }
+    }
+}
+
diff --git a/src/storage/pgcl/ProbabilisticBranch.h b/src/storage/pgcl/ProbabilisticBranch.h
new file mode 100755
index 000000000..669f3fb2a
--- /dev/null
+++ b/src/storage/pgcl/ProbabilisticBranch.h
@@ -0,0 +1,51 @@
+/* 
+ * File:   ProbabilisticBranch.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:43
+ */
+
+#ifndef PROBABILISTICBRANCH_H
+#define	PROBABILISTICBRANCH_H
+
+#include "src/storage/pgcl/BranchStatement.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class represents a probabilistic branch. It branches into two
+         * subprograms. The first program is executed with the probability p
+         * given by the assigned expression, the second subprogram is executed
+         * with probability (p - 1).
+         */
+        class ProbabilisticBranch : public BranchStatement {
+        public:
+            ProbabilisticBranch() = default;
+            /**
+             * Constructs a probabilistic branch initialized with the given
+             * probability and the left (first) and right (second) subprograms.
+             * Note that no verification is made whether the probability lies
+             * between 0 and 1 is made here. This is done at runtime of the PGCL
+             * program.
+             * @param probability The expression representing the probability of the branch.
+             * @param left The left (first) subprogram of the branch.
+             * @param right The right (second) subprogram of the branch.
+             */
+            ProbabilisticBranch(storm::expressions::Expression const& probability, std::shared_ptr<storm::pgcl::PgclProgram> const& left, std::shared_ptr<storm::pgcl::PgclProgram> const& right);
+            ProbabilisticBranch(const ProbabilisticBranch& orig) = default;
+            virtual ~ProbabilisticBranch() = default;
+            /**
+             * Returns the expression representing the probability.
+             * @return The expression representing the probability.
+             */
+            storm::expressions::Expression& getProbability();
+            void accept(class AbstractStatementVisitor&);
+        private:
+            /// The expression represents the probability of the branch.
+            storm::expressions::Expression probability;
+        };
+    }
+}
+
+#endif	/* PROBABILISTICBRANCH_H */
+
diff --git a/src/storage/pgcl/SimpleStatement.cpp b/src/storage/pgcl/SimpleStatement.cpp
new file mode 100755
index 000000000..b628b5d90
--- /dev/null
+++ b/src/storage/pgcl/SimpleStatement.cpp
@@ -0,0 +1,15 @@
+/* 
+ * File:   SimpleStatement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:41
+ */
+
+#include "src/storage/pgcl/SimpleStatement.h"
+
+namespace storm {
+    namespace pgcl {
+
+    }
+}
+
diff --git a/src/storage/pgcl/SimpleStatement.h b/src/storage/pgcl/SimpleStatement.h
new file mode 100755
index 000000000..252bc0b64
--- /dev/null
+++ b/src/storage/pgcl/SimpleStatement.h
@@ -0,0 +1,30 @@
+/* 
+ * File:   SimpleStatement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:41
+ */
+
+#ifndef SIMPLESTATEMENT_H
+#define	SIMPLESTATEMENT_H
+
+#include "src/storage/pgcl/Statement.h"
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        /*
+         * Simple statements are statements not containing other PGCL programs.
+         * Exactly one variable can be part of that statement.
+         */
+        class SimpleStatement : public Statement {
+        public:
+            SimpleStatement() = default;
+            SimpleStatement(const SimpleStatement& orig) = default;
+            virtual ~SimpleStatement() = default;
+            virtual void accept(class AbstractStatementVisitor& visitor) = 0;
+        };
+    }
+}
+#endif	/* SIMPLESTATEMENT_H */
+
diff --git a/src/storage/pgcl/Statement.cpp b/src/storage/pgcl/Statement.cpp
new file mode 100755
index 000000000..25aece4d4
--- /dev/null
+++ b/src/storage/pgcl/Statement.cpp
@@ -0,0 +1,64 @@
+/* 
+ * File:   Statement.cpp
+ * Author: Lukas Westhofen
+ * 
+ * Created on 11. April 2015, 17:41
+ */
+
+#include "src/storage/pgcl/Statement.h"
+
+namespace storm {
+    namespace pgcl {
+        const bool Statement::operator==(const Statement& other) const {
+            return (other.locationNumber == this->locationNumber);
+        }
+
+        void Statement::setLineNumber(std::size_t lineNumber) {
+            this->lineNumber = lineNumber;
+        }
+
+        std::size_t Statement::getLineNumber() {
+            return this->lineNumber;
+        }
+
+        std::size_t Statement::getLocationNumber() {
+            return this->locationNumber;
+        }
+
+        void Statement::setLocationNumber(std::size_t locationNumber) {
+            this->locationNumber = locationNumber;
+        }
+
+        bool Statement::isLast() {
+            return this->last;
+        }
+
+        void Statement::setLast(bool isLast) {
+            this->last = isLast;
+        }
+
+        bool Statement::isNondet() {
+            return false;
+        }
+
+        void Statement::setParentProgram(std::shared_ptr<storm::pgcl::PgclProgram> parentProgram) {
+                this->parentProgram = parentProgram;
+        }
+
+        boost::optional<std::shared_ptr<storm::pgcl::PgclProgram> > Statement::getParentProgram() {
+            return this->parentProgram;
+        }
+
+        void Statement::setParentStatement(std::shared_ptr<storm::pgcl::Statement> parentStatement) {
+            this->parentStatement = parentStatement;
+        }
+
+        boost::optional<std::shared_ptr<storm::pgcl::Statement> > Statement::getParentStatement() {
+            return this->parentStatement;
+        }
+
+        std::size_t Statement::getNumberOfOutgoingTransitions() {
+            return 1;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/Statement.h b/src/storage/pgcl/Statement.h
new file mode 100755
index 000000000..6afee011e
--- /dev/null
+++ b/src/storage/pgcl/Statement.h
@@ -0,0 +1,114 @@
+/* 
+ * File:   Statement.h
+ * Author: Lukas Westhofen
+ *
+ * Created on 11. April 2015, 17:41
+ */
+
+#ifndef STATEMENT_H
+#define	STATEMENT_H
+
+#include <cstdint>
+#include <memory>
+#include "boost/optional/optional.hpp"
+
+namespace storm {
+    namespace pgcl {
+        class PgclProgram;
+        /**
+         * A PGCL program consists of various statements. Statements can again
+         * save lists of statements as their children. To make life easier, the
+         * line number where that statement was parsed is stored. Additionaly,
+         * a unique non-negative index identifier (the location number) is
+         * saved.
+         */
+        class Statement {
+        public:
+            Statement() = default;
+            Statement(const Statement& orig) = default;
+            virtual ~Statement() = default;
+            /**
+             * Returns true iff the statements are equal, thus having the same
+             * location number.
+             * @param other The other statement to check equality of.
+             * @return True iff the statements are equal.
+             */
+            const bool operator==(const Statement& other) const;
+            /**
+             * Returns the line number inside the string where the PGCL program
+             * was parsed from.
+             * @return The line number of the statement.
+             */
+            std::size_t getLineNumber();
+            /**
+             * Sets the line number during the parsing process.
+             * @param lineNumber The location number of the statement.
+             */
+            void setLineNumber(std::size_t lineNumber);
+            /**
+             * Returns the unique location number of the statement.
+             * @return The line number of the statement.
+             */
+            std::size_t getLocationNumber();
+            /**
+             * Sets the unique location number of the statement.
+             * @param lineNumber The location number of the statement.
+             */
+            void setLocationNumber(std::size_t locationNumber);
+            /**
+             * Returns true if the statement is the last of its direct parent
+             * program.
+             * @return true Whether the statement is the last statement.
+             */
+            bool isLast();
+            /**
+             * Sets the information whether the statement is the last of its
+             * direct parent program.
+             * @param isLast Whether the statement is the last statement.
+             */
+            void setLast(bool isLast);
+            /**
+             * Returns wether the statements represents nondeterminism.
+             */
+            virtual bool isNondet();
+            /**
+             * Returns the number of transitions this statement will produce.
+             */
+            virtual std::size_t getNumberOfOutgoingTransitions();
+            virtual void accept(class AbstractStatementVisitor&) = 0;
+            /**
+             * Sets the parent program of the statement.
+             * @param parentProgram The parent program of the statement.
+             */
+            void setParentProgram(std::shared_ptr<storm::pgcl::PgclProgram> parentProgram);
+            /**
+             * Returns the parent program of the statement.
+             * @return The parent program of the statement.
+             */
+            boost::optional<std::shared_ptr<storm::pgcl::PgclProgram> > getParentProgram();
+            /**
+             * Sets the parent statement of the statement.
+             * @param parentProgram The parent statement of the statement.
+             */
+            void setParentStatement(std::shared_ptr<storm::pgcl::Statement> parentStatement);
+            /**
+             * Returns the parent statement of the statement.
+             * @return The parent statement of the statement.
+             */
+            boost::optional<std::shared_ptr<storm::pgcl::Statement> > getParentStatement();
+        protected:
+            /// The parent program of the statement.
+            boost::optional<std::shared_ptr<storm::pgcl::PgclProgram> > parentProgram;
+            /// The parent program of the statement.
+            boost::optional<std::shared_ptr<storm::pgcl::Statement> > parentStatement;
+            /// Represents the line number of the statement.
+            std::size_t lineNumber = 0;
+            /// Represents the unique statement location.
+            std::size_t locationNumber = 0;
+            /// If set to true, the statement is the last one of its (sub)program.
+            bool last = false;
+        };
+    }
+}
+#endif	/* STATEMENT_H */
+
diff --git a/src/storage/pgcl/StatementPrinterVisitor.cpp b/src/storage/pgcl/StatementPrinterVisitor.cpp
new file mode 100755
index 000000000..849014578
--- /dev/null
+++ b/src/storage/pgcl/StatementPrinterVisitor.cpp
@@ -0,0 +1,97 @@
+//
+// Created by Lukas Westhofen on 21.04.15.
+//
+
+#include "src/storage/pgcl/StatementPrinterVisitor.h"
+
+#include "src/storage/pgcl/AssignmentStatement.h"
+#include "src/storage/pgcl/ObserveStatement.h"
+#include "src/storage/pgcl/IfStatement.h"
+#include "src/storage/pgcl/LoopStatement.h"
+#include "src/storage/pgcl/NondeterministicBranch.h"
+#include "src/storage/pgcl/ProbabilisticBranch.h"
+
+namespace storm {
+    namespace pgcl {
+        StatementPrinterVisitor::StatementPrinterVisitor(std::ostream &stream) : stream(stream) {
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::AssignmentStatement& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            if(statement.getExpression().which() == 0) {
+                storm::expressions::Expression const& expression = boost::get<storm::expressions::Expression>(statement.getExpression());
+                this->stream << statement.getVariable().getType() << " " << statement.getVariable().getName() << " := " << expression << ";" << std::endl;
+            } else {
+                storm::pgcl::UniformExpression const& unif = boost::get<storm::pgcl::UniformExpression>(statement.getExpression());
+                this->stream << statement.getVariable().getType() << " " << statement.getVariable().getName() << " := " << "unif(" << unif.getBegin() << ", " << unif.getEnd() << ");" << std::endl;
+            }
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::ObserveStatement& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            this->stream << "observe(" << statement.getCondition().getBooleanExpression() << ");" << std::endl;
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::IfStatement& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            this->stream << "if(" << statement.getCondition().getBooleanExpression() << ") {" << std::endl;
+            int i = 1;
+            for(iterator it = (*(statement.getIfBody())).begin(); it != (*(statement.getIfBody())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "}" << std::endl;
+            if(statement.hasElse()) {
+                this->stream << "else {" << std::endl;
+                for(iterator it = (*(statement.getElseBody())).begin(); it != (*(statement.getElseBody())).end(); ++it) {
+                    (*(*it)).accept(*this);
+                    i++;
+                }
+                this->stream << "}" << std::endl;
+            }
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::LoopStatement& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            this->stream << "while(" << statement.getCondition().getBooleanExpression() << ") {" << std::endl;
+            int i = 1;
+            for(iterator it = (*(statement.getBody())).begin(); it != (*(statement.getBody())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "}" << std::endl;
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::NondeterministicBranch& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            this->stream << "{" << std::endl;
+            int i = 1;
+            for(iterator it = (*(statement.getLeftBranch())).begin(); it != (*(statement.getLeftBranch())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "} [] {" << std::endl;
+            for(iterator it = (*(statement.getRightBranch())).begin(); it != (*(statement.getRightBranch())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "}" << std::endl;
+        }
+
+        void StatementPrinterVisitor::visit(storm::pgcl::ProbabilisticBranch& statement) {
+            this->stream << statement.getLocationNumber() << ": ";
+            this->stream << "{" << std::endl;
+            int i = 1;
+            for(iterator it = (*(statement.getLeftBranch())).begin(); it != (*(statement.getLeftBranch())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "} [" << statement.getProbability() << "] {" << std::endl;
+            for(iterator it = (*(statement.getRightBranch())).begin(); it != (*(statement.getRightBranch())).end(); ++it) {
+                (*(*it)).accept(*this);
+                i++;
+            }
+            this->stream << "}" << std::endl;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/pgcl/StatementPrinterVisitor.h b/src/storage/pgcl/StatementPrinterVisitor.h
new file mode 100755
index 000000000..6e3ac9cc6
--- /dev/null
+++ b/src/storage/pgcl/StatementPrinterVisitor.h
@@ -0,0 +1,39 @@
+//
+// Created by Lukas Westhofen on 21.04.15.
+//
+
+#ifndef STORM_STATEMENTVISITOR_H
+#define STORM_STATEMENTVISITOR_H
+
+#include <iostream>
+#include <boost/variant/get.hpp>
+#include "src/storage/pgcl/AbstractStatementVisitor.h"
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This is a sample implementation of a concrete visitor which interface
+         * is defined in AbstractStatementVisitor.h. It prints out various
+         * details of the given statements when the visit method is called.
+         */
+        class StatementPrinterVisitor : public AbstractStatementVisitor {
+        public:
+            /**
+             * Constructs a statement printer which prints its output to the
+             * given stream.
+             * @param stream The stream to print to.
+             */
+            StatementPrinterVisitor(std::ostream& stream);
+            void visit(class AssignmentStatement&);
+            void visit(class ObserveStatement&);
+            void visit(class IfStatement&);
+            void visit(class LoopStatement&);
+            void visit(class NondeterministicBranch&);
+            void visit(class ProbabilisticBranch&);
+        private:
+            std::ostream& stream;
+        };
+    }
+}
+
+#endif //STORM_STATEMENTVISITOR_H
diff --git a/src/storage/pgcl/UniformExpression.cpp b/src/storage/pgcl/UniformExpression.cpp
new file mode 100644
index 000000000..a2c664454
--- /dev/null
+++ b/src/storage/pgcl/UniformExpression.cpp
@@ -0,0 +1,23 @@
+//
+// Created by foxnbk on 16.03.16.
+//
+
+#include "UniformExpression.h"
+
+namespace storm {
+    namespace pgcl {
+        UniformExpression::UniformExpression(int_fast64_t begin, int_fast64_t end) : begin(begin), end(end) {
+            // Intentionally left empty.
+        }
+
+        int_fast64_t UniformExpression::getBegin() const {
+            return this->begin;
+        }
+
+        int_fast64_t UniformExpression::getEnd() const {
+            return this->end;
+        }
+    }
+}
+
+#include "UniformExpression.h"
diff --git a/src/storage/pgcl/UniformExpression.h b/src/storage/pgcl/UniformExpression.h
new file mode 100644
index 000000000..f593f4631
--- /dev/null
+++ b/src/storage/pgcl/UniformExpression.h
@@ -0,0 +1,43 @@
+//
+// Created by Lukas Westhofen on 16.03.16.
+//
+
+#ifndef STORM_UNIFORMEXPRESSION_H
+#define STORM_UNIFORMEXPRESSION_H
+
+#include <stdint.h>
+
+namespace storm {
+    namespace pgcl {
+        /**
+         * This class wraps a uniform distribution expression of the form
+         * unif(k,l) where k <= l are both integers.
+         */
+        class UniformExpression {
+        public:
+            UniformExpression() = default;
+            /**
+             * Constructs a uniform expression with the given beginning and
+             * end.
+             * @param begin The begin of the uniform distribution.
+             * @param begin The end of the uniform distribution.
+             */
+            UniformExpression(int_fast64_t begin, int_fast64_t end);
+            /**
+             * Returns the begin of the uniform distribution.
+             * @return The begin of the uniform distribution.
+             */
+            int_fast64_t getBegin() const;
+            /**
+             * Returns the end of the uniform distribution.
+             * @return The end of the uniform distribution.
+             */
+            int_fast64_t getEnd() const;
+        private:
+            int_fast64_t begin = 0;
+            int_fast64_t end = 0;
+        };
+    }
+}
+
+#endif //STORM_UNIFORMEXPRESSION_H
diff --git a/src/storm-pgcl.cpp b/src/storm-pgcl.cpp
new file mode 100644
index 000000000..c756c5636
--- /dev/null
+++ b/src/storm-pgcl.cpp
@@ -0,0 +1,74 @@
+#include "src/parser/PgclParser.h"
+
+#include "logic/Formula.h"
+#include "utility/initialize.h"
+#include "utility/storm.h"
+#include "src/cli/cli.h"
+#include "src/exceptions/BaseException.h"
+#include "src/utility/macros.h"
+#include <boost/lexical_cast.hpp>
+
+#include "src/settings/modules/GeneralSettings.h"
+#include "src/settings/modules/PGCLSettings.h"
+#include "src/settings/modules/CoreSettings.h"
+#include "src/settings/modules/DebugSettings.h"
+//#include "src/settings/modules/CounterexampleGeneratorSettings.h"
+//#include "src/settings/modules/CuddSettings.h"
+//#include "src/settings/modules/SylvanSettings.h"
+#include "src/settings/modules/GmmxxEquationSolverSettings.h"
+#include "src/settings/modules/NativeEquationSolverSettings.h"
+//#include "src/settings/modules/BisimulationSettings.h"
+//#include "src/settings/modules/GlpkSettings.h"
+//#include "src/settings/modules/GurobiSettings.h"
+//#include "src/settings/modules/TopologicalValueIterationEquationSolverSettings.h"
+//#include "src/settings/modules/ParametricSettings.h"
+#include "src/settings/modules/EliminationSettings.h"
+
+/*!
+ * Initialize the settings manager.
+ */
+void initializeSettings() {
+    storm::settings::mutableManager().setName("StoRM-PGCL", "storm-pgcl");
+    
+    // Register all known settings modules.
+    storm::settings::addModule<storm::settings::modules::GeneralSettings>();
+    storm::settings::addModule<storm::settings::modules::PGCLSettings>();
+    storm::settings::addModule<storm::settings::modules::CoreSettings>();
+    storm::settings::addModule<storm::settings::modules::DebugSettings>();
+    //storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>();
+    //storm::settings::addModule<storm::settings::modules::CuddSettings>();
+    //storm::settings::addModule<storm::settings::modules::SylvanSettings>();
+    storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>();
+    storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>();
+    //storm::settings::addModule<storm::settings::modules::BisimulationSettings>();
+    //storm::settings::addModule<storm::settings::modules::GlpkSettings>();
+    //storm::settings::addModule<storm::settings::modules::GurobiSettings>();
+    //storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>();
+    //storm::settings::addModule<storm::settings::modules::ParametricSettings>();
+    storm::settings::addModule<storm::settings::modules::EliminationSettings>();
+}
+
+int main(const int argc, const char** argv) {
+    try {
+        storm::utility::setUp();
+        storm::cli::printHeader("StoRM-PGCL", argc, argv);
+        initializeSettings();
+        
+        bool optionsCorrect = storm::cli::parseOptions(argc, argv);
+        if (!optionsCorrect) {
+            return -1;
+        }
+        
+        if(storm::settings::getModule<storm::settings::modules::PGCLSettings>().isPgclFileSet()) {
+            storm::pgcl::PgclProgram prog = storm::parser::PgclParser::parse(storm::settings::getModule<storm::settings::modules::PGCLSettings>().getPgclFilename());
+            std::cout << prog << std::endl;
+        }
+        
+        
+        
+    }catch (storm::exceptions::BaseException const& exception) {
+        STORM_LOG_ERROR("An exception caused StoRM-PGCL to terminate. The message of the exception is: " << exception.what());
+    } catch (std::exception const& exception) {
+        STORM_LOG_ERROR("An unexpected exception occurred and caused StoRM-PGCL to terminate. The message of this exception is: " << exception.what());
+    }
+}
\ No newline at end of file