/*******************************************************************************
 * Copyright (c) 2006, 2014 Wind River Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *     Ericsson 		  - Modified for additional features in DSF Reference implementation
 *     Nokia - create and use backend service.
 *     Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
 *     Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
 *     Mikhail Khodjaiants (Mentor Graphics) - Refactor common code in GDBControl* classes (bug 372795)
 *     Marc Khouzam (Ericsson) - Pass errorStream to startCommandProcessing() (Bug 350837)
 *     Mikhail Khodjaiants (Mentor Graphics) - Terminate should cancel the initialization sequence 
 *                                             if it is still running (bug 373845)
 *     Marc Khouzam (Ericsson) - Terminate the session if we lose the connection to the remote target (bug 422586)
 *     Marc Khouzam (Ericsson) - Allow to override the creation of the ControlDMC (Bug 389945)
 *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service.command;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
import org.eclipse.cdt.dsf.concurrent.Sequence;
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.internal.Messages;
import org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
import org.eclipse.cdt.dsf.gdb.service.command.GdbCommandTimeoutManager.ICommandTimeoutListener;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
import org.eclipse.cdt.dsf.mi.service.IMIBackend2;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.IEventProcessor;
import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext;
import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor;
import org.eclipse.cdt.dsf.mi.service.command.output.MIConsoleStreamOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MILogStreamOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.IStatusHandler;
import org.osgi.framework.BundleContext;

/**
 * GDB Debugger control implementation.  This implementation extends the 
 * base MI control implementation to provide the GDB-specific debugger 
 * features.  This includes:<br>
 * - CLI console support,<br>
 * - inferior process status tracking.<br>
 */
public class GDBControl extends AbstractMIControl implements IGDBControl {

	private static final int STATUS_CODE_COMMAND_TIMED_OUT = 20100;

    /**
     * Event indicating that the back end process has started.
     */
    private static class GDBControlInitializedDMEvent extends AbstractDMEvent<ICommandControlDMContext> 
        implements ICommandControlInitializedDMEvent
    {
        public GDBControlInitializedDMEvent(ICommandControlDMContext context) {
            super(context);
        }
    }
    
    /**
     * Event indicating that the CommandControl (back end process) has terminated.
     */
    private static class GDBControlShutdownDMEvent extends AbstractDMEvent<ICommandControlDMContext> 
        implements ICommandControlShutdownDMEvent
    {
        public GDBControlShutdownDMEvent(ICommandControlDMContext context) {
            super(context);
        }
    }

	private class TimeoutListener implements ICommandTimeoutListener {

		@Override
		public void commandTimedOut(final ICommandToken token) {
			getExecutor().execute(new DsfRunnable() {
				
				@Override
				public void run() {
					GDBControl.this.commandTimedOut(token);
				}
			});
		}		
	}

	/**
	 * An event processor that handles some GDB life cycle events.
     * Currently, it detects a lost connection with the remote.
	 */
	private class ControlEventProcessor implements IEventProcessor {

		public ControlEventProcessor() {
			addCommandListener(this);
			addEventListener(this);
		}
		
		@Override
		public void dispose() {
    		removeEventListener(this);
    		removeCommandListener(this);			
		}
		
		@Override
		public void eventReceived(Object output) {
			if (output instanceof MIOutput) {
				verifyConnectionLost((MIOutput)output);
			} else {
				assert false;
			}
		}

		@Override
	    public void commandDone(ICommandToken token, ICommandResult cmdResult) {
			if (cmdResult instanceof MIInfo) {
				verifyConnectionLost(((MIInfo)cmdResult).getMIOutput());
			} else {
				assert false;
			}
		}

		@Override
		public void commandQueued(ICommandToken token) {
		}

		@Override
		public void commandSent(ICommandToken token) {
		}

		@Override
		public void commandRemoved(ICommandToken token) {
		}
	}
	
    private ICommandControlDMContext fControlDmc;

    private IGDBBackend fMIBackend;
        
    private IEventProcessor fMIEventProcessor;
    private IEventProcessor fCLICommandProcessor;
    private IEventProcessor fControlEventProcessor;
    private AbstractCLIProcess fCLIProcess;

    private GdbCommandTimeoutManager fCommandTimeoutManager;

    private ICommandTimeoutListener fTimeoutListener = new TimeoutListener();

