public static Func<ViMotionContext, ViMotionResult> DoMotion (Action<ViMotionContext> motion)
		{
			return (ViMotionContext context) => { 
				int count = context.Count ?? 1;
				ViMotionResult result = null;
				for (int i = 0; i < count; i++)
				{
					if (context.StartingLine.HasValue) context.Data.Caret.Line = context.StartingLine.Value;
					if (context.StartingColumn.HasValue) context.Data.Caret.Column = context.StartingColumn.Value;
					int line = context.Data.Caret.Line;
					int column = context.Data.Caret.Column; 
					motion(context);
					result = new ViMotionResult(context.Data.Caret.Line, context.Data.Caret.Column);
					context.StartingLine = result.Line;
					context.StartingColumn = result.Column;
					context.Data.Caret.Line = line;
					context.Data.Caret.Column = column;
				}
				context.StartingLine = null;
				context.StartingColumn = null;
				return result;
			};
		}
		public static ViMotionResult Left (ViMotionContext context)
		{
			ViMotionResult result = new ViMotionResult(context);
			result.Column -= (context.Count ?? 1);
			if (result.Column < 1) 
				result.Column = 1;
			return result;
		}
		public static ViMotionResult Right (ViMotionContext context)
		{
			ViMotionResult result = new ViMotionResult(context);
			DocumentLine currentLine = context.Data.Document.GetLine (context.Data.Caret.Line);
			if (currentLine.EndOffsetIncludingDelimiter-1 > context.Data.Caret.Offset) {
				result.Column += (context.Count ?? 1);
				if (result.Column > currentLine.Length)
					result.Column = currentLine.Length;
				result = ViEditMode.RetreatFromLineEnd (context, result);
			}
			return result;
		}
		public static ViMotionResult WordStart (ViMotionContext context)
		{
			var result = new ViMotionResult(context);
			TextDocument doc = context.Data.Document;
			for (int i=0; i < context.Count; i++)
			{
				int offset = doc.LocationToOffset(result.Line, result.Column);
				offset = context.Data.FindCurrentWordStart (offset);
				DocumentLocation loc = doc.OffsetToLocation(offset);
				result.Line = loc.Line;
				result.Column = loc.Column;
			}
			return result;
		}
		public static ViMotionResult Up (ViMotionContext context)
		{
			var result = new ViMotionResult(context);
			var data = context.Data;
			PersistColumn = System.Math.Max(PersistColumn, result.Column);
			result.Line -= (context.Count ?? 1);
			if (result.Line < 1)
				result.Line = 1;
			ViEditMode.RetreatFromLineEnd (context, result);
			DocumentLine line = data.Document.GetLine (result.Line);
			if ((PersistColumn != result.Column) && (PersistColumn <= line.Length))
			{
				result.Column = PersistColumn;
				PersistColumn = 0;
			}
			return result;	
		}