/*******************************************************************************
 *  Copyright (c) 2000, 2018 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
 *******************************************************************************/
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.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;

	private volatile InputStream fInput;

    private FileOutputStream fFileOutputStream;

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

    private boolean fStreamsClosed = false;

    /**
     * Proxy to a console document
     */
    public ProcessConsole(IProcess process, IConsoleColorProvider colorProvider) {
        this(process, colorProvider, null);
    }

    /**
     * Constructor
     * @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;

        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) {
                    }
                    StringBuffer buffer = new StringBuffer();
                    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));
        }
    }

    @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) {
        }
        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;
    }

    /**
     * @see org.eclipse.ui.console.AbstractConsole#init()
     */
    @Override
	protected void init() {
        super.init();
        if (fProcess.isTerminated()) {
            closeStreams();
            resetName();
        } else {
            DebugPlugin.getDefault().addDebugEventListener(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);
        }

		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 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);
        }

        /*
         * (non-Javadoc)
         *
         * @see org.eclipse.debug.core.IStreamListener#streamAppended(java.lang.String,
         *      org.eclipse.debug.core.model.IStreamMonitor)
         */
        @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;

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

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

		@Override
		protected IStatus run(IProgressMonitor monitor) {
            String encoding = getEncoding();
            try {
                byte[] b = new byte[1024];
                int read = 0;
				while (read >= 0) {
					InputStream input = fInput;
					if (input == null) {
						break;
					}
					read = input.read(b);
                    if (read > 0) {
                        String s;
                        if (encoding != null) {
							s = new String(b, 0, read, encoding);
						} else {
							s = new String(b, 0, read);
						}
                        streamsProxy.write(s);
                    }
                }
            } catch (IOException e) {
                DebugUIPlugin.log(e);
            }
            return Status.OK_STATUS;
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.ui.console.IConsole#getImageDescriptor()
     */
    @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) {
    		StringBuffer buffer = new StringBuffer(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();
        }
    }

	/* (non-Javadoc)
	 * @see org.eclipse.ui.console.AbstractConsole#getHelpContextId()
	 */
	@Override
	public String getHelpContextId() {
		return IDebugHelpContextIds.PROCESS_CONSOLE;
	}
}
