internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Gui.Document document)
		{
			Document.BeginAtomicUndo ();
			var result = template.InsertTemplateContents (document);
			TextLinkEditMode tle = new TextLinkEditMode (this, 
			                                             result.InsertPosition,
			                                             result.TextLinks);
			
			if (PropertyService.Get ("OnTheFlyFormatting", false)) {
				Formatter prettyPrinter = TextFileService.GetFormatter (Document.MimeType);
				if (prettyPrinter != null && prettyPrinter.SupportsOnTheFlyFormatting) {
					int endOffset = result.InsertPosition + result.Code.Length;
					string text = prettyPrinter.FormatText (document.Project.Policies, Document.MimeType, Document.Text, result.InsertPosition, endOffset);
					string oldText = Document.GetTextAt (result.InsertPosition, result.Code.Length);
					//					Console.WriteLine (result.InsertPosition);
					//					Console.WriteLine ("old:" + oldText);
					//					Console.WriteLine ("new:" + text);
					Replace (result.InsertPosition, result.Code.Length, text);
					Caret.Offset = result.InsertPosition + TranslateOffset (oldText, text, Caret.Offset - result.InsertPosition);
					foreach (TextLink textLink in tle.Links) {
						foreach (ISegment segment in textLink.Links) {
							segment.Offset = TranslateOffset (oldText, text, segment.Offset);
						}
					}
				}
			}
			
			if (tle.ShouldStartTextLinkMode) {
				tle.OldMode = CurrentMode;
				tle.StartMode ();
				CurrentMode = tle;
			}
			Document.EndAtomicUndo ();
		}
		internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Gui.Document document)
		{
			using (var undo = Document.OpenUndoGroup ()) {
				var result = template.InsertTemplateContents (document);

				var links = result.TextLinks;

				var tle = new TextLinkEditMode (this, result.InsertPosition, links);
				tle.TextLinkMode = TextLinkMode.General;
				if (tle.ShouldStartTextLinkMode) {
					tle.OldMode = CurrentMode;
					tle.StartMode ();
					CurrentMode = tle;
				}
			}
		}
		internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Gui.Document document)
		{
			Document.BeginAtomicUndo ();
			var result = template.InsertTemplateContents (document);
			var tle = new TextLinkEditMode (this, result.InsertPosition, result.TextLinks);
			
			if (PropertyService.Get ("OnTheFlyFormatting", false)) {
				var prettyPrinter = CodeFormatterService.GetFormatter (Document.MimeType);
				if (prettyPrinter != null) {
					int endOffset = result.InsertPosition + result.Code.Length;
					string oldText = Document.GetTextAt (result.InsertPosition, result.Code.Length);
					var policies = document.Project != null ? document.Project.Policies : null;
					string text = prettyPrinter.FormatText (policies, Document.Text, result.InsertPosition, endOffset);
					
					if (text != null)
						Replace (result.InsertPosition, result.Code.Length, text);
					else
						//if formatting failed, just use the unformatted text
						text = oldText;
					
					Caret.Offset = result.InsertPosition + TranslateOffset (oldText, text, Caret.Offset - result.InsertPosition);
					foreach (TextLink textLink in tle.Links) {
						foreach (ISegment segment in textLink.Links) {
							segment.Offset = TranslateOffset (oldText, text, segment.Offset);
						}
					}
				}
			}
			
			if (tle.ShouldStartTextLinkMode) {
				tle.OldMode = CurrentMode;
				tle.StartMode ();
				CurrentMode = tle;
			}
			Document.EndAtomicUndo ();
		}
		internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Editor.TextEditor editor, MonoDevelop.Ide.Editor.DocumentContext context)
		{
			using (var undo = editor.OpenUndoGroup ()) {
				var result = template.InsertTemplateContents (editor, context);

				var links = result.TextLinks.Select (l => new Mono.TextEditor.TextLink (l.Name) {
					Links = l.Links.Select (s => new TextSegment (s.Offset, s.Length)).ToList (),
					IsEditable = l.IsEditable,
					IsIdentifier = l.IsIdentifier,
					GetStringFunc = l.GetStringFunc != null ? (Func<Func<string, string>, Mono.TextEditor.PopupWindow.IListDataProvider<string>>)(arg => new ListDataProviderWrapper (l.GetStringFunc (arg))) : null
				}).ToList ();
				var tle = new TextLinkEditMode (this, result.InsertPosition, links);
				tle.TextLinkMode = TextLinkMode.General;
				if (tle.ShouldStartTextLinkMode) {
					tle.OldMode = CurrentMode;
					tle.StartMode ();
					CurrentMode = tle;
					GLib.Timeout.Add (10, delegate {
						tle.UpdateTextLinks ();
						return false;
					}); 
				}
			}
		}
		internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Editor.TextEditor editor, MonoDevelop.Ide.Editor.DocumentContext context)
		{
			using (var undo = editor.OpenUndoGroup ()) {
				var result = template.InsertTemplateContents (editor, context);

				var links = result.TextLinks.Select (l => new Mono.TextEditor.TextLink (l.Name) {
					Links = l.Links.Select (s => new TextSegment (s.Offset, s.Length)).ToList (),
					IsEditable = l.IsEditable,
					IsIdentifier = l.IsIdentifier
				}).ToList ();
				var tle = new TextLinkEditMode (this, result.InsertPosition, links);
				tle.TextLinkMode = TextLinkMode.General;
				if (tle.ShouldStartTextLinkMode) {
					tle.OldMode = CurrentMode;
					tle.StartMode ();
					CurrentMode = tle;
				}
			}
		}
		internal void InsertTemplate (CodeTemplate template, MonoDevelop.Ide.Gui.Document document)
		{
			using (var undo = Document.OpenUndoGroup ()) {
				var result = template.InsertTemplateContents (document);

				var links = result.TextLinks;
				if (PropertyService.Get ("OnTheFlyFormatting", true)) {
					var prettyPrinter = CodeFormatterService.GetFormatter (Document.MimeType);
					if (prettyPrinter != null) {
						int endOffset = result.InsertPosition + result.Code.Length;
						//						string oldText = Document.GetTextAt (result.InsertPosition, result.Code.Length);
						//						var policies = document.Project != null ? document.Project.Policies : null;
						var oldVersion = Document.Version;
						prettyPrinter.OnTheFlyFormat (document, result.InsertPosition, endOffset);
						foreach (var textLink in links) {
							for (int i = 0; i < textLink.Links.Count; i++) {
								var segment = textLink.Links [i];
								var translatedOffset = oldVersion.MoveOffsetTo (Document.Version, result.InsertPosition + segment.Offset) - result.InsertPosition;
								textLink.Links [i] = new TextSegment (translatedOffset, segment.Length);
							}
						}
					}
				}

				var tle = new TextLinkEditMode (this, result.InsertPosition, links);
				if (tle.ShouldStartTextLinkMode) {
					tle.OldMode = CurrentMode;
					tle.StartMode ();
					CurrentMode = tle;
				}
			}
		}