void InitForRemoteSession (RemoteSoftDebuggerStartInfo dsi, out IPEndPoint dbgEP, out IPEndPoint conEP)
		{
			if (remoteProcessName != null)
				throw new InvalidOperationException ("Cannot initialize connection more than once");
			
			remoteProcessName = dsi.AppName;
			if (string.IsNullOrEmpty (remoteProcessName))
				remoteProcessName = "mono";
			
			RegisterUserAssemblies (dsi.UserAssemblyNames);
			
			dbgEP = new IPEndPoint (dsi.Address, dsi.DebugPort);
			conEP = dsi.RedirectOutput? new IPEndPoint (dsi.Address, dsi.OutputPort) : null;
			
			if (!String.IsNullOrEmpty (dsi.LogMessage))
				LogWriter (false, dsi.LogMessage + "\n");
		}
		/// <summary>Starts the debugger connecting to a remote IP</summary>
		protected void StartConnecting (RemoteSoftDebuggerStartInfo dsi, int maxAttempts, int timeBetweenAttempts)
		{
			if (timeBetweenAttempts < 0 || timeBetweenAttempts > 10000)
				throw new ArgumentException ("timeBetweenAttempts");
			
			IPEndPoint dbgEP, conEP;
			InitForRemoteSession (dsi, out dbgEP, out conEP);
			
			AsyncCallback callback = null;
			int attemptNumber = 0;
			callback = delegate (IAsyncResult ar) {
				try {
					ConnectionStarted (VirtualMachineManager.EndConnect (ar));
					return;
				} catch (Exception ex) {
					attemptNumber++;
					if (!ShouldRetryConnection(ex, attemptNumber) || attemptNumber == maxAttempts || Exited) {
						OnConnectionError (ex);
						return;
					}
				}
				try {
					if (timeBetweenAttempts > 0)
						System.Threading.Thread.Sleep (timeBetweenAttempts);
					
					ConnectionStarting (VirtualMachineManager.BeginConnect (dbgEP, conEP, callback), dsi);
					
				} catch (Exception ex2) {
					OnConnectionError (ex2);
				}
			};
			
			ConnectionStarting (VirtualMachineManager.BeginConnect (dbgEP, conEP, callback), dsi);
		}
		protected virtual string GetConnectingMessage (RemoteSoftDebuggerStartInfo dsi)
		{
			//ignore the Obsolete warning
			#pragma warning disable 0612
			if (dsi is RemoteDebuggerStartInfo)
				return GetListenMessage ((RemoteDebuggerStartInfo)dsi);
			#pragma warning restore 0612
			
			return DefaultListenMessage;
		}
		/// <summary>Starts the debugger listening for a connection over TCP/IP</summary>
		protected void StartListening (RemoteSoftDebuggerStartInfo dsi)
		{
			IPEndPoint dbgEP, conEP;
			InitForRemoteSession (dsi, out dbgEP, out conEP);
			
			var callback = HandleConnectionCallbackErrors (delegate (IAsyncResult ar) {
				ConnectionStarted (VirtualMachineManager.EndListen (ar));
			});
			ConnectionStarting (VirtualMachineManager.BeginListen (dbgEP, conEP, callback), dsi);
		}
		void ShowConnectingDialog (RemoteSoftDebuggerStartInfo dsi)
		{
			string message = GetConnectingMessage (dsi);
			
			Gtk.Application.Invoke (delegate {
				if (VirtualMachine != null || Exited)
					return;
				
				dialog = new Gtk.Dialog () {
					Title = "Waiting for debugger"
				};
				
				var label = new Gtk.Alignment (0.5f, 0.5f, 1f, 1f) {
					Child = new Gtk.Label (message),
					BorderWidth = 12
				};
				dialog.VBox.PackStart (label);
				label.ShowAll ();	
				
				dialog.AddButton ("Cancel", Gtk.ResponseType.Cancel);
				
				int response = MonoDevelop.Ide.MessageService.ShowCustomDialog (dialog);
				
				dialog = null;
				
				if (response != (int) Gtk.ResponseType.Ok) {
					EndSession ();
				}
			});
		}