/*******************************************************************************
 *  Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 *  This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License 2.0
 *  which accompanies this distribution, and is available at
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Paul Pazderski  - Bug 545769: fixed rare UTF-8 character corruption bug
 *     Paul Pazderski  - Bug 552015: console finished signaled to late if input is connected to file
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.console;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
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.Path;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IFlushableStreamMonitor;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.debug.ui.console.IConsoleColorProvider;
import org.eclipse.debug.ui.console.IConsoleHyperlink;
import org.eclipse.debug.ui.console.IConsoleLineTracker;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleInputStream;
import org.eclipse.ui.console.IOConsoleOutputStream;
import org.eclipse.ui.console.IPatternMatchListener;
import org.eclipse.ui.console.PatternMatchEvent;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.progress.UIJob;

import com.ibm.icu.text.MessageFormat;


/**
 * A console for a system process with standard I/O streams.
 *
 * @since 3.0
 */
@SuppressWarnings("deprecation")
public class ProcessConsole extends IOConsole implements IConsole, IDebugEventSetListener, IPropertyChangeListener {
	private IProcess fProcess = null;

	private List<StreamListener> fStreamListeners = new ArrayList<>();

	private IConsoleColorProvider fColorProvider;

	/**
	 * The input stream which can supply user input in console to the system process
	 * stdin.
	 */
	private IOConsoleInputStream fUserInput;
	/**
	 * The stream connected to the system processe's stdin. May be the
	 * <i>fUserInput</i> stream to supply user input or a FileInputStream to supply
	 * input from a file.
	 */
	private volatile InputStream fInput;

	private FileOutputStream fFileOutputStream;

	private boolean fAllocateConsole = true;
	private String fStdInFile = null;

	private volatile boolean fStreamsClosed = false;

	/**
	 * Create process console with default encoding.
	 *
	 * @param process	   the process to associate with this console
	 * @param colorProvider the colour provider for this console
	 */
	public ProcessConsole(IProcess process, IConsoleColorProvider colorProvider) {
		this(process, colorProvider, null);
	}

	/**
	 * Create process console.
	 *
	 * @param process the process to associate with this console
	 * @param colorProvider the colour provider for this console
	 * @param encoding the desired encoding for this console
	 */
	public ProcessConsole(IProcess process, IConsoleColorProvider colorProvider, String encoding) {
		super(IInternalDebugCoreConstants.EMPTY_STRING, IDebugUIConstants.ID_PROCESS_CONSOLE_TYPE, null, encoding, true);
		fProcess = process;
		fUserInput = getInputStream();

		ILaunchConfiguration configuration = process.getLaunch().getLaunchConfiguration();
		String file = null;
		boolean append = false;
		if (configuration != null) {
			try {
				file = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String) null);
				fStdInFile = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_STDIN_FILE, (String) null);
				if (file != null || fStdInFile != null) {
					IStringVariableManager stringVariableManager = VariablesPlugin.getDefault().getStringVariableManager();
					if (file != null) {
						file = stringVariableManager.performStringSubstitution(file);
						append = configuration.getAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, false);
					}