    /**
     * GDBControl is only used for GDB earlier that 7.0. Although -list-features
     * is available in 6.8, it does not report anything we care about, so
     * return empty list.
     */
	private final List<String> fFeatures = new ArrayList<String>();

	private Sequence fInitializationSequence;
	
	/**
	 * Indicator to distinguish whether this service is initialized.
	 * <code>fInitializationSequence</code> can not be used for this 
	 * purpose because there is a period of time when the service is already
	 * initializing but the initialization sequence has not created yet.   
	 */
	private boolean fInitialized = false;

    private boolean fTerminated;

    /**
     * @since 3.0
     */
    public GDBControl(DsfSession session, ILaunchConfiguration config, CommandFactory factory) {
    	this(session, false, config, factory);
    }

    /**
	 * @since 4.1
	 */
    protected GDBControl(DsfSession session, boolean useThreadAndFrameOptions, ILaunchConfiguration config, CommandFactory factory) {
    	super(session, useThreadAndFrameOptions, factory);
    }

    @Override
    protected BundleContext getBundleContext() {
        return GdbPlugin.getBundleContext();
    }
    
    @Override
    public void initialize(final RequestMonitor requestMonitor) {
        super.initialize( new ImmediateRequestMonitor(requestMonitor) {
            @Override
            protected void handleSuccess() {
                doInitialize(requestMonitor);
            }
        });
    }

    private void doInitialize(final RequestMonitor requestMonitor) {

        fMIBackend = getServicesTracker().getService(IGDBBackend.class);
    	
        // getId, called to create this context, uses the MIBackend service, 
        // which is why we must wait until we have MIBackend, before we can create the below context.
        fControlDmc = createComandControlContext(); 

        getExecutor().execute(getStartupSequence(requestMonitor));
    }

    @Override
    public void shutdown(final RequestMonitor requestMonitor) {
        getExecutor().execute(getShutdownSequence(new RequestMonitor(getExecutor(), requestMonitor) {

        	@Override
        	protected void handleCompleted() {
				GDBControl.super.shutdown(requestMonitor);
        	}
        }));
    }        

	@Override
    public String getId() {
        return fMIBackend.getId();
    }
    
	/**
	 * Create the commandControl context.
	 * This method can be overridden to provide a different context.
	 * @since 4.4
	 */
	protected ICommandControlDMContext createComandControlContext() {
		return new GDBControlDMContext(getSession().getId(), getId());
	}
	
	@Deprecated
    @Override
    public MIControlDMContext getControlDMContext() {
		assert fControlDmc instanceof MIControlDMContext;
		if (fControlDmc instanceof MIControlDMContext) {
			return (MIControlDMContext)fControlDmc;
		}
		return null;
    }
    
	@Override
    public ICommandControlDMContext getContext() {
        return fControlDmc;
    }
    
	@Override
    public void terminate(final RequestMonitor rm) {
        if (fTerminated) {
            rm.done();
            return;
        }
        fTerminated = true;

        // If the initialization sequence is still running mark it as cancelled,
        // to avoid reporting errors to the user, since we are terminating anyway.
        if (fInitializationSequence != null) {
        	fInitializationSequence.getRequestMonitor().cancel();
        }
        
       // To fix bug 234467:
       // Interrupt GDB in case the inferior is running.
       // That way, the inferior will also be killed when we exit GDB.
       //
		IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class);
		if (runControl != null && !runControl.isTargetAcceptingCommands()) {
           fMIBackend.interrupt();
       }
       
        // Schedule a runnable to be executed 2 seconds from now.
        // If we don't get a response to the quit command, this 
        // runnable will kill the task.
        final Future<?> forceQuitTask = getExecutor().schedule(
            new DsfRunnable() {
            	@Override
                public void run() {
                    fMIBackend.destroy();
                    rm.done();
                }
                
                @Override
                protected boolean isExecutionRequired() {
                    return false;
                }
            }, 
            getGDBExitWaitTime(), TimeUnit.SECONDS);
        
