context: 
  #region ================== Copyright (c) 2007 Pascal vd Heiden
  
  /*
   * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
   * This program is released under GNU General Public License
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   * 
   */
  
  #endregion
  
  #region ================== Namespaces
  
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Globalization;
  using System.Text;
  using CodeImp.DoomBuilder.Geometry;
  using CodeImp.DoomBuilder.Rendering;
  using SlimDX.Direct3D9;
  using System.Drawing;
  using CodeImp.DoomBuilder.IO;
  
  #endregion
  
  namespace CodeImp.DoomBuilder.Map
  {
  	public sealed class Vertex : SelectableElement
  	{
  		#region ================== Constants
  		
  		public const int BUFFERVERTICES = 1;
  		public const int RENDERPRIMITIVES = 1;
  		
  		#endregion
  
  		#region ================== Variables
  
  		// Map
  		private MapSet map;
  		
  		// List items
  		private LinkedListNode<Vertex> selecteditem;
  
  		// Position
  		private Vector2D pos;
  
  		// References
  		private LinkedList<Linedef> linedefs;
  		
  		// Cloning
  		private Vertex clone;
  		private int serializedindex;
  		
  		#endregion
  
  		#region ================== Properties
  
  		public MapSet Map { get { return map; } }
  		public ICollection<Linedef> Linedefs { get { return linedefs; } }
  		public Vector2D Position { get { return pos; } }
  		internal Vertex Clone { get { return clone; } set { clone = value; } }
  		internal int SerializedIndex { get { return serializedindex; } set { serializedindex = value; } }
  
  		#endregion
  
  		#region ================== Constructor / Disposer
  
  		// Constructor
  		internal Vertex(MapSet map, int listindex, Vector2D pos)
  		{
  			// Initialize
  			this.map = map;
  			this.linedefs = new LinkedList<Linedef>();
  			this.listindex = listindex;
  			this.pos = pos;
  			
  			if(map == General.Map.Map)
  				General.Map.UndoRedo.RecAddVertex(this);
  			
  			// We have no destructor
  			GC.SuppressFinalize(this);
  		}
  
  		// Disposer
  		public override void Dispose()
  		{
  			// Not already disposed?
  			if(!isdisposed)
  			{
  				// Already set isdisposed so that changes can be prohibited
  				isdisposed = true;
  
  				if(map.AutoRemove)
  				{
  					// Dispose the lines that are attached to this vertex
  					// because a linedef cannot exist without 2 vertices.
  					foreach(Linedef ld in linedefs) ld.Dispose();
  				}
  				else
  				{
  					// Detach from linedefs
  					foreach(Linedef ld in linedefs) ld.DetachVertexP(this);
  				}
  				
  				if(map == General.Map.Map)
  					General.Map.UndoRedo.RecRemVertex(this);
  				
  				// Remove from main list
  				map.RemoveVertex(listindex);
  
  				// Clean up
  				linedefs = null;
  				map = null;
  
  				// Dispose base
  				base.Dispose();
  			}
  		}
  
  		#endregion
  
  		#region ================== Management
  
  		// Call this before changing properties
  		protected override void BeforePropsChange()
  		{
  			if(map == General.Map.Map)
  				General.Map.UndoRedo.RecPrpVertex(this);
  		}
  
  		// This attaches a linedef and returns the listitem
  		internal LinkedListNode<Linedef> AttachLinedefP(Linedef l)
  		{
  			return linedefs.AddLast(l);
  		}
  
  		// This detaches a linedef
  		internal void DetachLinedefP(LinkedListNode<Linedef> l)
  		{
  			// Not disposing?
  			if(!isdisposed)
  			{
  				// Remove linedef
  				linedefs.Remove(l);
  
  				// No more linedefs left?
  				if((linedefs.Count == 0) && map.AutoRemove)
  				{
  					// This vertex is now useless, dispose it
  					this.Dispose();
  				}
  			}
  		}
  
          // Serialize / deserialize
          // ano - using new keyword to shadow (and get rid of old DB2 warning)
          internal new void ReadWrite(IReadWriteStream s)
  		{
  			if(!s.IsWriting) BeforePropsChange();
  			
  			base.ReadWrite(s);
  			
  			s.rwVector2D(ref pos);
  			
  			if(s.IsWriting)
  			{
  				// Let all lines know they need an update
  				foreach(Linedef l in linedefs) l.NeedUpdate();
  			}
  		}
  
  		// Selected
  		protected override void DoSelect()
  		{
  			base.DoSelect();
  			selecteditem = map.SelectedVertices.AddLast(this);
  		}
  
  		// Deselect
  		protected override void DoUnselect()
  		{
  			base.DoUnselect();
  			if(selecteditem.List != null) selecteditem.List.Remove(selecteditem);
  			selecteditem = null;
  		}
  
  		#endregion
  		
  		#region ================== Methods
  
  		// This copies all properties to another thing
  		public void CopyPropertiesTo(Vertex v)
  		{
  			v.BeforePropsChange();
  			
  			// Copy properties
  			v.pos = pos;
  			base.CopyPropertiesTo(v);
  		}
  		
  		// This returns the distance from given coordinates
  		public float DistanceToSq(Vector2D p)
  		{
  			return (p.x - pos.x) * (p.x - pos.x) + (p.y - pos.y) * (p.y - pos.y);
  		}
  		
  		// This returns the distance from given coordinates
  		public float DistanceTo(Vector2D p)
  		{
  
gt: 			return Vector2D.Distance(p, pos);