context: //Define optimizations is a A* Pathfinding Project Pro only feature
  //#define ProfileAstar	//Enables profiling of the pathfinding process
  //#define ASTARDEBUG			//Enables more debugging messages, enable if this script is behaving weird (crashing or throwing NullReference exceptions or something)
  //#define NoGUI			//Disables the use of the OnGUI function, can possibly improve performance by a tiny bit (disables the InGame option for path debugging)
  
  //#define ASTAR_FAST_NO_EXCEPTIONS
  
  using UnityEngine;
  using System.Collections;
  using System.Collections.Generic;
  using System.Threading;
  using Pathfinding;
  
  // Note sure why anyone would want to use this...
  //#define ASTAR_MORE_PATH_IDS //Increases the number of pathIDs from 2^16 to 2^32. Uses more memory
  
  [AddComponentMenu ("Pathfinding/Pathfinder")]
  /** Main Pathfinding System.
   * This class handles all the pathfinding system, calculates all paths and stores the info.\n
   * This class is a singleton class, meaning it should only exist at most one active instance of it in the scene.\n
   * It might be a bit hard to use directly, usually interfacing with the pathfinding system is done through the Seeker class.
   * 
   * \nosubgrouping
   * \ingroup relevant */
  public class AstarPath : MonoBehaviour {
  	
  	/** The version number for the A* %Pathfinding Project
  	 */
  	public static System.Version Version {
  		get {
  			return new System.Version (3,4,0,4);
  		}
  	}
  	
  	public enum AstarDistribution { WebsiteDownload, AssetStore };
  	
  	/** Used by the editor to guide the user to the correct place to download updates */
  	public static readonly AstarDistribution Distribution = AstarDistribution.WebsiteDownload;
  
  	/** Which branch of the A* Pathfinding Project is this release.
  	 * Used when checking for updates so that
  	 * users of the development versions can get notifications of development
  	 * updates.
  	 */
  	public static readonly string Branch = "master_Free";
  
  	/** Used by the editor to show some Pro specific stuff.
  	 * Note that setting this to true will not grant you any additional features */
  	public static readonly bool HasPro = false;
  	
  	/** See Pathfinding.AstarData */
  	public System.Type[] graphTypes {
  		get {
  			return astarData.graphTypes;
  		}
  	}
  	
  	/** Reference to the Pathfinding.AstarData object for this graph. The AstarData object stores information about all graphs. */
  	public AstarData astarData;
  	
  	/** Returns the active AstarPath object in the scene.*/
  	public new static AstarPath active;
  	
  	/** Shortcut to Pathfinding.AstarData.graphs */
  	public NavGraph[] graphs {
  		get {
  			if (astarData == null)
  				astarData = new AstarData ();
  			return astarData.graphs;
  		}
  		set {
  			if (astarData == null)
  				astarData = new AstarData ();
  			astarData.graphs = value;
  		}
  	}
  	
  #region InspectorDebug
  	/** @name Inspector - Debug
  	 * @{ */
  	
  	/** Toggle for showing the gizmo debugging for the graphs in the scene view (editor only). */
  	public bool showNavGraphs = true;
  	
  	/** Toggle to show unwalkable nodes.
  	  * \see unwalkableNodeDebugSize */
  	public bool showUnwalkableNodes = true;
  	
  	/** The mode to use for drawing nodes in the sceneview.
  	 * \see Pathfinding.GraphDebugMode
  	 */
  	public GraphDebugMode debugMode;
  	
  	/** Low value to use for certain #debugMode modes.
  	 * For example if #debugMode is set to G, this value will determine when the node will be totally red.
  	 * \see #debugRoof
  	 */
  	public float debugFloor = 0;
  	
  	/** High value to use for certain #debugMode modes.
  	 * For example if #debugMode is set to G, this value will determine when the node will be totally green.
  	 * \see #debugFloor
  	 */
  	public float debugRoof = 20000;
  	
  	/** If enabled, nodes will draw a line to their 'parent'.
  	 * This will show the search tree for the latest path. This is editor only.
  	 * \todo Add a showOnlyLastPath flag to indicate whether to draw every node or only the ones visited by the latest path.
  	 */
  	public bool	showSearchTree = false;
  	
  	/** Size of the red cubes shown in place of unwalkable nodes.
  	  * \see showUnwalkableNodes */
  	public float unwalkableNodeDebugSize = 0.3F;
  	
  	/** The amount of debugging messages.
  	 * Use less debugging to improve performance (a bit) or just to get rid of the Console spamming.\n
  	 * Use more debugging (heavy) if you want more information about what the pathfinding is doing.\n
  	 * InGame will display the latest path log using in game GUI. */
  	public PathLog logPathResults = PathLog.Normal;
  	
  	/** @} */
  #endregion
  	
  #region InspectorSettings
  	/** @name Inspector - Settings
  	 * @{ */
  	
  	/** Max Nearest Node Distance.
  	 * When searching for a nearest node, this is the limit (world units) for how far away it is allowed to be.
  	 * \see Pathfinding.NNConstraint.constrainDistance
  	 */
  	public float maxNearestNodeDistance = 100;
  	
  	/** Max Nearest Node Distance Squared.
  	 * \see #maxNearestNodeDistance */
  	public float maxNearestNodeDistanceSqr {
  		get { return maxNearestNodeDistance*maxNearestNodeDistance; }
  	}
  	
  	/** If true, all graphs will be scanned in Awake.
  	 * This does not include loading from the cache.
  	 * If you disable this, you will have to call \link Scan AstarPath.active.Scan () \endlink yourself to enable pathfinding,
  	 * alternatively you could load a saved graph from a file.
  	 */
  	public bool scanOnStartup = true;
  	
  	/** Do a full GetNearest search for all graphs.
  	 * Additinal searches will normally only be done on the graph which in the first, fast searches proved to have the closest node.
  	 * With this setting on, additional searches will be done on all graphs.\n
  	 * More technically: GetNearestForce on all graphs will be called if true, otherwise only on the one graph which's GetNearest search returned the best node.\n
  	 * Usually faster when disabled, but higher quality searches when enabled.
  	 * When using a a navmesh or recast graph, for best quality, this setting should be combined with the Pathfinding.NavMeshGraph.accurateNearestNode setting set to true.
  	 * \note For the PointGraph this setting doesn't matter much as it has only one search mode.
  	 */
  	public bool fullGetNearestSearch = false;
  	
  	/** Prioritize graphs.
  	 * Graphs will be prioritized based on their order in the inspector.
  	 * The first graph which has a node closer than #prioritizeGraphsLimit will be chosen instead of searching all graphs.
  	 */
  	public bool prioritizeGraphs = false;
  	
  	/** Distance limit for #prioritizeGraphs.
  	 * \see #prioritizeGraphs
  	 */
  	public float prioritizeGraphsLimit = 1F;
  	
  	/** Reference to the color settings for this AstarPath object.
  	 * Color settings include for example which color the nodes should be in, in the sceneview. */
  	public AstarColor colorSettings;
  	
  	/** Stored tag names.
  	 * \see AstarPath.FindTagNames
  	 * \see AstarPath.GetTagNames
  	 */
  	[SerializeField]
  	protected string[] tagNames = null;
  	
  	/** The heuristic to use.
  	 * The heuristic, often referred to as 'H' is the estimated cost from a node to the target.
  	 * Different heuristics affect how the path picks which one to follow from multiple possible with the same length
  	 * \see Pathfinding.Heuristic
  	 */
  	public Heuristic heuristic = Heuristic.Euclidean;
  	
  	/** The scale of the heuristic. If a smaller value than 1 is used, the pathfinder will search more nodes (slower).
  	 * If 0 is used, the pathfinding will be equal to dijkstra's algorithm.
  	 * If a value larger than 1 is used the pathfinding will (usually) be faster because it expands fewer nodes, but the paths might not longer be optimal
  	 */
  	public float heuristicScale = 1F;
  
  	/** Number of pathfinding threads to use.
  	 * Multithreading puts pathfinding in another thread, this is great for performance on 2+ core computers since the framerate will barely be affected by the pathfinding at all.
  	 * But this can cause strange errors and pathfinding stopping to work if you are not carefull (that is, if you are modifying the pathfinding scripts). For basic usage (not modding the pathfinding core) it should be safe.\n
  	 * - None indicates that the pathfinding is run in the Unity thread as a coroutine
  	 * - Automatic will try to adjust the number of threads to the number of cores and memory on the computer.
  	 * 	Less than 512mb of memory or a single core computer will make it revert to using no multithreading.
  	 * \see CalculateThreadCount
  	 * \astarpro
  	 */
  	public ThreadCount threadCount = ThreadCount.None;
  	
  	/** Max number of milliseconds to spend each frame for pathfinding.
  	 * At least 500 nodes will be searched each frame (if there are that many to search).
  	 * When using multithreading this value is quite irrelevant,
  	 * but do not set it too low since that could add upp to some overhead, 10ms will work good for multithreading */
  	public float maxFrameTime = 1F;
  	
  	/** Defines the minimum amount of nodes in an area.
  	 * If an area has less than this amount of nodes, the area will be flood filled again with the area ID 254,
  	 * it shouldn't affect pathfinding in any significant way.\n
  	 * If you want to be able to separate areas from one another for some reason (for example to do a fast check to see if a path is at all possible)
  	 * you should set this variable to 0.\n
  	  * Can be found in A* Inspector-->Settings-->Min Area Size
  	  */
  	public int minAreaSize = 10;
  	
  	/** Limit graph updates. If toggled, graph updates will be executed less often (specified by #maxGraphUpdateFreq).*/
  	public bool limitGraphUpdates = true;
  	
  	/** How often should graphs be updated. If #limitGraphUpdates is true, this defines the minimum amount of seconds between each graph update.*/
  	public float maxGraphUpdateFreq = 0.2F;
  	
  	/** @} */
  #endregion
  	
  #region DebugVariables
  	/** @name Debug Members
  	 * @{ */
  	
  	/** How many paths has been computed this run. From application start.\n
  	 * Debugging variable */
  	public static int PathsCompleted = 0;
  	
  	public static System.Int64 				TotalSearchedNodes = 0;
  	public static System.Int64			 	TotalSearchTime = 0;
  	
  	/** The time it took for the last call to Scan() to complete.
  	 * Used to prevent automatically rescanning the graphs too often (editor only) */
  	public float lastScanTime = 0F;
  	
  	/** The path to debug using gizmos.
  	 * This is equal to the last path which was calculated,
  	 * it is used in the editor to draw debug information using gizmos.*/
  	public Path debugPath;
  	
  	/** NodeRunData from #debugPath.
  	 * Returns null if #debugPath is null
  	 */
  	public PathHandler debugPathData {
  		get {
  			if (debugPath == null) return null;
  			return debugPath.pathHandler;
  		}
  	}
  	
  	/** This is the debug string from the last completed path.
  	 * Will be updated if #logPathResults == PathLog.InGame */
  	public string inGameDebugPath;
  	
  	/* @} */
  #endregion
  	
  #region StatusVariables
  	
  	/** Set when scanning is being done. It will be true up until the FloodFill is done.
  	 * Used to better support Graph Update Objects called for example in OnPostScan */
  	public bool isScanning = false;
  	
  	/** Number of parallel pathfinders.
  	 * Returns the number of concurrent processes which can calculate paths at once.
  	 * When using multithreading, this will be the number of threads, if not using multithreading it is always 1 (since only 1 coroutine is used).
  	 * \see threadInfos
  	 * \see IsUsingMultithreading
  	 */
  	public static int NumParallelThreads {
  		get {
  			return threadInfos != null ? threadInfos.Length : 0;
  		}
  	}
  	
  	/** Returns whether or not multithreading is used.
  	 * \exception System.Exception Is thrown when it could not be decided if multithreading was used or not.
  	 * This should not happen if pathfinding is set up correctly.
  	 * \note This uses info about if threads are running right now, it does not use info from the settings on the A* object.
  	 */
  	public static bool IsUsingMultithreading {
  		get {
  			if (threads != null && threads.Length > 0)
  				return true;
  			else if (threads != null && threads.Length == 0 && threadEnumerator != null)
  				return false;
  			else if (Application.isPlaying)
  				throw new System.Exception ("Not 'using threading' and not 'not using threading'... Are you sure pathfinding is set up correctly?\nIf scripts are reloaded in unity editor during play this could happen.\n"+
  					(threads != null ? ""+threads.Length : "NULL") + " " + (threadEnumerator != null));
  			else 
  				return false;
  		}
  	}
  	
  	/** Returns if any graph updates are waiting to be applied */
  	public bool IsAnyGraphUpdatesQueued { get { return graphUpdateQueue != null && graphUpdateQueue.Count > 0; }}
  	
  	private bool graphUpdateRoutineRunning = false;
  	
  	private bool isRegisteredForUpdate = false;
  	
  #endregion
  	
  #region Callbacks
  	/** @name Callbacks */
  	 /* Callbacks to pathfinding events.
  	 * These allow you to hook in to the pathfinding process.\n
  	 * Callbacks can be used like this:
  	 * \code
  	 * public void Start () {
  	 * 	AstarPath.OnPostScan += SomeFunction;
  	 * }
  	 * 
  	 * public void SomeFunction (AstarPath active) {
  	 * 	//This will be called every time the graphs are scanned
  	 * }
  	 * \endcode
  	*/
  	 /** @{ */
  	
  	/** Called on Awake before anything else is done.
  	  * This is called at the start of the Awake call, right after #active has been set, but this is the only thing that has been done.\n
  	  * Use this when you want to set up default settings for an AstarPath component created during runtime since some settings can only be changed in Awake
  	  * (such as multithreading related stuff)
  	  * \code
  	  * //Create a new AstarPath object on Start and apply some default settings
  	  * public void Start () {
  	  * 	AstarPath.OnAwakeSettings += ApplySettings;
  	  * 	AstarPath astar = AddComponent<AstarPath>();
  	  * }
  	  * 
  	  * public void ApplySettings () {
  	  * 	//Unregister from the delegate
  	  * 	AstarPath.OnAwakeSettings -= ApplySettings;
  	  * 	
  	  * 	//For example useMultithreading should not be changed after the Awake call
  	  * 	//so here's the only place to set it if you create the component during runtime
  	  * 	AstarPath.active.useMultithreading = true;
  	  * }
  	  * \endcode
  	  */
  	public static OnVoidDelegate OnAwakeSettings;
  	
  	public static OnGraphDelegate OnGraphPreScan; /**< Called for each graph before they are scanned */
  	
  	public static OnGraphDelegate OnGraphPostScan; /**< Called for each graph after they have been scanned. All other graphs might not have been scanned yet. */
  	
  	public static OnPathDelegate OnPathPreSearch; /**< Called for each path before searching. Be carefull when using multithreading since this will be called from a different thread. */
  	public static OnPathDelegate OnPathPostSearch; /**< Called for each path after searching. Be carefull when using multithreading since this will be called from a different thread. */
  	
  	public static OnScanDelegate OnPreScan; /**< Called before starting the scanning */
  	public static OnScanDelegate OnPostScan; /**< Called after scanning. This is called before applying links, flood-filling the graphs and other post processing. */
  	public static OnScanDelegate OnLatePostScan; /**< Called after scanning has completed fully. This is called as the last thing in the Scan function. */
  	
  	public static OnScanDelegate OnGraphsUpdated; /**< Called when any graphs are updated. Register to for example recalculate the path whenever a graph changes. */
  	
  	/** Called when \a pathID overflows 65536.
  	 * The Pathfinding.CleanupPath65K will be added to the queue, and directly after, this callback will be called.
  	 * \note This callback will be cleared every timed it is called, so if you want to register to it repeatedly, register to it directly on receiving the callback as well. 
  	 */
  	public static OnVoidDelegate On65KOverflow;
  	
  	/** Will send a callback when it is safe to update the nodes. Register to this with RegisterSafeNodeUpdate
  	 * When it is safe is defined as between the path searches.
  	 * This callback will only be sent once and is nulled directly after the callback is sent.
  	 * \warning Note that these callbacks are not thread safe when using multithreading, DO NOT call any part of the Unity API from these callbacks except for Debug.Log
  	 */
  	private static OnVoidDelegate OnSafeCallback;
  	
  	/** Will send a callback when it is safe to update the nodes. Register to this with RegisterThreadSafeNodeUpdate
  	 * When it is safe is defined as between the path searches.
  	 * This callback will only be sent once and is nulled directly after the callback is sent.
  	 * \see OnSafeCallback
  	 */
  	private static OnVoidDelegate OnThreadSafeCallback;
  	
  	/** Used to enable gizmos in editor scripts.
  	  * Used internally by the editor, do not use this in game code */
  	public OnVoidDelegate OnDrawGizmosCallback;
  	
  	[System.ObsoleteAttribute]
  	public OnVoidDelegate OnGraphsWillBeUpdated;
  	[System.ObsoleteAttribute]
  	public OnVoidDelegate OnGraphsWillBeUpdated2;
  	
  	/* @} */
  #endregion
  	
  #region MemoryStructures
  	
  	/** Stack containing all waiting graph update queries. Add to this stack by using \link UpdateGraphs \endlink
  	 * \see UpdateGraphs
  	 */
  	[System.NonSerialized]
  	public Queue<GraphUpdateObject> graphUpdateQueue;
  	
  	/** Stack used for flood-filling the graph. It is saved to minimize memory allocations. */
  	[System.NonSerialized]
  	public Stack<GraphNode> floodStack;
  	
  	ThreadControlQueue pathQueue = new ThreadControlQueue(0);
  	
  	private static Thread[] threads;
  	
  	/** Holds info about each thread.
  	 * The first item will hold information about the pathfinding coroutine when not using multithreading.
  	 */
  	private static PathThreadInfo[] threadInfos = new PathThreadInfo[0];
  	
  	/** When no multithreading is used, the IEnumerator is stored here.
  	 * When no multithreading is used, a coroutine is used instead. It is not directly called with StartCoroutine
  	 * but a separate function has just a while loop which increments the main IEnumerator.
  	 * This is done so other functions can step the thread forward at any time, without having to wait for Unity to update it.
  	 * \see CalculatePaths
  	 * \see CalculatePathsHandler
  	 */
  	private static IEnumerator threadEnumerator;
  	private static Pathfinding.Util.LockFreeStack pathReturnStack = new Pathfinding.Util.LockFreeStack();
  	
  #endregion
  	
  	/** Shows or hides graph inspectors.
  	 * Used internally by the editor */
  	public bool showGraphs = false;
  	
  	public static bool isEditor = true;
  	
  	/** The last area index which was used.
  	 * Used for the \link FloodFill(Node node) FloodFill \endlink function to start flood filling with an unused area.
  	 * \see FloodFill(Node node)
  	 */
  	public uint lastUniqueAreaIndex = 0;
  	
  #region ThreadingMembers
  	
  	private static readonly System.Object safeUpdateLock = new object();
  	
  #endregion
  	
  	/** Time the last graph update was done.
  	 * Used to group together frequent graph updates to batches */
  	private float lastGraphUpdate = -9999F;
  	
  	/** The next unused Path ID.
  	 * Incremented for every call to GetFromPathPool */
  	private ushort nextFreePathID = 1;
  	
  	/** Returns tag names.
  	 * Makes sure that the tag names array is not null and of length 32.
  	 * If it is null or not of length 32, it creates a new array and fills it with 0,1,2,3,4 etc...
  	 * \see AstarPath.FindTagNames
  	 */
  	public string[] GetTagNames () {
  		
  		if (tagNames == null || tagNames.Length	!= 32) {
  			tagNames = new string[32];
  			for (int i=0;i<tagNames.Length;i++) {
  				tagNames[i] = ""+i;
  			}
  			tagNames[0] = "Basic Ground";
  		}
  		return tagNames;
  	}
  	
  	/** Tries to find an AstarPath object and return tag names.
  	 * If an AstarPath object cannot be found, it returns an array of length 1 with an error message.
  	 * \see AstarPath.GetTagNames
  	 */
  	public static string[] FindTagNames () {
  		if (active != null) return active.GetTagNames ();
  		else {
  			AstarPath a = GameObject.FindObjectOfType (typeof (AstarPath)) as AstarPath;
  			if (a != null) { active = a; return a.GetTagNames (); }
  			else {
  				return new string[1] {"There is no AstarPath component in the scene"};
  			}
  		}
  	}
  	
  	/** Returns the next free path ID. If the next free path ID overflows 65535, a cleanup operation is queued
  	  * \see Pathfinding.CleanupPath65K */
  	public ushort GetNextPathID ()
  	{
  		if (nextFreePathID == 0) {
  			nextFreePathID++;
  			
  			//Queue a cleanup operation to zero all path IDs
  			//StartPath (new CleanupPath65K ());
  			Debug.Log ("65K cleanup");
  			
  			//ushort toBeReturned = nextFreePathID;
  			
  			if (On65KOverflow != null) {
  				OnVoidDelegate tmp = On65KOverflow;
  				On65KOverflow = null;
  				tmp ();
  			}
  			
  			//return nextFreePathID++;
  		}
  		return nextFreePathID++;
  	}
  	
  	
  	/** Calls OnDrawGizmos on graph generators and also #OnDrawGizmosCallback */
  	private void OnDrawGizmos () {
  		AstarProfiler.StartProfile ("OnDrawGizmos");
  		
  		if (active == null) {
  			active = this;
  		} else if (active != this) {
  			return;
  		}
  		
  		if (graphs == null) return;
  		
  		//If updating graphs, graph info might be corrupt right now
  		if (pathQueue != null && pathQueue.AllReceiversBlocked && workItems.Count > 0) return;
  		
  		for (int i=0;i<graphs.Length;i++) {
  			if (graphs[i] == null) continue;
  			
  			if (graphs[i].drawGizmos)
  				graphs[i].OnDrawGizmos (showNavGraphs);
  		}
  		
  		if (showUnwalkableNodes && showNavGraphs) {
  			Gizmos.color = AstarColor.UnwalkableNode;
  			
  			GraphNodeDelegateCancelable del = DrawUnwalkableNode;
  			
  			for (int i=0;i<graphs.Length;i++) {
  				if (graphs[i] != null) graphs[i].GetNodes (del);
  			}
  		}
  		
  		if (OnDrawGizmosCallback != null) {
  			OnDrawGizmosCallback ();
  		}
  		
  		AstarProfiler.EndProfile ("OnDrawGizmos");
  	}
  	
  	/** Draws a cube at the node's position if unwalkable.
  	 * Used for gizmo drawing
  	 */
  	private bool DrawUnwalkableNode (GraphNode node) {
  		if (!node.Walkable) {
  			Gizmos.DrawCube ((Vector3)node.position, Vector3.one*unwalkableNodeDebugSize);
  		}
  		return true;
  	}
  
  	/** Draws the InGame debugging (if enabled), also shows the fps if 'L' is pressed down.
  	 * \see #logPathResults PathLog
  	 */
  	private void OnGUI () {
  		
  		if (Input.GetKey ("l")) {
  			GUI.Label (new Rect (Screen.width-100,5,100,25),(1F/Time.smoothDeltaTime).ToString ("0")+" fps");
  		}
  		
  		if (logPathResults == PathLog.InGame) {
  			
  			if (inGameDebugPath != "") {
  						
  				GUI.Label (new Rect (5,5,400,600),inGameDebugPath);
  			}
  		}
  		
  		/*if (GUI.Button (new Rect (Screen.width-100,5,100,20),"Load New Level")) {
  			Application.LoadLevel (0);
  		}*/
  		
  	}
  	
  #line hidden
  	/** Logs a string while taking into account #logPathResults */
  	private static void AstarLog (string s) {
  		if (System.Object.ReferenceEquals(active,null)) {
  			Debug.Log ("No AstarPath object was found : "+s);
  			return;
  		}
  		
  		if (active.logPathResults != PathLog.None && active.logPathResults != PathLog.OnlyErrors) {
  			Debug.Log (s);
  		}
  	}
  	
  	/** Logs an error string while taking into account #logPathResults */
  	private static void AstarLogError (string s) {
  		if (active == null) {
  			Debug.Log ("No AstarPath object was found : "+s);
  			return;
  		}
  		
  		if (active.logPathResults != PathLog.None) {
  			Debug.LogError (s);
  		}
  	}
  #line default
  
  	/** Prints path results to the log. What it prints can be controled using #logPathResults.
  	 * \see #logPathResults
  	 * \see PathLog
  	 * \see Pathfinding.Path.DebugString
  	 */
  	private void LogPathResults (Path p) {
  		
  		if (logPathResults == PathLog.None || (logPathResults == PathLog.OnlyErrors && !p.error)) {
  			return;
  		}
  		
  		string debug = p.DebugString (logPathResults);
  		
  		if (logPathResults == PathLog.InGame) {
  			inGameDebugPath = debug;
  		} else {
  			Debug.Log (debug);
  		}
  	}
  	
  	
  	public struct AstarWorkItem {
  		/** Init function.
  		 * May be null if no initialization is needed.
  		 * Will be called once, right before the first call to #update.
  		 */
  		public OnVoidDelegate init;
  		
  		/** Update function, called once per frame when the work item executes.
  		 * Takes a param \a force. If that is true, the work item should try to complete the whole item in one go instead
  		 * of spreading it out over multiple frames.
  		 * \returns True when the work item is completed.
  		 */
  		public System.Func<bool, bool> update;
  		
  		public AstarWorkItem (System.Func<bool, bool> update) {
  			init = null;
  			this.update = update;
  		}
  		
  		public AstarWorkItem (OnVoidDelegate init, System.Func<bool, bool> update) {
  			this.init = init;
  			this.update = update;
  		}
  	}
  	
  	private Queue<AstarWorkItem> workItems = new Queue<AstarWorkItem>();
  	
  	/* Checks if the OnThreadSafeCallback callback needs to be (and can) be called and if so, does it.
  	 * Unpauses pathfinding threads after that.
  	 * \see CallThreadSafeCallbacks
  	 */
  	private void Update () {
  		PerformBlockingActions();
  		
  		//Process paths
  		if (threadEnumerator != null) {
  			try {
  				threadEnumerator.MoveNext ();
  				
  			} catch (System.Exception e) {
  				//This will kill pathfinding
  				threadEnumerator = null;
  				
  				// Queue termination exceptions should be ignored, they are supposed to kill the thread
  				if (!(e is ThreadControlQueue.QueueTerminationException)) {
  			
  					Debug.LogException (e);
  					Debug.LogError ("Unhandled exception during pathfinding. Terminating.");
  					pathQueue.TerminateReceivers();
  					
  					//This will throw an exception supposed to kill the thread
  					try {
  						pathQueue.PopNoBlock(false);
  					} catch {}
  				}
  			}
  		}
  		
  		//Return calculated paths
  		ReturnPaths(true);
  	}
  	
  	private void PerformBlockingActions (bool force = false, bool unblockOnComplete = true) {
  		if (pathQueue.AllReceiversBlocked) {
  			// Return all paths before starting blocking actions (these might change the graph and make returned paths invalid (at least the nodes))
  			ReturnPaths (false);
  			
  			//This must be called before since otherwise ProcessWorkItems might start pathfinding again
  			//if no work items are left to be processed resulting in thread safe callbacks never being called
  			if (OnThreadSafeCallback != null) {
  				OnVoidDelegate tmp = OnThreadSafeCallback;
  				OnThreadSafeCallback = null;
  				tmp ();
  			}
  			
  			if (ProcessWorkItems (force) == 2) {
  				//At this stage there are no more work items, restart pathfinding threads
  				workItemsQueued = false;
  				if (unblockOnComplete) {
  					pathQueue.Unblock();
  				}
  			}
  		}
  		
  	}
  	
  	private bool workItemsQueued = false;
  	private bool queuedWorkItemFloodFill = false;
  	
  	/** Call during work items to queue a flood fill.
  	 * An instant flood fill can be done via FloodFill()
  	 * but this method can be used to batch several updates into one
  	 * which can often save performance.
  	 * WorkItems which require a valid Flood Fill in their execution can call EnsureValidFloodFill directly.
  	 * If queued a flood fill will be done after all WorkItems have been executed
  	 */
  	public void QueueWorkItemFloodFill () {
  		//Not a perfect check for if it is called inside or outside a workitem, but good enough
  		if (!pathQueue.AllReceiversBlocked) {
  			throw new System.Exception ("You are calling QueueWorkItemFloodFill from outside a WorkItem. This might cause unexpected behaviour.");
  		}
  		
  		queuedWorkItemFloodFill = true;
  	}
  	
  	/** If a WorkItem needs to have a valid flood fill during execution, call this method to ensure there are no pending flood fills.
  	 */
  	public void EnsureValidFloodFill () {
  		if (queuedWorkItemFloodFill) {
  			FloodFill();
  		}
  	}
  	
  	/** Add a work item to be processed when pathfinding is paused.
  	 * 
  	 * \see ProcessWorkItems
  	 */
  	public void AddWorkItem (AstarWorkItem itm) {
  		
  		workItems.Enqueue (itm);
  		
  		//Make sure pathfinding is stopped and work items are processed
  		if (!workItemsQueued) {
  			workItemsQueued = true;
  			if (!isScanning) {
  				InterruptPathfinding ();
  			}
  		}
  
  #if UNITY_EDITOR
  		//If not playing, execute instantly
  		if (!Application.isPlaying) {
  			FlushWorkItems();
  		}
  #endif
  	}
  	
  	bool processingWorkItems = false;
  	
  	/** Process graph updating work items.
  	 * Process all queued work items, e.g graph updates and the likes.
  	 * 
  	 * \returns 
  	 * - 0 if there were no work items to be processed or if nothing can be done
  	 * 	because pathfinding is not paused.
  	 * - 1 if there are still items to be processed.
  	 * - 2 if the last work items was processed and pathfinding threads are ready to be resumed.
  	 * 
  	 * \see AddWorkItem
  	 * \see threadSafeUpdateState
  	 * \see Update
  	 */
  	private int ProcessWorkItems (bool force) {
  		if (pathQueue.AllReceiversBlocked) {
  			if (processingWorkItems) throw new System.Exception ("Processing work items recursively. Please do not wait for other work items to be completed inside work items. " +
  				"If you think this is not caused by any of your scripts, this might be a bug.");
  			
  			processingWorkItems = true;
  			while (workItems.Count > 0) {
  				AstarWorkItem itm = workItems.Peek ();
  				
  				//Call init the first time the item is seen
  				if (itm.init != null) {
  					itm.init ();
  					itm.init = null;
  				}
  				
  				bool status;
  				try {
  					status = itm.update == null ? true : itm.update (force);
  				} catch {
  					workItems.Dequeue ();
  					processingWorkItems = false;
  					throw;
  				}
  				
  				if (!status) {
  					// Still work items to process
  					processingWorkItems = false;
  					return 1;
  				}
  				else workItems.Dequeue ();
  			}
  			
  			EnsureValidFloodFill ();
  			
  			processingWorkItems = false;
  			return 2;
  		}
  		return 0;
  	}
  	
  #region GraphUpdateMethods
  	
  	/** Will apply queued graph updates as soon as possible, regardless of #limitGraphUpdates.
  	 * Calling this multiple times will not create multiple callbacks.
  	 * Makes sure DoUpdateGraphs is called as soon as possible.\n
  	 * This function is useful if you are limiting graph updates, but you want a specific graph update to be applied as soon as possible regardless of the time limit.
  	 * \see FlushGraphUpdates
  	 */
  	public void QueueGraphUpdates () {
  		if (!isRegisteredForUpdate) {
  			isRegisteredForUpdate = true;
  			AstarWorkItem itm = new AstarWorkItem();
  			itm.init = QueueGraphUpdatesInternal;
  			itm.update = ProcessGraphUpdates;
  			AddWorkItem (itm);
  		}
  	}
  	
  	/** Waits a moment with updating graphs.
  	 * If limitGraphUpdates is set, we want to keep some space between them to let pathfinding threads running and then calculate all queued calls at once
  	 */
  	private IEnumerator DelayedGraphUpdate () {
  		graphUpdateRoutineRunning = true;
  		
  		yield return new WaitForSeconds (maxGraphUpdateFreq-(Time.time-lastGraphUpdate));
  		QueueGraphUpdates ();
  		graphUpdateRoutineRunning = false;
  	}
  	
  	/** Update all graphs within \a bounds after \a t seconds.
  	 * This function will add a GraphUpdateObject to the #graphUpdateQueue.
  	 * The graphs will be updated as soon as possible.
  	 */
  	public void UpdateGraphs (Bounds bounds, float t) {
  		UpdateGraphs (new GraphUpdateObject (bounds),t);
  	}
  	
  	/** Update all graphs using the GraphUpdateObject after \a t seconds.
  	 * This can be used to, e.g make all nodes in an area unwalkable, or set them to a higher penalty.
  	*/
  	public void UpdateGraphs (GraphUpdateObject ob, float t) {
  		StartCoroutine (UpdateGraphsInteral (ob,t));
  	}
  	
  	/** Update all graphs using the GraphUpdateObject after \a t seconds */
  	private IEnumerator UpdateGraphsInteral (GraphUpdateObject ob, float t) {
  		yield return new WaitForSeconds (t);
  		UpdateGraphs (ob);
  	}
  	
  	/** Update all graphs within \a bounds.
  	 * This function will add a GraphUpdateObject to the #graphUpdateQueue.
  	 * The graphs will be updated as soon as possible.
  	 * 
  	 * This is equivalent to\n
  	 * UpdateGraphs (new GraphUpdateObject (bounds))
  	 * 
  	 * \see FlushGraphUpdates
  	 */
  	public void UpdateGraphs (Bounds bounds) {
  		UpdateGraphs (new GraphUpdateObject (bounds));
  	}
  	
  	/** Update all graphs using the GraphUpdateObject.
  	 * This can be used to, e.g make all nodes in an area unwalkable, or set them to a higher penalty.
  	 * The graphs will be updated as soon as possible (with respect to #limitGraphUpdates)
  	 * 
  	 * \see FlushGraphUpdates
  	*/
  	public void UpdateGraphs (GraphUpdateObject ob) {
  		
  		//Create a new queue if no queue exists yet
  		if (graphUpdateQueue == null) {
  			graphUpdateQueue = new Queue<GraphUpdateObject> ();
  		}
  		
  		//Put the GUO in the queue
  		graphUpdateQueue.Enqueue (ob);
  		
  		//If we should limit graph updates, start a coroutine which waits until we should update graphs
  		if (limitGraphUpdates && Time.time-lastGraphUpdate < maxGraphUpdateFreq) {
  			if (!graphUpdateRoutineRunning) {
  				StartCoroutine (DelayedGraphUpdate ());
  			}
  		} else {
  			//Otherwise, graph updates should be carried out as soon as possible
  			QueueGraphUpdates ();
  		}
  		
  	}
  	
  	/** Forces graph updates to run.
  	 * This will force all graph updates to run immidiately. Or more correctly, it will block the Unity main thread until graph updates can be performed and then issue them.
  	 * This will force the pathfinding threads to finish calculate the path they are currently calculating (if any) and then pause.
  	 * When all threads have paused, graph updates will be performed.
  	 * \warning Using this very often (many times per second) can reduce your fps due to a lot of threads waiting for one another.
  	 * But you probably wont have to worry about that.
  	 * 
  	 * \note This is almost identical to FlushThreadSafeCallbacks, but added for more descriptive name.
  	 * This function will also override any time limit delays for graph updates.
  	 * This is because graph updates are implemented using thread safe callbacks.
  	 * So calling this function will also call other thread safe callbacks (if any are waiting).
  	 * 
  	 * Will not do anything if there are no graph updates queued (not even call other callbacks).
  	 */
  	public void FlushGraphUpdates () {
  		if (IsAnyGraphUpdatesQueued) {
  			QueueGraphUpdates ();
  			FlushWorkItems ();
  		}
  	}
  	
  	public void FlushWorkItems () {
  		
  		//FlushThreadSafeCallbacks();
  		BlockUntilPathQueueBlocked();
  		//Run tasks
  		PerformBlockingActions(true);
  	}
  	
  #endregion
  	
  	private void QueueGraphUpdatesInternal () {
  		
  		isRegisteredForUpdate = false;
  		
  		bool anyRequiresFloodFill = false;
  		
  		while (graphUpdateQueue.Count > 0) {
  			GraphUpdateObject ob = graphUpdateQueue.Dequeue ();
  			
  			if (ob.requiresFloodFill) anyRequiresFloodFill = true;
  		
  			foreach (IUpdatableGraph g in astarData.GetUpdateableGraphs ()) {
  				NavGraph gr = g as NavGraph;
  				if (ob.nnConstraint == null || ob.nnConstraint.SuitableGraph (active.astarData.GetGraphIndex (gr),gr)) {
  					GUOSingle aguo = new GUOSingle ();
  					aguo.order = GraphUpdateOrder.GraphUpdate;
  					aguo.obj = ob;
  					aguo.graph = g;
  					graphUpdateQueueRegular.Enqueue (aguo);
  				}
  			}
  		}
  		
  		if (anyRequiresFloodFill) {
  			GUOSingle guo = new GUOSingle();
  			guo.order = GraphUpdateOrder.FloodFill;
  			graphUpdateQueueRegular.Enqueue (guo);
  		}
  		
  		//Nodes might have been invalidated and then the debugPathData could lead to nodes being used which have been invalidated
  		//This could in the long run lead to exceptions
  		debugPath = null;
  		
  		GraphModifier.TriggerEvent (GraphModifier.EventType.PreUpdate);
  	}
  	
  	/** Updates graphs.
  	 * Will do some graph updates, eventually signal another thread to do them.
  	 * Will only process graph updates added by QueueGraphUpdatesInternal
  	 * 
  	 * \param force If true, all graph updates will be processed before this function returns. The return value
  	 * will be True.
  	 * 
  	 * \returns True if all graph updates have been done and pathfinding (or other tasks) may resume.
  	 * False if there are still graph updates being done or waiting in the queue.
  	 * 
  	 * 
  	 */
  	private bool ProcessGraphUpdates (bool force) {
  		
  		if (force) {
  			processingGraphUpdatesAsync.WaitOne ();
  		} else {
  			if (!processingGraphUpdatesAsync.WaitOne (0)) {
  				return false;
  			}
  		}
  		
  		if (graphUpdateQueueAsync.Count != 0) throw new System.Exception ("Queue should be empty at this stage");
  		
  		while (graphUpdateQueueRegular.Count > 0) {
  			
  			GUOSingle s = graphUpdateQueueRegular.Peek ();
  			
  			GraphUpdateThreading threading = s.order == GraphUpdateOrder.FloodFill ? GraphUpdateThreading.SeparateThread : s.graph.CanUpdateAsync(s.obj);
  			
  			if (!force && (threading == GraphUpdateThreading.SeparateAndUnityInit)) {
  				if (graphUpdateQueueAsync.Count > 0) {
  					//Process async graph updates first.
  					
  					//Next call to this function will process this object so it is not dequeued now	
  					processingGraphUpdatesAsync.Reset ();
  					graphUpdateAsyncEvent.Set ();
  					
  					return false;
  				}
  				
  				s.graph.UpdateAreaInit (s.obj);
  				
  				//Move GUO to async queue to be updated by another thread
  				graphUpdateQueueRegular.Dequeue ();
  				graphUpdateQueueAsync.Enqueue (s);
  				
  				//Next call to this function will process this object so it is not dequeued now	
  				processingGraphUpdatesAsync.Reset ();
  				graphUpdateAsyncEvent.Set ();
  				
  				return false;
  			} else if (!force && (threading == GraphUpdateThreading.SeparateThread)) {
  				//Move GUO to async queue to be updated by another thread
  				graphUpdateQueueRegular.Dequeue ();
  				graphUpdateQueueAsync.Enqueue (s);
  			} else {
  				//Everything should be done in the unity thread
  				
  				if (graphUpdateQueueAsync.Count > 0) {
  					//Process async graph updates first.
  					
  					if (force) throw new System.Exception ("This should not happen");
  					
  					//Next call to this function will process this object so it is not dequeued now	
  					processingGraphUpdatesAsync.Reset ();
  					graphUpdateAsyncEvent.Set ();
  					
  					return false;
  				}
  				
  				graphUpdateQueueRegular.Dequeue ();
  				
  				if (s.order == GraphUpdateOrder.FloodFill) {
  					FloodFill ();
  				} else {
  					if (threading == GraphUpdateThreading.SeparateAndUnityInit) {
  						try {
  							s.graph.UpdateAreaInit (s.obj);
  						} catch (System.Exception e) {
  							Debug.LogError ("Error while initializing GraphUpdates\n" + e);
  						}
  					}
  					try {
  						s.graph.UpdateArea (s.obj);
  					} catch (System.Exception e) {
  						Debug.LogError ("Error while updating graphs\n"+e);
  					}
  				}
  			}
  		}
  		
  		if (graphUpdateQueueAsync.Count > 0) {
  			
  			//Next call to this function will process this object so it is not dequeued now	
  			processingGraphUpdatesAsync.Reset ();
  			graphUpdateAsyncEvent.Set ();
  			
  			return false;
  		}
  		
  		GraphModifier.TriggerEvent (GraphModifier.EventType.PostUpdate);
  		if (OnGraphsUpdated != null) OnGraphsUpdated(this);
  		
  		return true;
  	}
  	
  	/** \todo Should be signaled in OnDestroy */
  	private System.Threading.AutoResetEvent graphUpdateAsyncEvent = new System.Threading.AutoResetEvent(false);
  	private System.Threading.ManualResetEvent processingGraphUpdatesAsync = new System.Threading.ManualResetEvent(true);
  	private Queue<GUOSingle> graphUpdateQueueAsync = new Queue<GUOSingle>();
  	private Queue<GUOSingle> graphUpdateQueueRegular = new Queue<GUOSingle>();
  
  	enum GraphUpdateOrder {
  		GraphUpdate,
  		FloodFill
  	}
  	
  	struct GUOSingle {
  		public GraphUpdateOrder order;
  		public IUpdatableGraph graph;
  		public GraphUpdateObject obj;
  	}
  	
  	private void ProcessGraphUpdatesAsync (System.Object _astar) {
  		AstarPath astar = _astar as AstarPath;
  		if (System.Object.ReferenceEquals (astar, null)) {
  			Debug.LogError ("ProcessGraphUpdatesAsync started with invalid parameter _astar (was no AstarPath object)");
  			return;
  		}
  		
  		while (!astar.pathQueue.IsTerminating) {
  			graphUpdateAsyncEvent.WaitOne ();
  			
  			//Abort thread and clear queue
  			if (astar.pathQueue.IsTerminating) {
  				graphUpdateQueueAsync.Clear ();
  				processingGraphUpdatesAsync.Set ();
  				return;
  			}
  			
  			while (graphUpdateQueueAsync.Count > 0) {
  				GUOSingle aguo = graphUpdateQueueAsync.Dequeue ();
  				
  				try {
  					if (aguo.order == GraphUpdateOrder.GraphUpdate) {
  						aguo.graph.UpdateArea (aguo.obj);
  					} else if (aguo.order == GraphUpdateOrder.FloodFill) {
  						astar.FloodFill ();
  					} else {
  						throw new System.NotSupportedException ("" + aguo.order);
  					}
  				} catch (System.Exception e) {
  					Debug.LogError ("Exception while updating graphs:\n"+e);
  				}
  			}
  			
  			processingGraphUpdatesAsync.Set ();
  		}
  	}
  	
  	/** Forces thread safe callbacks to run.
  	 * This will force all thread safe callbacks to run immidiately. Or rather, it will block the Unity main thread until callbacks can be called and then issue them.
  	 * This will force the pathfinding threads to finish calculate the path they are currently calculating (if any) and then pause.
  	 * When all threads have paused, thread safe callbacks will be called (which can be e.g graph updates).
  	 * 
  	 * \warning Using this very often (many times per second) can reduce your fps due to a lot of threads waiting for one another.
  	 * But you probably wont have to worry about that
  	 * 
  	 * \note This is almost (note almost) identical to FlushGraphUpdates, but added for more appropriate name.
  	 */
  	public void FlushThreadSafeCallbacks () {
  		
  		//No callbacks? why wait?
  		if (OnThreadSafeCallback == null) {
  			return;
  		}
  		
  		BlockUntilPathQueueBlocked();
  		PerformBlockingActions();
  		
  		
  	}
  	
  	
  	/** Calculates number of threads to use.
  	 * If \a count is not Automatic, simply returns \a count casted to an int.
  	 * \returns An int specifying how many threads to use, 0 means a coroutine should be used for pathfinding instead of a separate thread.
  	 * 
  	 * If \a count is set to Automatic it will return a value based on the number of processors and memory for the current system.
  	 * If memory is <= 512MB or logical cores are <= 1, it will return 0. If memory is <= 1024 it will clamp threads to max 2.
  	 * Otherwise it will return the number of logical cores clamped to 6.
  	 */
  	public static int CalculateThreadCount (ThreadCount count) {
  		if (count == ThreadCount.AutomaticLowLoad || count == ThreadCount.AutomaticHighLoad) {
  			int logicalCores = Mathf.Max (1,SystemInfo.processorCount);
  			int memory = SystemInfo.systemMemorySize;
  			
  			if ( memory <= 0 ) {
  				Debug.LogError ("Machine reporting that is has <= 0 bytes of RAM. This is definitely not true, assuming 1 GiB");
  				memory = 1024;
  			}
  			
  			if ( logicalCores <= 1) return 0;
  			if ( memory <= 512) return 0;
  			
  			return 1;
  		} else {
  			return (int)count > 0 ? 1 : 0;
  		}
  	}
  	
  	/** Sets up all needed variables and scans the graphs.
  	 * Calls Initialize, starts the ReturnPaths coroutine and scans all graphs.
  	 * Also starts threads if using multithreading
  	 * \see #OnAwakeSettings */
  	public void Awake () {
  		//Very important to set this. Ensures the singleton pattern holds
  		active = this;
  		
  		if (FindObjectsOfType (typeof(AstarPath)).Length > 1) {
  			Debug.LogError ("You should NOT have more than one AstarPath component in the scene at any time.\n" +
  				"This can cause serious errors since the AstarPath component builds around a singleton pattern.");
  		}
  		
  		//Disable GUILayout to gain some performance, it is not used in the OnGUI call
  		useGUILayout = false;
  		
  		isEditor = Application.isEditor;
  		
  		if (OnAwakeSettings != null) {
  			OnAwakeSettings ();
  		}
  		
  		//To make sure all graph modifiers have been enabled before scan (to avoid script run order issues)
  		GraphModifier.FindAllModifiers ();
  		RelevantGraphSurface.FindAllGraphSurfaces ();
  		
  		int numThreads = CalculateThreadCount (threadCount);
  		
  		// Trying to prevent simple modding to add support for more than one thread
  		if ( numThreads > 1 ) {
  			threadCount = ThreadCount.One;
  			numThreads = 1;
  		}
  		
  		threads = new Thread[numThreads];
  		//Thread info, will contain at least one item since the coroutine "thread" is thought of as a real thread in this case
  		threadInfos = new PathThreadInfo[System.Math.Max(numThreads,1)];
  		
  		//Set up path queue with the specified number of receivers
  		pathQueue = new ThreadControlQueue(threadInfos.Length);
  		
  		for (int i=0;i<threadInfos.Length;i++) {
  			threadInfos[i] = new PathThreadInfo(i,this,new PathHandler());
  		}
  		for (int i=0;i<threads.Length;i++) {
  			threads[i] = new Thread (new ParameterizedThreadStart (CalculatePathsThreaded));
  			threads[i].Name = "Pathfinding Thread " + i;
  			threads[i].IsBackground = true;
  		}
  		
  		
  		//Start coroutine if not using multithreading
  		if (numThreads == 0) {
  			threadEnumerator = CalculatePaths (threadInfos[0]);
  		} else {
  			threadEnumerator = null;
  		}
  		
  		//Start pathfinding threads
  		for (int i=0;i<threads.Length;i++) {
  			if (logPathResults == PathLog.Heavy)
  				Debug.Log ("Starting pathfinding thread "+i);
  			threads[i].Start (threadInfos[i]);
  		}
  		
  	
  		Thread graphUpdateThread = new Thread (new ParameterizedThreadStart(ProcessGraphUpdatesAsync));
  		graphUpdateThread.IsBackground = true;
  		graphUpdateThread.Start (this);
  		
  		Initialize ();
  		
  		
  		// Flush work items, possibly added in initialize to load graph data
  		FlushWorkItems();
  		
  		if (scanOnStartup) {
  			if (!astarData.cacheStartup || astarData.data_cachedStartup == null) {
  				Scan ();
  			}
  		}
  		
  	}
  	
  	/** Does simple error checking.
  	 */
  	public void VerifyIntegrity () {
  		
  		if (active != this) {
  			throw new System.Exception ("Singleton pattern broken. Make sure you only have one AstarPath object in the scene");
  		}
  		
  		if (astarData == null) {
  			throw new System.NullReferenceException ("AstarData is null... Astar not set up correctly?");
  		}
  		
  		if (astarData.graphs == null) {
  			astarData.graphs = new NavGraph[0];
  		}
  		
  		if (pathQueue == null && !Application.isPlaying) {
  			pathQueue = new ThreadControlQueue(0);
  		}
  		if (threadInfos == null && !Application.isPlaying) {
  			threadInfos = new PathThreadInfo[0];
  		}
  		
  		//Dummy if, the getter does some error checking
  		if (IsUsingMultithreading) {
  		}
  	}
  	
  	/** Makes sure #active is set to this object and that #astarData is not null.
  	 * Also calls OnEnable for the #colorSettings and initializes astarData.userConnections if it wasn't initialized before */
  	public void SetUpReferences () {
  		active = this;
  		if (astarData == null) {
  			astarData = new AstarData ();
  		}
  		
  		if (astarData.userConnections == null) {
  			astarData.userConnections = new UserConnection[0];
  		}
  		
  		if (colorSettings == null) {
  			colorSettings = new AstarColor ();
  		}
  			
  		colorSettings.OnEnable ();
  	}
  	
  	/** Initializes various variables.
  	 * \link SetUpReferences Sets up references \endlink, 
  	 * Searches for graph types, calls Awake on #astarData and on all graphs
  	 * 
  	 * \see AstarData.FindGraphTypes 
  	 * \see SetUpReferences
  	 */
  	private void Initialize () {
  		
  		AstarProfiler.InitializeFastProfile (new string [14] {
  			"Prepare", 			//0
  			"Initialize",		//1
  			"CalculateStep",	//2
  			"Trace",			//3
  			"Open",				//4
  			"UpdateAllG",		//5
  			"Add",				//6
  			"Remove",			//7
  			"PreProcessing",	//8
  			"Callback",			//9
  			"Overhead",			//10
  			"Log",				//11
  			"ReturnPaths",		//12
  			"PostPathCallback"	//13
  		});
  		
  		SetUpReferences ();
  		
  		astarData.FindGraphTypes ();
  		
  		astarData.Awake ();
  		
  		astarData.UpdateShortcuts ();
  		
  		//Initialize all graphs by calling their Awake functions
  		for (int i=0;i<astarData.graphs.Length;i++) {			
  			if (astarData.graphs[i] != null) astarData.graphs[i].Awake ();
  		}
  	}
  	
  	/** Clears up variables and other stuff, destroys graphs.
  	 * Note that when destroying an AstarPath object, all static variables such as callbacks will be cleared.
  	 */
  	public void OnDestroy () {
  		
  		if (logPathResults == PathLog.Heavy)
  			Debug.Log ("+++ AstarPath Component Destroyed - Cleaning Up Pathfinding Data +++");
  		
  		if ( active != this ) return;
  		
  		
  		//Don't accept any more path calls to this AstarPath instance.
  		//This will cause all eventual multithreading threads to exit
  		pathQueue.TerminateReceivers();
  
  		BlockUntilPathQueueBlocked();
  		FlushWorkItems ();
  
  		if (logPathResults == PathLog.Heavy)
  			Debug.Log ("Processing Eventual Work Items");
  		
  		// Process work items until done 
  		// Nope, don't do this
  		//PerformBlockingActions (true);
  		
  		//Resume graph update thread, will cause it to terminate
  		graphUpdateAsyncEvent.Set();
  		
  		//Try to join pathfinding threads
  		if (threads != null) {
  			for (int i=0;i<threads.Length;i++) {
  #if UNITY_WEBPLAYER
  				if (!threads[i].Join(200)) {
  					Debug.LogError ("Could not terminate pathfinding thread["+i+"] in 200ms." +
  						"Not good.\nUnity webplayer does not support Thread.Abort\nHoping that it will be terminated by Unity WebPlayer");
  				}
  #else
  				if (!threads[i].Join (50)) {
  					Debug.LogError ("Could not terminate pathfinding thread["+i+"] in 50ms, trying Thread.Abort");
  					threads[i].Abort ();
  				}
  #endif
  			}
  		}
  		
  		if (logPathResults == PathLog.Heavy)
  			Debug.Log ("Returning Paths");
  		
  		
  		//Return all paths
  		ReturnPaths (false);
  		//Just in case someone happened to request a path in ReturnPath() (even though they should get canceled)
  		pathReturnStack.PopAll ();
  		
  		if (logPathResults == PathLog.Heavy)
  			Debug.Log ("Destroying Graphs");
  
  		
  		//Clean graphs up
  		astarData.OnDestroy ();
  		
  		if (logPathResults == PathLog.Heavy)
  			Debug.Log ("Cleaning up variables");
  		
  		//Clear variables up, static variables are good to clean up, otherwise the next scene might get weird data
  		floodStack = null;
  		graphUpdateQueue = null;
  		
  		//Clear all callbacks
  		OnDrawGizmosCallback	= null;
  		OnAwakeSettings			= null;
  		OnGraphPreScan			= null;
  		OnGraphPostScan			= null;
  		OnPathPreSearch			= null;
  		OnPathPostSearch		= null;
  		OnPreScan				= null;
  		OnPostScan				= null;
  		OnLatePostScan			= null;
  		On65KOverflow			= null;
  		OnGraphsUpdated			= null;
  		OnSafeCallback			= null;
  		OnThreadSafeCallback	= null;
  		
  		threads = null;
  		threadInfos = null;
  		
  		PathsCompleted = 0;
  		
  		active = null;
  		
  	}
  	
  #region ScanMethods
  	
  	/** Floodfills starting from the specified node */
  	public void FloodFill (GraphNode seed) {
  		FloodFill (seed, lastUniqueAreaIndex+1);
  		lastUniqueAreaIndex++;
  	}
  	
  	/** Floodfills starting from 'seed' using the specified area */
  	public void FloodFill (GraphNode seed, uint area) {
  		
  		if (area > GraphNode.MaxRegionCount) {
  			Debug.LogError ("Too high area index - The maximum area index is " + GraphNode.MaxRegionCount);
  			return;
  		}
  		
  		if (area < 0) {
  			Debug.LogError ("Too low area index - The minimum area index is 0");
  			return;
  		}
  					
  		if (floodStack == null) {
  			floodStack = new Stack<GraphNode> (1024);
  		}
  		
  		Stack<GraphNode> stack = floodStack;
  					
  		stack.Clear ();
  		
  		stack.Push (seed);
  		seed.Area = (uint)area;
  		
  		while (stack.Count > 0) {
  			stack.Pop ().FloodFill (stack,(uint)area);
  		}
  				
  	}
  	
  	/** Floodfills all graphs and updates areas for every node.
  	  * \see Pathfinding.Node.area */
  	public void FloodFill () {
  		queuedWorkItemFloodFill = false;
  		
  		
  
gt: 		if (astarData.graphs == null) {