public List<Symbol> execute(Symbol s, ref List<Symbol> newState) {
			for (int i = 0; i < operations.Count; i++) {
				List<Symbol> newSymbols = new List<Symbol>();
				operations [i].applyOperation (s, ref newSymbols);
				if (newSymbols.Count > 0) {
					newState.AddRange(newSymbols);
				}
			}
			return newState;
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			//Debug.Log ("Trying to save " + shapeType);
			Vector3[] points = new Vector3[s.getPoints ().Count];
			for (int i = 0; i < s.getPoints ().Count; i++) {
				points [i] = s.getPoint (i);
			}
			symbols.Add (new Symbol (shapeType, points));


		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			if (sx != 1 && sy != 1 && sz != 1) {
				setScale (sx, sy, sz);
				return;
			}
			int numberOfPoints = s.getPoints ().Count;
			for (int i = 0; i < numberOfPoints; i++) {
				Vector3 p = s.getPoint (i);
				s.addPoint(new Vector3(p.x, sy, p.z));
			}
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			//Debug.Log ("Going to insert model " + this.model);
			GameObject newObj = GameObject.CreatePrimitive(PrimitiveType.Quad);

			GameObject.Destroy (newObj.GetComponent<MeshCollider> ());
			Vector3[] symbolPoints = s.getPoints ().ToArray();
			Vector3 normal = Vector3.Cross ((symbolPoints [1] - symbolPoints [0]), (symbolPoints [2] - symbolPoints [0]));
			newObj.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
			newObj.isStatic = true;

			newObj.transform.Translate ((symbolPoints [0]+symbolPoints[1]+symbolPoints[2]+symbolPoints[3])/4);
			normal = normal / normal.magnitude;

			newObj.transform.Rotate (0, 180, 0);
			Quaternion _facing = newObj.transform.rotation;
			newObj.transform.rotation = Quaternion.LookRotation (normal)*_facing;
			newObj.name = this.model;
			//GameObject newObj = new GameObject(this.model);
			if (this.model == "window") {
				newObj.transform.localScale = new Vector3 (1.5f, 2f, 2f);

				//newObj.transform.localRotation = Quaternion.Euler (0, 180, 0);
				int random = new System.Random ().Next (0, 4);
				if (random == 0) {
					newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/HighRiseGlass0016_1_S");
				} else if (random == 1) {
					newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/HighRiseGlass0055_1_S");
				
				} else if (random == 2) {
					newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/WindowsBacklit0020_1_s");

				} else if (random == 3) {
					newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/WindowsBLocks0002_4_s");
				}
			} else if (this.model == "door") {
				newObj.transform.localScale = new Vector3 (1.6f, 3.16f, 0.1f);
				//newObj.transform.Translate (0, 0.8f, 0);
				int random = new System.Random ().Next (0, 2);
				if (random == 0) {
				newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/DoorsWood0133_S");
				} else if (random == 1) {
					newObj.GetComponent<MeshRenderer> ().material.mainTexture = Resources.Load<Texture> ("Textures/DoorsWood0140_1_S");
				}
			}
			newObj.transform.Translate (-0.25f, 0, -0.25f);

			//newObj.transform.Rotate (Vector3.left, 270);

			if (this.model == "door") {
				//objMesh.transform.Translate(new Vector3(0.0f,-0.1f,0.75f));
			}


		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			//Debug.Log ("Shape gemaakt");
			GameObject shapeg = GameObject.CreatePrimitive (shape);
			shapeg.transform.parent = scope.getGameObject ().transform;
			shapeg.transform.localScale = new Vector3 (scope.getSx (), scope.getSy (), scope.getSz ());
			if (shape == PrimitiveType.Cylinder) {
				shapeg.transform.Translate (new Vector3 (scope.getSx() / 2, scope.getSy(), scope.getSz() / 2));
			} else {
				shapeg.transform.Translate (new Vector3 (scope.getSx() / 2, scope.getSy() / 2, scope.getSz() / 2));
			}
			shapeg.transform.Translate (scope.getTranslationWithScalar ());
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			//Debug.Log("Subdivide Operation on "+ dimension + " with " + parameters.Length + " parameters and " + outputs.Length + " outputs");
			List<Vector3> points = s.getPoints ();
			Color c = UnityEngine.Random.ColorHSV();
			//Debug.DrawLine (points [0], points [3], c, 2000f);
			//Debug.DrawLine (points [1], points [2], c, 2000f);
			float distance = 0;
			if (this.dimension == "X") {
				distance = (points [0] - points [1]).magnitude;
			} else if (this.dimension == "Y") {
				distance = (points [0] - points [3]).magnitude;
			}
				float rDistance = solveR (distance, parameters);
				//Debug.Log ("Distance :" + distance);
				//Debug.Log ("RDISTANCE = " + rDistance);
				float oldFraction = 0;
			for (int i = 0; i < parameters.Length; i++) {
				float value;
				if (parameters [i].EndsWith ("r")) {
					value = float.Parse (parameters [i].Substring (0, parameters [i].Length - 1)) * rDistance;
				} else {
					value = float.Parse (parameters [i]);
				}
				Vector3[] newPoints = new Vector3[4];
				float fraction = (oldFraction * distance + value) / distance;
				if (this.dimension == "X") {
					newPoints [0] = points [0] * oldFraction + points [1] * (1 - oldFraction);
					newPoints [1] = points [0] * fraction + points [1] * (1 - fraction);
					newPoints [2] = points [2] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [3] = points [2] * fraction + points [3] * (1 - fraction);
				} else if (this.dimension == "Y") {
					newPoints [2] = points [0] * oldFraction + points [2] * (1 - oldFraction);
					newPoints [0] = points [0] * fraction + points [2] * (1 - fraction);
					newPoints [3] = points [1] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [1] = points [1] * fraction + points [3] * (1 - fraction);
				}
				//Debug.DrawLine (newPoints [0], newPoints [1], c, 2000f);
				//Debug.DrawLine (newPoints [2], newPoints [3], c, 2000f);
				//Debug.DrawLine (newPoints [1], newPoints [3], c, 2000f);
				oldFraction = fraction;
				symbols.Add (new Symbol (outputs [i], newPoints));

			}

		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			switch (type) {
			case "sidefaces":
				List<Vector3> points = s.getPoints ();

				int localFaces = s.getPoints().Count /2;
				for (int i = 0; i < localFaces && localFaces > 4; i++) {
					Vector3 point1 = points[i];
					Vector3 point2 = points[(i+1)%localFaces];

					if (Vector3.Distance (point1, point2) > 0.001) {
						Vector3 newPoint = (point1 + point2) / 2;
						if ((i + 1) % localFaces < i) {
							Vector3 lowerPoint = (points [localFaces] + points [localFaces + i]) / 2;
							points.RemoveAt (localFaces + i);
							points.RemoveAt (localFaces);

							points.Insert (localFaces, lowerPoint);
							points.RemoveAt (i);
							points.RemoveAt (0);


							points.Insert (0, newPoint);

							localFaces--;
						} else {
							Vector3 lowerPoint = (points[localFaces+i+1]+points[localFaces+i])/2;
							points.RemoveAt (localFaces + i+1);
							points.RemoveAt (localFaces + i);
							points.Insert(localFaces+i,lowerPoint);
							points.RemoveAt (i+1);
							points.RemoveAt (i);

							points.Insert (i, newPoint);

							localFaces--;
						}

					}
						
				}
				//Debug.Log ("Sidefaces: " + numberOfFaces);
				Vector3 c = new Vector3 (0, 0, 0);
				int numberOfPoints = points.Count/2;
				for (int i = 0; i < numberOfPoints; i++) {
					c += points [i]/  numberOfPoints;
					//c.y += points [i].y / (float) numberOfPoints;
					//c.z += points [i].z / (float) numberOfPoints;
				}
				int numberOfFaces = points.Count / 2;
				for(int i = 0; i < numberOfFaces; i++) {
					Vector3[] sidefacePoints = new Vector3[4];
					sidefacePoints [0] = points [i];
					sidefacePoints [1] = points [(i + 1) % numberOfFaces];
					sidefacePoints [2] = points [numberOfFaces+i];
					sidefacePoints [3] = points [numberOfFaces+(i + 1) % numberOfFaces];
					Symbol newSymbol = new Symbol (this.param, sidefacePoints, true);

					newSymbol.extraValues.Add ("center", c);
					symbols.Add (newSymbol);
				}


				/*Mesh m = scope.getGameObject ().GetComponentInChildren<MeshFilter> ().mesh;
				m.RecalculateBounds ();
				m.RecalculateNormals ();
				Vector3[] vertices = new Vector3[m.vertices.Length / 3];
				HashSet<Vector3> uniqueVertices = new HashSet<Vector3> ();
				for (int i = 0; i < m.triangles.Length; i++) {
					
				}


				for (int i = 0; i < m.vertices.Length; i++) {
					uniqueVertices.Add (m.vertices [i]);
					Debug.Log (scope.getGameObject ().transform.GetChild (0).name);
					Debug.DrawRay (scope.getGameObject ().transform.GetChild (0).transform.localToWorldMatrix.MultiplyPoint (m.vertices [i]), m.normals [i], Color.cyan, 2000f);
					Debug.Log (scope.getGameObject ().transform.GetChild (0).transform.localToWorldMatrix.MultiplyPoint (m.vertices [i]));
				}

				//for (int i = 0; i < points.Length; i++) {
				//	Debug.DrawLine (points [i], points [i] + Vector3.up, Color.red, 2000f);
				//}*/
				break;
			}
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			scope.setTranslation (tx, ty, tz);
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			scope.getGameObject().transform.Rotate (new Vector3 (rx, ry, rz));
		}
		abstract public void applyOperation(Symbol s, ref List<Symbol> symbols);
		public Symbol getSuccessor(Symbol predecessor) {
			return predecessor;
		}
		public override void applyOperation(Symbol s, ref List<Symbol> symbols) {
			//Debug.Log("Repeat Operation on "+ dimension + " parameters and " + output + " as output");
			List<Vector3> points = s.getPoints ();
			Color c = UnityEngine.Random.ColorHSV();
			float distance = 0;
			if (dimension == "X") {
				distance = (points [0] - points [1]).magnitude;
			}
			else if(dimension == "Y") {
				distance = (points [0] - points [2]).magnitude;
			}
			int repetitions = (int)Math.Ceiling ((double)distance / float.Parse (this.length));
			float repDistance = distance / repetitions;
			float oldFraction = 0;
			//Debug.Log ("Repetitions: " + repetitions + " , RepDistance: " + repDistance);
			for (int i = 0; i < repetitions; i++) {
				Vector3[] newPoints = new Vector3[4];
				float fraction = (oldFraction * distance + repDistance) / distance;
				if (dimension == "X") {
					newPoints [0] = points [0] * oldFraction + points [1] * (1 - oldFraction);
					newPoints [1] = points [0] * fraction + points [1] * (1 - fraction);
					newPoints [2] = points [2] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [3] = points [2] * fraction + points [3] * (1 - fraction);
					//Debug.DrawLine (newPoints [0], newPoints [1], c, 2000f);
					//Debug.DrawLine (newPoints [2], newPoints [3], c, 2000f);
					//Debug.DrawLine (newPoints [1], newPoints [3], c, 2000f);
				} else if (dimension == "Y") {
					newPoints [2] = points [0] * oldFraction + points [2] * (1 - oldFraction);
					newPoints [0] = points [0] * fraction + points [2] * (1 - fraction);
					newPoints [3] = points [1] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [1] = points [1] * fraction + points [3] * (1 - fraction);
					//Debug.DrawLine (newPoints [0], newPoints [1], c, 2000f);
					//Debug.DrawLine (newPoints [2], newPoints [3], c, 2000f);
					//Debug.DrawLine (newPoints [1], newPoints [3], c, 2000f);
				}
				oldFraction = fraction;

				symbols.Add (new Symbol (output, newPoints));
			}
				/*float rDistance = solveR (distance, parameters);
				Debug.Log ("Distance :" + distance);
				Debug.Log ("RDISTANCE = " + rDistance);
				float oldFraction = 0;
				for (int i = 0; i < parameters.Length; i++) {
					float value;
					if (parameters [i].EndsWith ("r")) {
						value = float.Parse (parameters [i].Substring (0, parameters [i].Length - 1)) * rDistance;
					} else {
						value = float.Parse (parameters [i]);
					}
					Vector3[] newPoints = new Vector3[4];
					float fraction = (oldFraction * distance + value) / distance;
					newPoints [0] = points [0] * oldFraction + points [1] * (1 - oldFraction);
					newPoints [1] = points [0] * fraction + points [1] * (1 - fraction);
					newPoints [2] = points [2] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [3] = points [2] * fraction + points [3] * (1 - fraction);
					Debug.DrawLine (newPoints [0], newPoints [1], c, 2000f);
					Debug.DrawLine (newPoints [2], newPoints [3], c, 2000f);
					Debug.DrawLine (newPoints [1], newPoints [3], c, 2000f);
					oldFraction = fraction;
					symbols.Add (new Symbol (parameters [i], newPoints));

				}
			} else if (dimension == "Y") {
				float distance = (points [0] - points [2]).magnitude;
				float rDistance = solveR (distance, parameters);
				Debug.Log ("Distance :" + distance);
				Debug.Log ("RDISTANCE = " + rDistance);
				float oldFraction = 0;
				for (int i = 0; i < parameters.Length; i++) {
					float value;
					if (parameters [i].EndsWith ("r")) {
						value = float.Parse (parameters [i].Substring (0, parameters [i].Length - 1)) * rDistance;
					} else {
						value = float.Parse (parameters [i]);
					}
					Vector3[] newPoints = new Vector3[4];
					float fraction = (oldFraction * distance + value) / distance;
					newPoints [0] = points [0] * oldFraction + points [2] * (1 - oldFraction);
					newPoints [1] = points [0] * fraction + points [2] * (1 - fraction);
					newPoints [2] = points [1] * oldFraction + points [3] * (1 - oldFraction);
					newPoints [3] = points [1] * fraction + points [3] * (1 - fraction);
					Debug.DrawLine (newPoints [0], newPoints [1], c, 2000f);
					Debug.DrawLine (newPoints [2], newPoints [3], c, 2000f);
					Debug.DrawLine (newPoints [1], newPoints [3], c, 2000f);
					oldFraction = fraction;
					symbols.Add (new Symbol (parameters [i], newPoints));

				}
			}*/
		}