					if (fStdInFile != null) {
						fStdInFile = stringVariableManager.performStringSubstitution(fStdInFile);
					}
				}
			} catch (CoreException e) {
			}
		}

		if (file != null && configuration != null) {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IWorkspaceRoot root = workspace.getRoot();
			Path path = new Path(file);
			IFile ifile = root.getFileForLocation(path);
			String message = null;

			try {
				String fileLoc = null;
				if (ifile != null) {
					if (append && ifile.exists()) {
						ifile.appendContents(new ByteArrayInputStream(new byte[0]), true, true, new NullProgressMonitor());
					} else {
						if (ifile.exists()) {
							ifile.delete(true, new NullProgressMonitor());
						}
						ifile.create(new ByteArrayInputStream(new byte[0]), true, new NullProgressMonitor());
					}
				}

				File outputFile = new File(file);
				fFileOutputStream = new FileOutputStream(outputFile, append);
				fileLoc = outputFile.getAbsolutePath();

				message = MessageFormat.format(ConsoleMessages.ProcessConsole_1, new Object[] { fileLoc });
				addPatternMatchListener(new ConsoleLogFilePatternMatcher(fileLoc));
			} catch (FileNotFoundException e) {
				message = MessageFormat.format(ConsoleMessages.ProcessConsole_2, new Object[] { file });
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
			if (message != null) {
				try (IOConsoleOutputStream stream = newOutputStream()) {
					stream.write(message);
				} catch (IOException e) {
					DebugUIPlugin.log(e);
				}
			}
			try {
				fAllocateConsole = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
			} catch (CoreException e) {
			}
		}
		if (fStdInFile != null && configuration != null) {
			String message = null;
			try {
				fInput = new FileInputStream(new File(fStdInFile));
				if (fInput != null) {
					setInputStream(fInput);
				}

			} catch (FileNotFoundException e) {
				message = MessageFormat.format(ConsoleMessages.ProcessConsole_3, new Object[] { fStdInFile });
			}
			if (message != null) {
				try (IOConsoleOutputStream stream = newOutputStream()) {
					stream.write(message);
				} catch (IOException e) {
					DebugUIPlugin.log(e);
				}
			}
		}
		fColorProvider = colorProvider;
		if (fInput == null) {
			fInput = getInputStream();
		}


		colorProvider.connect(fProcess, this);

		setName(computeName());

		Color color = fColorProvider.getColor(IDebugUIConstants.ID_STANDARD_INPUT_STREAM);
		if (fInput instanceof IOConsoleInputStream) {
			((IOConsoleInputStream)fInput).setColor(color);
		}

		IConsoleLineTracker[] lineTrackers = DebugUIPlugin.getDefault().getProcessConsoleManager().getLineTrackers(process);
		if (lineTrackers.length > 0) {
			addPatternMatchListener(new ConsoleLineNotifier());
		}
	}

	/**
	 * Computes and returns the image descriptor for this console.
	 *
	 * @return an image descriptor for this console or <code>null</code>
	 */
	protected ImageDescriptor computeImageDescriptor() {
		ILaunchConfiguration configuration = getProcess().getLaunch().getLaunchConfiguration();
		if (configuration != null) {
			ILaunchConfigurationType type;
			try {
				type = configuration.getType();
				return DebugPluginImages.getImageDescriptor(type.getIdentifier());
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		}
		return null;
	}

	/**
	 * Computes and returns the current name of this console.
	 *
	 * @return a name for this console
	 */
	protected String computeName() {
		String label = null;
		IProcess process = getProcess();
		ILaunchConfiguration config = process.getLaunch().getLaunchConfiguration();

		label = process.getAttribute(IProcess.ATTR_PROCESS_LABEL);
		if (label == null) {
			if (config == null) {
				label = process.getLabel();
			} else {
				// check if PRIVATE config
				if (DebugUITools.isPrivate(config)) {
					label = process.getLabel();
				} else {
					String type = null;
					try {
						type = config.getType().getName();
					} catch (CoreException e) {
					}
					StringBuilder buffer = new StringBuilder();
					buffer.append(config.getName());
					if (type != null) {
						buffer.append(" ["); //$NON-NLS-1$
						buffer.append(type);
						buffer.append("] "); //$NON-NLS-1$
					}
					buffer.append(process.getLabel());
					label = buffer.toString();
				}
			}
		}

		if (process.isTerminated()) {
			return MessageFormat.format(ConsoleMessages.ProcessConsole_0, new Object[] { label });
		}
		return label;
	}

	/**
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		String property = evt.getProperty();
		IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
		if (property.equals(IDebugPreferenceConstants.CONSOLE_WRAP) || property.equals(IDebugPreferenceConstants.CONSOLE_WIDTH)) {
			boolean fixedWidth = store.getBoolean(IDebugPreferenceConstants.CONSOLE_WRAP);
			if (fixedWidth) {
				int width = store.getInt(IDebugPreferenceConstants.CONSOLE_WIDTH);
				setConsoleWidth(width);
			} else {
				setConsoleWidth(-1);
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT) || property.equals(IDebugPreferenceConstants.CONSOLE_HIGH_WATER_MARK) || property.equals(IDebugPreferenceConstants.CONSOLE_LOW_WATER_MARK)) {
			boolean limitBufferSize = store.getBoolean(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT);
			if (limitBufferSize) {
				int highWater = store.getInt(IDebugPreferenceConstants.CONSOLE_HIGH_WATER_MARK);
				int lowWater = store.getInt(IDebugPreferenceConstants.CONSOLE_LOW_WATER_MARK);
				if (highWater > lowWater) {
					setWaterMarks(lowWater, highWater);
				}
			} else {
				setWaterMarks(-1, -1);
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH)) {
			int tabWidth = store.getInt(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH);
			setTabWidth(tabWidth);
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT)) {
			boolean activateOnOut = store.getBoolean(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT);
			@SuppressWarnings("resource")
			IOConsoleOutputStream stream = getStream(IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM);
			if (stream != null) {
				stream.setActivateOnWrite(activateOnOut);
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR)) {
			boolean activateOnErr = store.getBoolean(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR);
			@SuppressWarnings("resource")
			IOConsoleOutputStream stream = getStream(IDebugUIConstants.ID_STANDARD_ERROR_STREAM);
			if (stream != null) {
				stream.setActivateOnWrite(activateOnErr);
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_SYS_OUT_COLOR)) {
			@SuppressWarnings("resource")
			IOConsoleOutputStream stream = getStream(IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM);
			if (stream != null) {
				stream.setColor(fColorProvider.getColor(IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM));
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_SYS_ERR_COLOR)) {
			@SuppressWarnings("resource")
			IOConsoleOutputStream stream = getStream(IDebugUIConstants.ID_STANDARD_ERROR_STREAM);
			if (stream != null) {
				stream.setColor(fColorProvider.getColor(IDebugUIConstants.ID_STANDARD_ERROR_STREAM));
			}
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_SYS_IN_COLOR)) {
			if (fInput != null && fInput instanceof IOConsoleInputStream) {
				((IOConsoleInputStream) fInput).setColor(fColorProvider.getColor(IDebugUIConstants.ID_STANDARD_INPUT_STREAM));
			}
		} else if (property.equals(IDebugUIConstants.PREF_CONSOLE_FONT)) {
			setFont(JFaceResources.getFont(IDebugUIConstants.PREF_CONSOLE_FONT));
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_BAKGROUND_COLOR)) {
			setBackground(DebugUIPlugin.getPreferenceColor(IDebugPreferenceConstants.CONSOLE_BAKGROUND_COLOR));
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_INTERPRET_CONTROL_CHARACTERS)) {
			setHandleControlCharacters(store.getBoolean(IDebugPreferenceConstants.CONSOLE_INTERPRET_CONTROL_CHARACTERS));
		} else if (property.equals(IDebugPreferenceConstants.CONSOLE_INTERPRET_CR_AS_CONTROL_CHARACTER)) {
			setCarriageReturnAsControlCharacter(store.getBoolean(IDebugPreferenceConstants.CONSOLE_INTERPRET_CR_AS_CONTROL_CHARACTER));
		}
	}

	@Override
	public IOConsoleOutputStream getStream(String streamIdentifier) {
		if (streamIdentifier == null) {
			return null;
		}
		for (StreamListener listener : fStreamListeners) {
			if (streamIdentifier.equals(listener.fStreamId)) {
				return listener.fStream;
			}
		}
		return null;
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#getProcess()
	 */
	@Override
	public IProcess getProcess() {
		return fProcess;
	}

	/**
	 * @see org.eclipse.ui.console.IOConsole#dispose()
	 */
	@Override
	protected void dispose() {
		super.dispose();
		fColorProvider.disconnect();
		DebugPlugin.getDefault().removeDebugEventListener(this);
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		JFaceResources.getFontRegistry().removeListener(this);
		closeStreams();
		disposeStreams();
	}

	/**
	 * cleanup method to close all of the open stream to this console
	 */
	private synchronized void closeStreams() {
		if (fStreamsClosed) {
			return;
		}
		for (StreamListener listener : fStreamListeners) {
			listener.closeStream();
		}
		if (fFileOutputStream != null) {
			synchronized (fFileOutputStream) {
				try {
					fFileOutputStream.flush();
					fFileOutputStream.close();
				} catch (IOException e) {
				}
			}
		}
		try {
			fInput.close();
		} catch (IOException e) {
		}
		if (fInput != fUserInput) {
			try {
				fUserInput.close();
			} catch (IOException e) {
			}
		}
		fStreamsClosed = true;
	}

	/**
	 * disposes the listeners for each of the stream associated with this
	 * console
	 */
	private synchronized void disposeStreams() {
		for (StreamListener listener : fStreamListeners) {
			listener.dispose();
		}
		fFileOutputStream = null;
		fInput = null;
		fUserInput = null;
	}

	/**
	 * @see org.eclipse.ui.console.AbstractConsole#init()
	 */
	@Override
	protected void init() {
		super.init();
		DebugPlugin.getDefault().addDebugEventListener(this);
		if (fProcess.isTerminated()) {
			closeStreams();
			resetName();
			DebugPlugin.getDefault().removeDebugEventListener(this);
		}
		IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
		store.addPropertyChangeListener(this);
		JFaceResources.getFontRegistry().addListener(this);
		if (store.getBoolean(IDebugPreferenceConstants.CONSOLE_WRAP)) {
			setConsoleWidth(store.getInt(IDebugPreferenceConstants.CONSOLE_WIDTH));
		}
		setTabWidth(store.getInt(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH));

		if (store.getBoolean(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT)) {
			int highWater = store.getInt(IDebugPreferenceConstants.CONSOLE_HIGH_WATER_MARK);
			int lowWater = store.getInt(IDebugPreferenceConstants.CONSOLE_LOW_WATER_MARK);
			setWaterMarks(lowWater, highWater);
		}

		setHandleControlCharacters(store.getBoolean(IDebugPreferenceConstants.CONSOLE_INTERPRET_CONTROL_CHARACTERS));
		setCarriageReturnAsControlCharacter(store.getBoolean(IDebugPreferenceConstants.CONSOLE_INTERPRET_CR_AS_CONTROL_CHARACTER));

		DebugUIPlugin.getStandardDisplay().asyncExec(() -> {
			setFont(JFaceResources.getFont(IDebugUIConstants.PREF_CONSOLE_FONT));
			setBackground(DebugUIPlugin.getPreferenceColor(IDebugPreferenceConstants.CONSOLE_BAKGROUND_COLOR));
		});
	}

	/**
	 * Notify listeners when name changes.
	 *
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getSource().equals(getProcess())) {

				if (event.getKind() == DebugEvent.TERMINATE) {
					closeStreams();
					DebugPlugin.getDefault().removeDebugEventListener(this);
				}

				resetName();
			}
		}
	}

	/**
	 * resets the name of this console to the original computed name
	 */
	private synchronized void resetName() {
		final String newName = computeName();
		String name = getName();
		if (!name.equals(newName)) {
			UIJob job = new UIJob("Update console title") { //$NON-NLS-1$
				@Override
				public IStatus runInUIThread(IProgressMonitor monitor) {
					 ProcessConsole.this.setName(newName);
					 warnOfContentChange();
					 return Status.OK_STATUS;
				}
			};
			job.setSystem(true);
			job.schedule();
		}
	}

	/**
	 * send notification of a change of content in this console
	 */
	private void warnOfContentChange() {
		ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(DebugUITools.getConsole(fProcess));
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#connect(org.eclipse.debug.core.model.IStreamsProxy)
	 */
	@Override
	public void connect(IStreamsProxy streamsProxy) {
		IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
		IStreamMonitor streamMonitor = streamsProxy.getErrorStreamMonitor();
		if (streamMonitor != null) {
			connect(streamMonitor, IDebugUIConstants.ID_STANDARD_ERROR_STREAM,
					store.getBoolean(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR));
		}
		streamMonitor = streamsProxy.getOutputStreamMonitor();
		if (streamMonitor != null) {
			connect(streamMonitor, IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM,
					store.getBoolean(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT));
		}
		InputReadJob readJob = new InputReadJob(streamsProxy);
		readJob.setSystem(true);
		readJob.schedule();
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#connect(org.eclipse.debug.core.model.IStreamMonitor, java.lang.String)
	 */
	@Override
	public void connect(IStreamMonitor streamMonitor, String streamIdentifier) {
		connect(streamMonitor, streamIdentifier, false);
	}

	/**
	 * Connects the given stream monitor to a new output stream with the given identifier.
	 *
	 * @param streamMonitor stream monitor
	 * @param streamIdentifier stream identifier
	 * @param activateOnWrite whether the stream should displayed when written to
	 */
	@SuppressWarnings("resource")
	private void connect(IStreamMonitor streamMonitor, String streamIdentifier, boolean activateOnWrite) {
		IOConsoleOutputStream stream = null;
		if (fAllocateConsole) {

			stream = newOutputStream();
			Color color = fColorProvider.getColor(streamIdentifier);
			stream.setColor(color);
			stream.setActivateOnWrite(activateOnWrite);
		}
		synchronized (streamMonitor) {
			StreamListener listener = new StreamListener(streamIdentifier, streamMonitor, stream);
			fStreamListeners.add(listener);
		}
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#addLink(org.eclipse.debug.ui.console.IConsoleHyperlink, int, int)
	 */
	@Override
	public void addLink(IConsoleHyperlink link, int offset, int length) {
		try {
			addHyperlink(link, offset, length);
		} catch (BadLocationException e) {
			DebugUIPlugin.log(e);
		}
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#addLink(org.eclipse.ui.console.IHyperlink, int, int)
	 */
	@Override
	public void addLink(IHyperlink link, int offset, int length) {
		try {
			addHyperlink(link, offset, length);
		} catch (BadLocationException e) {
			DebugUIPlugin.log(e);
		}
	}

	/**
	 * @see org.eclipse.debug.ui.console.IConsole#getRegion(org.eclipse.debug.ui.console.IConsoleHyperlink)
	 */
	@Override
	public IRegion getRegion(IConsoleHyperlink link) {
		return super.getRegion(link);
	}

	/**
	 * This class listens to a specified IO stream
	 */
	private class StreamListener implements IStreamListener {

		private IOConsoleOutputStream fStream;

		private IStreamMonitor fStreamMonitor;

		private String fStreamId;

		private boolean fFlushed = false;

		private boolean fListenerRemoved = false;

		public StreamListener(String streamIdentifier, IStreamMonitor monitor, IOConsoleOutputStream stream) {
			this.fStreamId = streamIdentifier;
			this.fStreamMonitor = monitor;
			this.fStream = stream;
			fStreamMonitor.addListener(this);
			//fix to bug 121454. Ensure that output to fast processes is processed.
			streamAppended(null, monitor);
		}

		@Override
		public void streamAppended(String text, IStreamMonitor monitor) {
			String encoding = getEncoding();
			if (fFlushed) {
				try {
					if (fStream != null) {
						if (encoding == null) {
							fStream.write(text);
						} else {
							fStream.write(text.getBytes(encoding));
						}
					}
					if (fFileOutputStream != null) {
						synchronized (fFileOutputStream) {
							if (encoding == null) {
								fFileOutputStream.write(text.getBytes());
							} else {
								fFileOutputStream.write(text.getBytes(encoding));
							}
						}
					}
				} catch (IOException e) {
					DebugUIPlugin.log(e);
				}
			} else {
				String contents = null;
				synchronized (fStreamMonitor) {
					fFlushed = true;
					contents = fStreamMonitor.getContents();
					if (fStreamMonitor instanceof IFlushableStreamMonitor) {
						IFlushableStreamMonitor m = (IFlushableStreamMonitor) fStreamMonitor;
						m.flushContents();
						m.setBuffered(false);
					}
				}
				try {
					if (contents != null && contents.length() > 0) {
						if (fStream != null) {
							fStream.write(contents);
						}
						if (fFileOutputStream != null) {
							synchronized (fFileOutputStream) {
								fFileOutputStream.write(contents.getBytes());
							}
						}
					}
				} catch (IOException e) {
					DebugUIPlugin.log(e);
				}
			}
		}

		public void closeStream() {
			if (fStreamMonitor == null) {
				return;
			}
			synchronized (fStreamMonitor) {
				fStreamMonitor.removeListener(this);
				if (!fFlushed) {
					String contents = fStreamMonitor.getContents();
					streamAppended(contents, fStreamMonitor);
				}
				fListenerRemoved = true;
				try {
					if (fStream != null) {
						fStream.close();
					}
				} catch (IOException e) {
				}
			}
		}

		public void dispose() {
			if (!fListenerRemoved) {
				closeStream();
			}
			fStream = null;
			fStreamMonitor = null;
			fStreamId = null;
		}
	}

	private class InputReadJob extends Job {

		private IStreamsProxy streamsProxy;

		/**
		 * The {@link InputStream} this job is currently reading from or maybe blocking
		 * on. May be <code>null</code>.
		 */
		private InputStream readingStream;

		InputReadJob(IStreamsProxy streamsProxy) {
			super("Process Console Input Job"); //$NON-NLS-1$
			this.streamsProxy = streamsProxy;
		}

		@Override
		protected void canceling() {
			super.canceling();
			if (readingStream != null) {
				// Close stream or job may not be able to cancel.
				// This is primary for IOConsoleInputStream because there is no guarantee an
				// arbitrary InputStream will release a blocked read() on close.
				try {
					readingStream.close();
				} catch (IOException e) {
					DebugUIPlugin.log(e);
				}
			}
		}

		@Override
		public boolean belongsTo(Object family) {
			return ProcessConsole.class == family;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			if (fInput == null || fStreamsClosed) {
				return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
			}
			Charset encoding = getCharset();
			readingStream = fInput;
			InputStreamReader streamReader = (encoding == null ? new InputStreamReader(readingStream)
					: new InputStreamReader(readingStream, encoding));
			try {
				char[] cbuf = new char[1024];
				int charRead = 0;
				while (charRead >= 0 && !monitor.isCanceled()) {
					if (fInput == null || fStreamsClosed) {
						break;
					}
					if (fInput != readingStream) {
						readingStream = fInput;
						streamReader = (encoding == null ? new InputStreamReader(readingStream)
								: new InputStreamReader(readingStream, encoding));
					}

					charRead = streamReader.read(cbuf);
					if (charRead > 0) {
						String s = new String(cbuf, 0, charRead);
						streamsProxy.write(s);
					}
				}
			} catch (IOException e) {
				DebugUIPlugin.log(e);
			}
			readingStream = null;
			return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
		}
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		if (super.getImageDescriptor() == null) {
			setImageDescriptor(computeImageDescriptor());
		}
		return super.getImageDescriptor();
	}

	private class ConsoleLogFilePatternMatcher implements IPatternMatchListener {
		String fFilePath;

		public ConsoleLogFilePatternMatcher(String filePath) {
			fFilePath = escape(filePath);
		}

		private String escape(String path) {
			StringBuilder buffer = new StringBuilder(path);
			int index = buffer.indexOf("\\"); //$NON-NLS-1$
			while (index >= 0) {
				buffer.insert(index, '\\');
				index = buffer.indexOf("\\", index+2); //$NON-NLS-1$
			}
			return buffer.toString();
		}

		@Override
		public String getPattern() {
			return fFilePath;
		}

		@Override
		public void matchFound(PatternMatchEvent event) {
			try {
				addHyperlink(new ConsoleLogFileHyperlink(fFilePath), event.getOffset(), event.getLength());
				removePatternMatchListener(this);
			} catch (BadLocationException e) {
			}
		}

		@Override
		public int getCompilerFlags() {
			return 0;
		}

		@Override
		public String getLineQualifier() {
			return null;
		}

		@Override
		public void connect(TextConsole console) {
		}

		@Override
		public void disconnect() {
		}
	}

	private class ConsoleLogFileHyperlink implements IHyperlink {
		String fFilePath;
		ConsoleLogFileHyperlink(String filePath) {
			fFilePath = filePath;
		}

		@Override
		public void linkActivated() {
			IEditorInput input;
			Path path = new Path(fFilePath);
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			IFile ifile = root.getFileForLocation(path);
			if (ifile == null) { // The file is not in the workspace
				File file = new File(fFilePath);
				LocalFileStorage lfs = new LocalFileStorage(file);
				input = new StorageEditorInput(lfs, file);

			} else {
				input = new FileEditorInput(ifile);
			}

			IWorkbenchPage activePage = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
			try {
				activePage.openEditor(input, EditorsUI.DEFAULT_TEXT_EDITOR_ID, true);
			} catch (PartInitException e) {
			}
		}
		@Override
		public void linkEntered() {
		}
		@Override
		public void linkExited() {
		}
	}

	class StorageEditorInput extends PlatformObject implements IStorageEditorInput {
		private File fFile;
		private IStorage fStorage;

		public StorageEditorInput(IStorage storage, File file) {
			fStorage = storage;
			fFile = file;
		}

		@Override
		public IStorage getStorage() {
			return fStorage;
		}

		@Override
		public ImageDescriptor getImageDescriptor() {
			return null;
		}

		@Override
		public String getName() {
			return getStorage().getName();
		}

		@Override
		public IPersistableElement getPersistable() {
			return null;
		}

		@Override
		public String getToolTipText() {
			return getStorage().getFullPath().toOSString();
		}

		@Override
		public boolean equals(Object object) {
			return object instanceof StorageEditorInput &&
			 getStorage().equals(((StorageEditorInput)object).getStorage());
		}

		@Override
		public int hashCode() {
			return getStorage().hashCode();
		}

		@Override
		public boolean exists() {
			return fFile.exists();
		}
	}

	@Override
	public String getHelpContextId() {
		return IDebugHelpContextIds.PROCESS_CONSOLE;
	}
}
