/** All nodes inside the shape.
		  * \note Be nice to the garbage collector and release the list when you have used it (optional)
		  * \see Pathfinding.Util.ListPool
		  *
		  * \see GetNodesInArea(Bounds)
		  */
		public List<GraphNode> GetNodesInArea (GraphUpdateShape shape) {
			return GetNodesInArea (shape.GetBounds (), shape);
		}
		/** All nodes inside the shape or if null, the bounding box.
		 * If a shape is supplied, it is assumed to be contained inside the bounding box.
		 * \see GraphUpdateShape.GetBounds
		 */
		private List<GraphNode> GetNodesInArea (Bounds b, GraphUpdateShape shape) {

			if (nodes == null || width*depth != nodes.Length) {
				return null;
			}

			// Get a buffer we can use
			List<GraphNode> inArea = ListPool<GraphNode>.Claim ();

			// Take the bounds and transform it using the matrix
			// Then convert that to a rectangle which contains
			// all nodes that might be inside the bounds
			Vector3 min, max;
			GetBoundsMinMax (b,inverseMatrix,out min, out max);

			int minX = Mathf.RoundToInt (min.x-0.5F);
			int maxX = Mathf.RoundToInt (max.x-0.5F);

			int minZ = Mathf.RoundToInt (min.z-0.5F);
			int maxZ = Mathf.RoundToInt (max.z-0.5F);

			var originalRect = new IntRect(minX,minZ,maxX,maxZ);

			// Rect which covers the whole grid
			var gridRect = new IntRect(0,0,width-1,depth-1);

			// Clamp the rect to the grid
			var rect = IntRect.Intersection (originalRect, gridRect);

			// Loop through all nodes in the rectangle
			for (int x = rect.xmin; x <= rect.xmax;x++) {
				for (int z = rect.ymin;z <= rect.ymax;z++) {

					int index = z*width+x;

					GraphNode node = nodes[index];

					// If it is contained in the bounds (and optionally the shape)
					// then add it to the buffer
					if (b.Contains ((Vector3)node.position) && (shape == null || shape.Contains ((Vector3)node.position))) {
						inArea.Add (node);
					}
				}
			}

			return inArea;
		}
		/** Updates graphs with a created GUO.
		 * Creates a Pathfinding.GraphUpdateObject with a Pathfinding.GraphUpdateShape
		 * representing the polygon of this object and update all graphs using AstarPath.UpdateGraphs.
		 * This will not update graphs directly. See AstarPath.UpdateGraph for more info.
		 */
		public void Apply () {

			if (AstarPath.active == null) {
				Debug.LogError ("There is no AstarPath object in the scene");
				return;
			}

			GraphUpdateObject guo;

			if (points == null || points.Length == 0) {

				var coll = GetComponent<Collider>();
				var rend = GetComponent<Renderer>();

				Bounds b;
				if (coll != null) b = coll.bounds;
				else if (rend != null) b = rend.bounds;
				else {
					Debug.LogWarning ("Cannot apply GraphUpdateScene, no points defined and no renderer or collider attached");
					return;
				}

				if (b.size.y < minBoundsHeight) b.size = new Vector3(b.size.x,minBoundsHeight,b.size.z);

				guo = new GraphUpdateObject (b);

			} else {
				var shape = new GraphUpdateShape ();
				shape.convex = convex;
				Vector3[] worldPoints = points;
				if (!useWorldSpace) {
					worldPoints = new Vector3[points.Length];
					Matrix4x4 matrix = transform.localToWorldMatrix;
					for (int i=0;i<worldPoints.Length;i++) worldPoints[i] = matrix.MultiplyPoint3x4 (points[i]);
				}

				shape.points = worldPoints;

				Bounds b = shape.GetBounds ();
				if (b.size.y < minBoundsHeight) b.size = new Vector3(b.size.x,minBoundsHeight,b.size.z);
				guo = new GraphUpdateObject (b);
				guo.shape = shape;
			}

			firstApplied = true;

			guo.modifyWalkability = modifyWalkability;
			guo.setWalkability = setWalkability;
			guo.addPenalty = penaltyDelta;
			guo.updatePhysics = updatePhysics;
			guo.updateErosion = updateErosion;
			guo.resetPenaltyOnPhysics = resetPenaltyOnPhysics;

			guo.modifyTag = modifyTag;
			guo.setTag = setTag;

			AstarPath.active.UpdateGraphs (guo);
		}