        queueCommand(
       		getCommandFactory().createMIGDBExit(getContext()),
            new DataRequestMonitor<MIInfo>(getExecutor(), rm) { 
                @Override
                public void handleCompleted() {
                    if (isSuccess()) {
                        // Cancel the time out runnable (if it hasn't run yet).
                        if (forceQuitTask.cancel(false)) {
                        	rm.done();
                        }
                    }
                    // else: the forceQuitTask has or will handle it.
                    // It is good to wait for the forceQuitTask to trigger
                    // to leave enough time for the interrupt() to complete.
                }
            }
        );
    }

	@Override
    public AbstractCLIProcess getCLIProcess() { 
        return fCLIProcess; 
    }
    
	/**
	 * @since 2.0
	 */
	@Override
	public void setTracingStream(OutputStream tracingStream) {
		setMITracingStream(tracingStream);
	}
	
	/** @since 3.0 */
	@Override
	public void setEnvironment(Properties props, boolean clear, final RequestMonitor rm) {
		int count = 0;
		CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm);

		// First clear the environment if requested.
		if (clear) {
			count++;
			queueCommand(
					getCommandFactory().createCLIUnsetEnv(getContext()),
					new DataRequestMonitor<MIInfo>(getExecutor(), countingRm));	
		}
		
		// Now set the new variables
		for (Entry<Object,Object> property : props.entrySet()) {
			count++;
			String name = (String)property.getKey();
			String value = (String)property.getValue();
			queueCommand(
					getCommandFactory().createMIGDBSetEnv(getContext(), name, value),
					new DataRequestMonitor<MIInfo>(getExecutor(), countingRm));	
		}
		countingRm.setDoneCount(count);
	}
	 
	/**
	 * @since 4.0
	 */
	@Override
	public void completeInitialization(final RequestMonitor rm) {
		// We take the attributes from the launchConfiguration
		ILaunch launch = (ILaunch)getSession().getModelAdapter(ILaunch.class);
    	Map<String, Object> attributes = null;
		try {
			attributes = launch.getLaunchConfiguration().getAttributes();
		} catch (CoreException e) {}

		// We need a RequestMonitorWithProgress, if we don't have one, we create one.
		IProgressMonitor monitor = (rm instanceof RequestMonitorWithProgress) ?				
				((RequestMonitorWithProgress)rm).getProgressMonitor() : new NullProgressMonitor();
		RequestMonitorWithProgress progressRm = new RequestMonitorWithProgress(getExecutor(), monitor) {

			@Override
			protected void handleCompleted() {
				fInitializationSequence = null;
				fInitialized = true;
				if (!isCanceled()) {
					// Only set the status if the user has not cancelled the operation already.
					rm.setStatus(getStatus());
				} else {
					rm.cancel();
				}
    			rm.done();
			}
		};

		fInitializationSequence = getCompleteInitializationSequence(attributes, progressRm);
		ImmediateExecutor.getInstance().execute(fInitializationSequence);
	}
	
	/**
	 * Return the sequence that is to be used to complete the initialization of GDB.
	 * 
	 * @param rm A RequestMonitorWithProgress that will indicate when the sequence is completed, but that
	 *           also contains an IProgressMonitor to be able to cancel the launch.  A NullProgressMonitor
	 *           can be used if cancellation is not required.
	 * 
	 * @since 4.0
	 */
	protected Sequence getCompleteInitializationSequence(Map<String, Object> attributes, RequestMonitorWithProgress rm) {
		return new FinalLaunchSequence(getSession(), attributes, rm);
	}
	
    @DsfServiceEventHandler 
    public void eventDispatched(ICommandControlShutdownDMEvent e) {
    	// Handle our "GDB Exited" event and stop processing commands.
    	stopCommandProcessing();

    	// Before GDB 7.0, we have to send the containerExited event ourselves
    	IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
        if (procService != null) {
    		IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(getContext(), MIProcesses.UNIQUE_GROUP_ID);
    		getSession().dispatchEvent(
    				new ContainerExitedDMEvent(processContainerDmc), getProperties());
        }
    }
    
    @DsfServiceEventHandler 
    public void eventDispatched(BackendStateChangedEvent e) {
        if (e.getState() == IMIBackend.State.TERMINATED && e.getBackendId().equals(fMIBackend.getId())) {
            // Handle "GDB Exited" event, just relay to following event.
            getSession().dispatchEvent(new GDBControlShutdownDMEvent(getContext()), getProperties());
        }
    }
    
    public static class InitializationShutdownStep extends Sequence.Step {
        public enum Direction { INITIALIZING, SHUTTING_DOWN }
        
        private Direction fDirection;
        public InitializationShutdownStep(Direction direction) { fDirection = direction; }
        
        @Override
        final public void execute(RequestMonitor requestMonitor) {
            if (fDirection == Direction.INITIALIZING) {
                initialize(requestMonitor);
            } else {
                shutdown(requestMonitor);
            }
        }
        
        @Override
        final public void rollBack(RequestMonitor requestMonitor) {
            if (fDirection == Direction.INITIALIZING) {
                shutdown(requestMonitor);
            } else {
                super.rollBack(requestMonitor);
            }
        }
        
        protected void initialize(RequestMonitor requestMonitor) {
            requestMonitor.done();
        }
        
        protected void shutdown(RequestMonitor requestMonitor) {
            requestMonitor.done();
        }
    }
    
    protected class CommandMonitoringStep extends InitializationShutdownStep {
        CommandMonitoringStep(Direction direction) { super(direction); }

        @Override
        protected void initialize(final RequestMonitor requestMonitor) {
        	doCommandMonitoringStep(requestMonitor);
        }

        @Override
        protected void shutdown(RequestMonitor requestMonitor) {
            undoCommandMonitoringStep(requestMonitor);
        }
    }
    
    /** @since 5.1 */
    protected void doCommandMonitoringStep(final RequestMonitor requestMonitor) {
    	InputStream errorStream = null;
    	if (fMIBackend instanceof IMIBackend2) {
    		errorStream = ((IMIBackend2)fMIBackend).getMIErrorStream();
    	}
    	startCommandProcessing(fMIBackend.getMIInputStream(), fMIBackend.getMIOutputStream(), errorStream);
    	requestMonitor.done();
    }
    
    /** @since 5.1 */
    protected void undoCommandMonitoringStep(RequestMonitor requestMonitor) {
    	stopCommandProcessing();
    	requestMonitor.done();
    }

    protected class CommandProcessorsStep extends InitializationShutdownStep {
        CommandProcessorsStep(Direction direction) { super(direction); }

        @Override
        public void initialize(final RequestMonitor requestMonitor) {
            doCommandProcessorsStep(requestMonitor);
        }

        @Override
        protected void shutdown(RequestMonitor requestMonitor) {
        	undoCommandProcessorsStep(requestMonitor);
        }
    }
    
    /** @since 5.1 */
    protected void doCommandProcessorsStep(final RequestMonitor requestMonitor) {
		try {
            fCLIProcess = new GDBBackendCLIProcess(GDBControl.this, fMIBackend);
        }
        catch(IOException e) {
            requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Failed to create CLI Process", e)); //$NON-NLS-1$
            requestMonitor.done();
            return;
        }
        
        fCLICommandProcessor = createCLIEventProcessor(GDBControl.this, getContext());
        fMIEventProcessor = createMIRunControlEventProcessor(GDBControl.this, getContext());
        fControlEventProcessor = createControlEventProcessor();

        requestMonitor.done();
	}

    /** @since 5.1 */
    protected void undoCommandProcessorsStep(RequestMonitor requestMonitor) {
		fControlEventProcessor.dispose();
    	fCLICommandProcessor.dispose();
        fMIEventProcessor.dispose();
        fCLIProcess.dispose();

        requestMonitor.done();
	}

    /**
	 * @since 4.1
	 */
    protected class CommandTimeoutStep extends InitializationShutdownStep {
		CommandTimeoutStep( Direction direction ) {
			super( direction );
		}

		@Override
		public void initialize( final RequestMonitor requestMonitor ) {
			doCommandTimeoutStep(requestMonitor);
		}

		@Override
		protected void shutdown( RequestMonitor requestMonitor ) {
			undoCommandTimeoutStep(requestMonitor);
		}
	}

    /** @since 5.1 */
    protected void doCommandTimeoutStep(final RequestMonitor requestMonitor) {
    	fCommandTimeoutManager = createCommandTimeoutManager( GDBControl.this );
    	if (fCommandTimeoutManager != null) {
    		fCommandTimeoutManager.addCommandTimeoutListener(fTimeoutListener);
    	}
    	requestMonitor.done();
    }
    
    /** @since 5.1 */
    protected void undoCommandTimeoutStep(RequestMonitor requestMonitor) {
    	if ( fCommandTimeoutManager != null ) {
    		fCommandTimeoutManager.removeCommandTimeoutListener(fTimeoutListener);
    		fCommandTimeoutManager.dispose();
    	}
    	requestMonitor.done();
    }

    protected class RegisterStep extends InitializationShutdownStep {
        RegisterStep(Direction direction) { super(direction); }
        @Override
        public void initialize(final RequestMonitor requestMonitor) {
            doRegisterStep(requestMonitor);
        }

        @Override
        protected void shutdown(RequestMonitor requestMonitor) {
            undoRegisterStep(requestMonitor);
        }
    }

    /** @since 5.1 */
    protected void doRegisterStep(final RequestMonitor requestMonitor) {
		getSession().addServiceEventListener(GDBControl.this, null);
        register(
            new String[]{ ICommandControl.class.getName(), 
                          ICommandControlService.class.getName(), 
                          IMICommandControl.class.getName(),
                          AbstractMIControl.class.getName(),
                          IGDBControl.class.getName() }, 
            new Hashtable<String,String>());
        getSession().dispatchEvent(new GDBControlInitializedDMEvent(getContext()), getProperties());
        requestMonitor.done();
	}

    /** @since 5.1 */
    protected void undoRegisterStep(RequestMonitor requestMonitor) {
    	unregister();
    	getSession().removeServiceEventListener(GDBControl.this);
    	requestMonitor.done();
    }

	/** @since 4.0 */
	@Override
	public List<String> getFeatures() {
		return fFeatures;
	}
	
	/**
	 * @since 4.0
	 */
	@Override
	public void enablePrettyPrintingForMIVariableObjects(RequestMonitor rm) {
		rm.done();
	}
	
	/**
	 * @since 4.0
	 */
	@Override
	public void setPrintPythonErrors(boolean enabled, RequestMonitor rm) {
		rm.done();
	}

	/**
	 * @since 4.1
	 */
	protected Sequence getStartupSequence(final RequestMonitor requestMonitor) {
        final Sequence.Step[] initializeSteps = new Sequence.Step[] {
                new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING),
                new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING),
                new CommandTimeoutStep(InitializationShutdownStep.Direction.INITIALIZING),
                new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING),
            };

        return new Sequence(getExecutor(), requestMonitor) {
            @Override public Step[] getSteps() { return initializeSteps; }
        };
	}

	/**
	 * @since 4.1
	 */
	protected Sequence getShutdownSequence(RequestMonitor requestMonitor) {
        final Sequence.Step[] shutdownSteps = new Sequence.Step[] {
                new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
                new CommandTimeoutStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
                new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
                new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
            };
        return new Sequence(getExecutor(), requestMonitor) {
            @Override public Step[] getSteps() { return shutdownSteps; }
        };
	}

	/**
	 * @since 4.1
	 */
	protected IEventProcessor createCLIEventProcessor(ICommandControlService connection, ICommandControlDMContext controlDmc) {
		return new CLIEventProcessor(connection, controlDmc);
	}

	/**
	 * @since 4.1
	 */
	protected IEventProcessor createMIRunControlEventProcessor(AbstractMIControl connection, ICommandControlDMContext controlDmc) {
		return new MIRunControlEventProcessor(connection, controlDmc);
	}

	/** @since 4.3 */
	protected IEventProcessor createControlEventProcessor() {
		return new ControlEventProcessor();
	}

	/**
	 * @since 4.1
	 */
	protected void setFeatures(List<String> features) {
		fFeatures.clear();
		fFeatures.addAll(features);
	}
	
	/**
	 * @since 4.1
	 */
	protected GdbCommandTimeoutManager createCommandTimeoutManager(ICommandControl commandControl) {
		GdbCommandTimeoutManager manager = new GdbCommandTimeoutManager(commandControl);
		manager.initialize();
		return manager;
	}

	/**
	 * @since 4.1
	 */
	@ConfinedToDsfExecutor("this.getExecutor()")
	protected void commandTimedOut(ICommandToken token) {
		String commandText = token.getCommand().toString();
		if (commandText.endsWith("\n")) //$NON-NLS-1$
			commandText = commandText.substring(0, commandText.length() - 1);
		final String errorMessage = String.format("Command '%s' is timed out", commandText); //$NON-NLS-1$
		commandFailed(token, STATUS_CODE_COMMAND_TIMED_OUT, errorMessage);
		
		// If the timeout occurs while the launch sequence is running 
		// the error will be reported by the launcher's error reporting mechanism.
		// We need to show the error message only when the session is initialized.
		if (isInitialized()) {
			// The session is terminated if a command is timed out.
			terminate(new RequestMonitor(getExecutor(), null) {
				
				@Override
				protected void handleErrorOrWarning() {
					GdbPlugin.getDefault().getLog().log(getStatus());
					super.handleErrorOrWarning();
				};
			} );

			IStatus status = new Status( 
					IStatus.ERROR, 
					GdbPlugin.PLUGIN_ID, 
					IGdbDebugConstants.STATUS_HANDLER_CODE, 
					String.format( Messages.GDBControl_Session_is_terminated, errorMessage ), 
					null);
			IStatusHandler statusHandler = DebugPlugin.getDefault().getStatusHandler(status);
			if (statusHandler != null) {
				try {
					statusHandler.handleStatus(status, null);
				}
				catch(CoreException e) {
					GdbPlugin.getDefault().getLog().log(e.getStatus());
				}
			}
		}
	}

	/**
	 * Parse output from GDB to determine if the connection to the remote was lost.
	 * 
	 * @param output The output received from GDB that must be parsed
	 *               to determine if the connection to the remote was lost.
	 * 
	 * @return True if the connection was lost, false otherwise.
	 * @since 4.3
	 */
	protected boolean verifyConnectionLost(MIOutput output) {
		boolean connectionLost = false;
		String reason = null;
		
		// Check if any command has a result that indicates a lost connection.
		// This can happen as a normal command result, or as an out-of-band event.
		// The out-of-band case can happen when GDB sends another response to 
		// a previous command.  This case can happen, for example, in all-stop 
		// when sending an -exec-continue and then killing gdbserver while connected
		// to a process; in that case a second result to -exec-continue will be sent
		// and will indicate the remote connection is closed.
		MIResultRecord rr = output.getMIResultRecord();
		if (rr != null) {
			String state = rr.getResultClass();
			if ("error".equals(state)) { //$NON-NLS-1$
				MIResult[] results = rr.getMIResults();
				for (MIResult result : results) {
					String var = result.getVariable();
					if (var.equals("msg")) { //$NON-NLS-1$
						MIValue value = result.getMIValue();
						if (value instanceof MIConst) {
							String str = ((MIConst)value).getCString();
							if (str != null && str.startsWith("Remote connection closed")) { //$NON-NLS-1$
								connectionLost = true;
								reason = str;
							}
						}
					}
				}
			}
		} else {
			// Only check for out-of-band records when there is no result record.
			// This is because OOBRecords that precede a result are included in the
			// result output even though they have already been processed.  To avoid
			// processing them a second time, we only handle them when not dealing
			// with a result record.
			for (MIOOBRecord oobr : output.getMIOOBRecords()) {
				if (oobr instanceof MIConsoleStreamOutput) {
					MIConsoleStreamOutput out = (MIConsoleStreamOutput) oobr;
					String str = out.getString();
					if (str != null && str.startsWith("Ending remote debugging")) { //$NON-NLS-1$
						// This happens if the user types 'disconnect' in the console
						connectionLost = true;
						reason = str;
						break;

						// Note that this will not trigger in the case where a
						// -target-disconnect is used.  This is a case that CDT handles
						// explicitly as it is an MI command; we shouldn't have to catch it here.
						// In fact, catching it here and terminating the session would break
						// the workaround for GDB 7.2 handled by GDBProcesses_7_2.needFixForGDB72Bug352998()
					}
				} else if (oobr instanceof MILogStreamOutput) {
					MILogStreamOutput out = (MILogStreamOutput) oobr;
					String str = out.getString().trim();
					if (str != null && str.startsWith("Remote connection closed")) { //$NON-NLS-1$
						// This happens if gdbserver is killed or dies
						connectionLost = true;
						reason = str;
						break;
					}
				}
			}
		}

		if (connectionLost) {
    		connectionLost(reason);
    		return true;
    	}
    	
    	return false;
	}
	
	/**
	 * Handle the loss of the connection to the remote.
	 * The default implementation terminates the debug session.
	 * 
	 * @param reason A string indicating as much as possible why the connection was lost. Can be null.
	 * @since 4.3
	 */
	protected void connectionLost(String reason) {
		terminate(new ImmediateRequestMonitor() {
			@Override
			protected void handleErrorOrWarning() {
				GdbPlugin.getDefault().getLog().log(getStatus());
				super.handleErrorOrWarning();
			};
		});
	}
	
	/**
	 * @since 4.1
	 */
	protected boolean isInitialized() {
		return fInitialized;
	}

	/**
	 * Returns the time (in seconds) the debugger will wait for "gdb-exit" to complete.
	 * 
	 * @since 4.2
	 */
	protected int getGDBExitWaitTime() {
		return 2;
	}
}
