/// <summary>Require the given image on any atlas. Note that this may reject the requirement if the image is too big and isn't worthwhile on an atlas.</summary>
		public AtlasLocation RequireImage(AtlasEntity image){
			
			int entityID=image.GetAtlasID();
			
			AtlasLocation result;
			if(ActiveImages.TryGetValue(entityID,out result)){
				// Most calls fall through here.
				return result;
			}
			
			int width;
			int height;
			
			image.GetDimensionsOnAtlas(out width,out height);
			
			if(width>InitialSize || height>InitialSize){
				// Won't fit or is unsuitable for atlasing anyway.
				return null;
			}
			
			if(Last==null){
				Create();
			}else{
				
				// Fast check - was this texture recently removed from any atlas?
				// We might have the chance of restoring it.
				// Their added at the back of the empty queue, so naturally, start at the end of the empty set
				// and go back until we hit one with a null texture.
				
				TextureAtlas currentAtlas=Last;
				
				while(currentAtlas!=null){
					
					AtlasLocation currentE=currentAtlas.LastEmpty;
					
					while(currentE!=null){
						
						if(currentE.Image==null){
							// Nope! Shame.
							break;
						}else if(currentE.AtlasID==entityID){
							// Ace! Time to bring it back from the dead.
							currentE.Select(image,width,height,Spacing);
							ActiveImages[entityID]=currentE;
							
							return currentE;
						}
						
						currentE=currentE.EmptyBefore;
					}
					
					currentAtlas=currentAtlas.Previous;
				}
				
			}
			
			// Push to top of stack:
			result=Last.Add(image,entityID,width,height);
			
			if(result!=null){
				return result;
			}
			
			// Non-fitter - try fitting in lower stack frames:
			
			TextureAtlas current=Last.Previous;
			
			while(current!=null){
				
				result=current.Add(image,entityID,width,height);
				
				if(result!=null){
					return result;
				}
				
				current=current.Previous;
			}
			
			// Still not fitting! Create a new stack frame:
			Create();
			
			return Last.Add(image,entityID,width,height);
			
		}
		/// <summary>This texture has selected this location to fit into. This adds it to the atlas.</summary>
		/// <param name="texture">The texture that wants to go here.</param>
		/// <param name="width">The width of the texture in pixels.</param>
		/// <param name="height">The height of the texture in pixels.</param>
		public void Select(AtlasEntity image,int width,int height,int spacing){
			// The given texture wants to go in this location.
			// Width and height are given for dynamic textures - textures who's pixels are actually written straight to the atlas.
			Empty=false;
			
			int spacedWidth=width+spacing;
			int spacedHeight=height+spacing;
			
			// Remove from empty queue:
			if(EmptyBefore==null){
				Atlas.FirstEmpty=EmptyAfter;
			}else{
				EmptyBefore.EmptyAfter=EmptyAfter;
			}
			
			if(EmptyAfter==null){
				Atlas.LastEmpty=EmptyBefore;
			}else{
				EmptyAfter.EmptyBefore=EmptyBefore;
			}
			
			int entityID=image.GetAtlasID();
			
			if(AtlasID==entityID){
				// This is a restore - we don't need to do anything else.
				return;
			}
			
			Image=image;
			AtlasID=entityID;
			// If it's not a perfect fit, generate new atlas locations to the right and above of this one.
			
			if(Atlas.Mode==AtlasingMode.SmallestSpace){
			
				if(Width>spacedWidth){
					// The textures a little thin.
					
					// Generate a new area to the right of this one (NB: 0,0 is bottom left)
					AtlasLocation newRight=new AtlasLocation(Atlas,X+spacedWidth,Y,Width-spacedWidth,height);
					// Immediately mark this as empty:
					newRight.AddToEmptySet();
				}
				
				if(Height>spacedHeight){
					// The textures a little short.
					
					// Generate a new area above this one (NB: 0,0 is bottom left)
					AtlasLocation newTop=new AtlasLocation(Atlas,X,Y+spacedHeight,Width,Height-spacedHeight);
					// Immediately mark this as empty:
					newTop.AddToEmptySet();
				}
				
			}else{
				
				int maxX=X+spacedWidth;
				
				if(Atlas.ColumnProgress < maxX){
					
					Atlas.ColumnProgress=maxX;
					
				}
				
				if(Height>spacedHeight){
					// The textures a little short.
					
					// Generate a new area above this one (NB: 0,0 is bottom left)
					AtlasLocation newTop=new AtlasLocation(Atlas,X,Y+spacedHeight,Width,Height-spacedHeight);
					// Immediately mark this as empty:
					newTop.AddToEmptySet();
				}
				
			}
			
			// Set the new size of this location for UV baking:
			Width=width;
			Height=height;
			Spacing=spacing;
			
			// Update the UV's:
			BakeUV();
			
			// Make sure the area is up to date:
			Area=spacedWidth*spacedHeight;
			
			// Write it in:
			Flush();
		}
		/// <summary>Removes a texture from the atlas.</summary>
		/// <param name="texture">The texture to remove.</param>
		public void Remove(AtlasEntity texture){
			if(texture==null){
				return;
			}
			
			AtlasLocation location=Get(texture.GetAtlasID());
			
			if(location==null){
				return;
			}
			
			// Make the location available:
			location.Deselect();
		}