From: incastrix <incastrix>
Date: Fri, 14 Mar 2008 17:08:25 +0000 (+0000)
Subject: Fix missed files from cvs to svn migration. again!
X-Git-Url: http://git.phpeclipse.com?hp=0e4c9cec5483b3f58914e3e013d5881c7061e3c4

Fix missed files from cvs to svn migration. again!
---

diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java
new file mode 100644
index 0000000..689c7d1
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialog.java
@@ -0,0 +1,632 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+
+//import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+//import org.eclipse.jface.viewers.TableTreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+public class EventDetailsDialog extends Dialog {
+	private LogEntry entry, parentEntry;
+	private LogViewLabelProvider labelProvider;
+	private static int COPY_ID = 22;
+	private /*Table*/TreeViewer provider;
+	private int elementNum, totalElementCount;
+	private LogEntry[] entryChildren;
+	private int childIndex = 0;
+	private boolean isOpen;
+	
+	private Label dateLabel;
+	private Label severityImageLabel;
+	private Label severityLabel;
+	private Text msgText;
+	private Text stackTraceText;
+	private Text sessionDataText;
+	private Clipboard clipboard;
+	private Button copyButton;
+	private Button backButton;
+	private Button nextButton;
+	private Image imgNextEnabled;
+	private Image imgPrevEnabled;
+	private Image imgCopyEnabled;
+	private SashForm sashForm;
+	
+	// sorting
+	private static int ASCENDING = 1;
+	private Comparator comparator = null;
+	private Collator collator;
+	
+	// location configuration
+	private IDialogSettings dialogSettings;
+	private Point dialogLocation;
+	private Point dialogSize;
+	private int[] sashWeights;
+	
+	// externalize strings
+	private String EVENT_NO_STACK = "EventDetailsDialog.noStack"; //$NON-NLS-1$
+	private String EVENT_PREVIOUS = "EventDetailsDialog.previous"; //$NON-NLS-1$
+	private String EVENT_NEXT = "EventDetailsDialog.next"; //$NON-NLS-1$
+	private String EVENT_COPY = "EventDetailsDialog.copy"; //$NON-NLS-1$
+
+	/**
+	 * @param parentShell
+	 *            shell in which dialog is displayed
+	 */
+	protected EventDetailsDialog(Shell parentShell, IAdaptable selection, ISelectionProvider provider) {
+		super(parentShell);
+		labelProvider = new LogViewLabelProvider();
+		this.provider = (/*Table*/TreeViewer) provider;
+		this.entry = (LogEntry)selection;
+		setShellStyle(SWT.MODELESS | SWT.MIN | SWT.MAX | SWT.RESIZE | SWT.CLOSE | SWT.BORDER | SWT.TITLE);
+		clipboard = new Clipboard(parentShell.getDisplay());
+		initialize();
+		createImages();
+		collator = Collator.getInstance();
+		readConfiguration();
+	}
+
+	private void initialize() {
+		elementNum = getParentElementNum();
+		totalElementCount = provider.getTree().getItemCount() - getVisibleChildrenCount();
+		parentEntry = (LogEntry) entry.getParent(entry);
+		if (isChild(entry)){
+			setEntryChildren(parentEntry);
+			resetChildIndex();
+		}
+	}
+	
+	private void resetChildIndex(){
+		for (int i = 0; i<entryChildren.length; i++){
+			if (entryChildren[i].getMessage().equals(entry.getMessage())
+					&& entryChildren[i].getDate().equals(entry.getDate())
+					&& entryChildren[i].getPluginId().equals(entry.getPluginId())
+					&& entryChildren[i].getSeverity() == entry.getSeverity() 
+					&& entryChildren[i].getSeverityText().equals(entry.getSeverityText())){
+				childIndex = i;
+				break;
+			}
+		}
+	}
+	
+	private void createImages(){
+		imgCopyEnabled =
+			PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY).createImage(
+				true);
+		//imgNextDisabled. = PHPDegugCorePluginImages.DESC_NEXT_EVENT_DISABLED.createImage(true);
+		//imgPrevDisabled = PHPDegugCorePluginImages.DESC_PREV_EVENT_DISABLED.createImage(true);
+		imgPrevEnabled = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_PREV_EVENT);
+		imgNextEnabled = XDebugUIPluginImages.get(XDebugUIPluginImages.DESC_NEXT_EVENT);
+	}
+
+	private boolean isChild(LogEntry entry) {
+		return entry.getParent(entry) != null;
+	}
+	
+	public boolean isOpen(){
+		return isOpen;
+	}
+
+	public int open(){
+		isOpen = true;
+		if (sashWeights == null){
+			int width = getSashForm().getClientArea().width;
+			if (width - 100 > 0)
+				width -= 100;
+			else
+				width = width/2;
+			sashWeights = new int[]{width, getSashForm().getClientArea().width-width};
+		}
+		getSashForm().setWeights(sashWeights);
+		return super.open();
+	}
+	
+	public boolean close() {
+		storeSettings();
+		isOpen = false;
+		imgCopyEnabled.dispose();
+		imgNextEnabled.dispose();
+		imgPrevEnabled.dispose();
+		return super.close();
+	}
+
+	public void create() {
+		super.create();
+		
+		// dialog location 
+		if (dialogLocation != null)
+			getShell().setLocation(dialogLocation);
+		
+		// dialog size
+		if (dialogSize != null)
+			getShell().setSize(dialogSize);
+		else
+			getShell().setSize(500,550);
+		
+		
+		applyDialogFont(buttonBar);
+		getButton(IDialogConstants.OK_ID).setFocus();
+	}
+
+	protected void buttonPressed(int buttonId) {
+		if (IDialogConstants.OK_ID == buttonId)
+			okPressed();
+		else if (IDialogConstants.CANCEL_ID == buttonId)
+			cancelPressed();
+		else if (IDialogConstants.BACK_ID == buttonId)
+			backPressed();
+		else if (IDialogConstants.NEXT_ID == buttonId)
+			nextPressed();
+		else if (COPY_ID == buttonId)
+			copyPressed();
+	}
+
+	protected void backPressed() {
+		if (isChild(entry)) {
+			if (childIndex > 0) {
+				childIndex--;
+				entry = entryChildren[childIndex];
+			} else
+				entry = parentEntry;
+		} else {
+			if (elementNum - 1 >= 0)
+				elementNum -= 1;
+			entry = (LogEntry) provider.getTree().getItem(elementNum).getData();
+		}
+		setEntrySelectionInTable();
+	}
+
+	protected void nextPressed() {
+		if (isChild(entry) && childIndex < entryChildren.length-1) {
+			childIndex++;
+			entry = entryChildren[childIndex];
+		} else if (elementNum + 1 < totalElementCount){
+				elementNum += 1;
+			entry = (LogEntry) provider.getTree().getItem(elementNum).getData(); //getElementAt(elementNum);
+		} else { // at end of list but can branch into child elements - bug 58083
+			setEntryChildren(entry);
+			entry = entryChildren[0];
+		}
+		setEntrySelectionInTable();
+	}
+
+	protected void copyPressed() {
+		StringWriter writer = new StringWriter();
+		PrintWriter pwriter = new PrintWriter(writer);
+
+		entry.write(pwriter);
+		pwriter.flush();
+		String textVersion = writer.toString();
+		try {
+			pwriter.close();
+			writer.close();
+		} catch (IOException e) {
+		}
+		// set the clipboard contents
+		clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance()});	
+	}
+
+	public void setComparator(Comparator comparator){
+		this.comparator = comparator;
+		updateProperties();
+	}
+	private void setComparator(byte sortType, final int sortOrder){
+		if (sortType == LogView.DATE){
+			comparator = new Comparator(){
+				public int compare(Object e1, Object e2) {
+					try {
+						SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+						Date date1 = formatter.parse(((LogEntry)e1).getDate());
+						Date date2 = formatter.parse(((LogEntry)e2).getDate());
+						if (sortOrder == ASCENDING) 
+							return date1.before(date2) ? -1 : 1;
+						return date1.after(date2) ? -1 : 1;
+					} catch (ParseException e) {
+					}
+					return 0;
+				}
+			};
+		} else if (sortType == LogView.PLUGIN){
+			comparator = new Comparator(){
+				public int compare(Object e1, Object e2) {
+					LogEntry entry1 = (LogEntry)e1;
+					LogEntry entry2 = (LogEntry)e2;
+					return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * sortOrder;
+				}
+			};
+		} else {
+			comparator = new Comparator(){
+				public int compare(Object e1, Object e2) {
+					LogEntry entry1 = (LogEntry)e1;
+					LogEntry entry2 = (LogEntry)e2;
+					return collator.compare(entry1.getMessage(), entry2.getMessage()) * sortOrder;
+				}
+			};
+		}
+	}
+	
+	public void resetSelection(IAdaptable selectedEntry, byte sortType, int sortOrder){
+		setComparator(sortType, sortOrder);
+		resetSelection(selectedEntry);
+	}
+	
+	public void resetSelection(IAdaptable selectedEntry){
+		if (entry.equals(selectedEntry) &&
+				elementNum == getParentElementNum()){
+			updateProperties();
+			return;
+		}
+		entry = (LogEntry)selectedEntry;
+		initialize();
+		updateProperties();
+	}
+	
+	public void resetButtons(){
+		backButton.setEnabled(false);
+		nextButton.setEnabled(false);
+	}
+	
+	private void setEntrySelectionInTable(){
+		ISelection selection = new StructuredSelection(entry);
+		provider.setSelection(selection);
+	}
+	
+	public void updateProperties() {	
+		if (isChild(entry)){
+			parentEntry = (LogEntry) entry.getParent(entry);
+			setEntryChildren(parentEntry);
+			resetChildIndex();
+		}
+
+
+		totalElementCount = provider.getTree().getItemCount() - getVisibleChildrenCount();
+		dateLabel.setText(entry.getDate());
+		severityImageLabel.setImage(labelProvider.getColumnImage(entry, 1));
+		severityLabel.setText(entry.getSeverityText());
+		msgText.setText(entry.getMessage());
+		String stack = entry.getStack();
+		if (stack != null) {
+			stackTraceText.setText(stack);
+		} else {
+			stackTraceText.setText(XDebugUIPlugin.getString(EVENT_NO_STACK));
+		}
+		LogSession session = entry.getSession();
+		if (session != null && session.getSessionData() != null)
+			sessionDataText.setText(session.getSessionData());
+
+		updateButtons();
+	}
+	
+	private void updateButtons(){
+		boolean isAtEnd = elementNum == totalElementCount - 1;
+		if (isChild(entry)){
+			backButton.setEnabled(true);
+			boolean isLastChild = childIndex == entryChildren.length-1;
+			nextButton.setEnabled(!isLastChild || !isAtEnd || entry.hasChildren());
+		} else {
+			backButton.setEnabled(elementNum != 0);
+			nextButton.setEnabled(!isAtEnd || entry.hasChildren());
+		}
+	}
+	
+	private void setEntryChildren(LogEntry parent){
+		Object[] children = parent.getChildren(parent);
+		if (comparator != null)
+			Arrays.sort(children, comparator);
+		entryChildren = new LogEntry[children.length];
+		
+		System.arraycopy(children,0,entryChildren,0,children.length);
+	}
+	
+	private int getParentElementNum(){
+		LogEntry itemEntry = (LogEntry)((IStructuredSelection)provider.getSelection()).getFirstElement();
+		itemEntry = getRootEntry(itemEntry);
+		
+		for (int i = 0; i<provider.getTree().getItemCount()/* getTableTree().getItemCount()*/; i++){
+			try {
+				LogEntry littleEntry = (LogEntry)provider.getTree().getItem(i).getData();// getElementAt(i);
+				if (itemEntry.equals(littleEntry)){
+					return i;
+				}
+			} catch (Exception e){
+				
+			}
+		}
+		return 0;
+	}
+	private LogEntry getRootEntry(LogEntry entry){
+		if (!isChild(entry))
+			return entry;
+		return getRootEntry((LogEntry)entry.getParent(entry));
+	}
+	public SashForm getSashForm(){
+		return sashForm;
+	}
+	private int getVisibleChildrenCount(){
+		Object[] elements = provider.getVisibleExpandedElements();
+		LogEntry[] expandedElements = new LogEntry[elements.length];
+		System.arraycopy(elements, 0, expandedElements, 0, elements.length);
+		int count = 0;
+		for (int i = 0; i<expandedElements.length; i++){
+			count += expandedElements[i].getChildren(expandedElements[i]).length;
+		}
+		return count;
+	}
+	
+	protected Control createDialogArea(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		container.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		container.setLayoutData(gd);
+
+		createDetailsSection(container);
+		createSashForm(container);
+		createStackSection(getSashForm());
+		createSessionSection(getSashForm());
+
+		updateProperties();
+		Dialog.applyDialogFont(container);
+		return container;
+	}
+
+	private void createSashForm(Composite parent){
+		sashForm = new SashForm(parent, SWT.VERTICAL);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = 0;
+		sashForm.setLayout(layout);
+		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
+	}
+	
+	private void createToolbarButtonBar(Composite parent) {
+		Composite comp = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = layout.marginHeight = 0;
+		layout.numColumns = 1;
+		comp.setLayout(layout);
+		comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		Composite container = new Composite(comp, SWT.NONE);
+		layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 10;
+		layout.numColumns = 1;
+		container.setLayout(layout);
+		container.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		backButton = createButton(container, IDialogConstants.BACK_ID, "", false); //$NON-NLS-1$
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 3;
+		gd.verticalSpan = 1;
+		backButton.setLayoutData(gd);
+		backButton.setToolTipText(XDebugUIPlugin.getString(EVENT_PREVIOUS));
+		backButton.setImage(imgPrevEnabled);
+		
+		nextButton = createButton(container, IDialogConstants.NEXT_ID, "", false); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		gd.verticalSpan = 1;
+		nextButton.setLayoutData(gd);
+		nextButton.setToolTipText(XDebugUIPlugin.getString(EVENT_NEXT));
+		nextButton.setImage(imgNextEnabled);
+		
+		copyButton = createButton(container, COPY_ID, "", false); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		gd.verticalSpan = 1;
+		copyButton.setLayoutData(gd);
+		copyButton.setImage(imgCopyEnabled);
+		copyButton.setToolTipText(XDebugUIPlugin.getString(EVENT_COPY));
+	}
+
+	protected void createButtonsForButtonBar(Composite parent) {
+		// create OK button only by default
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+	}
+
+	private void createDetailsSection(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		container.setLayout(layout);
+		container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		createTextSection(container);
+		createToolbarButtonBar(container);
+	}
+
+	private void createTextSection(Composite parent) {
+		Composite textContainer = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.marginHeight = layout.marginWidth = 0;
+		textContainer.setLayout(layout);
+		textContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Label label = new Label(textContainer, SWT.NONE);
+		label.setText(XDebugUIPlugin.getString("EventDetailsDialog.date")); //$NON-NLS-1$
+		dateLabel = new Label(textContainer, SWT.NULL);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		dateLabel.setLayoutData(gd);
+
+		label = new Label(textContainer, SWT.NONE);
+		label.setText(XDebugUIPlugin.getString("EventDetailsDialog.severity")); //$NON-NLS-1$
+		severityImageLabel = new Label(textContainer, SWT.NULL);
+		severityLabel = new Label(textContainer, SWT.NULL);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		severityLabel.setLayoutData(gd);
+
+		label = new Label(textContainer, SWT.NONE);
+		label.setText(XDebugUIPlugin.getString("EventDetailsDialog.message")); //$NON-NLS-1$
+		gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
+		label.setLayoutData(gd);
+		msgText = new Text(textContainer, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
+		msgText.setEditable(false);
+		gd = new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL);
+		gd.horizontalSpan = 2;
+		gd.verticalSpan = 8;
+		gd.grabExcessVerticalSpace = true;
+		msgText.setLayoutData(gd);
+	}
+
+	private void createStackSection(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 6;
+		container.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = 100;
+		container.setLayoutData(gd);
+
+		Label label = new Label(container, SWT.NULL);
+		label.setText(XDebugUIPlugin.getString("EventDetailsDialog.exception")); //$NON-NLS-1$
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 3;
+		label.setLayoutData(gd);
+
+		stackTraceText = new Text(container, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
+		gd.grabExcessHorizontalSpace = true;
+		stackTraceText.setLayoutData(gd);
+		stackTraceText.setEditable(false);
+	}
+
+	private void createSessionSection(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 6;
+		container.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.heightHint = 100;
+		container.setLayoutData(gd);
+
+		Label line = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.widthHint = 1;
+		line.setLayoutData(gd);
+		
+		Label label = new Label(container, SWT.NONE);
+		label.setText(XDebugUIPlugin.getString("EventDetailsDialog.session")); //$NON-NLS-1$
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		label.setLayoutData(gd);
+		sessionDataText = new Text(container, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL );
+		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
+		gd.grabExcessHorizontalSpace = true;
+		sessionDataText.setLayoutData(gd);
+		sessionDataText.setEditable(false);
+	}
+	
+	//--------------- configuration handling --------------
+	
+	/**
+	 * Stores the current state in the dialog settings.
+	 * @since 2.0
+	 */
+	private void storeSettings() {
+		writeConfiguration();
+	}
+	/**
+	 * Returns the dialog settings object used to share state
+	 * between several event detail dialogs.
+	 * 
+	 * @return the dialog settings to be used
+	 */
+	private IDialogSettings getDialogSettings() {
+//		IDialogSettings settings= XDebugCorePlugin.getDefault().getDialogSettings();
+		IDialogSettings settings = getDialogSettings();
+		dialogSettings= settings.getSection(getClass().getName());
+		if (dialogSettings == null)
+			dialogSettings= settings.addNewSection(getClass().getName());
+		return dialogSettings;
+	}
+
+	/**
+	 * Initializes itself from the dialog settings with the same state
+	 * as at the previous invocation.
+	 */
+	private void readConfiguration() {
+		IDialogSettings s= getDialogSettings();
+		try {
+			int x= s.getInt("x"); //$NON-NLS-1$
+			int y= s.getInt("y"); //$NON-NLS-1$
+			dialogLocation= new Point(x, y);
+			
+			x = s.getInt("width"); //$NON-NLS-1$
+			y = s.getInt("height"); //$NON-NLS-1$
+			dialogSize = new Point(x,y);
+			
+			sashWeights = new int[2];
+			sashWeights[0] = s.getInt("sashWidth1"); //$NON-NLS-1$
+			sashWeights[1] = s.getInt("sashWidth2"); //$NON-NLS-1$
+			
+		} catch (NumberFormatException e) {
+			dialogLocation= null;
+			dialogSize = null;
+			sashWeights = null;
+		}
+	}
+	
+	private void writeConfiguration(){
+		IDialogSettings s = getDialogSettings();
+		Point location = getShell().getLocation();
+		s.put("x", location.x); //$NON-NLS-1$
+		s.put("y", location.y); //$NON-NLS-1$
+		
+		Point size = getShell().getSize();
+		s.put("width", size.x); //$NON-NLS-1$
+		s.put("height", size.y); //$NON-NLS-1$
+		
+		sashWeights = getSashForm().getWeights();
+		s.put("sashWidth1", sashWeights[0]); //$NON-NLS-1$
+		s.put("sashWidth2", sashWeights[1]); //$NON-NLS-1$
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialogAction.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialogAction.java
new file mode 100644
index 0000000..5a6fe1a
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/EventDetailsDialogAction.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.util.Comparator;
+
+
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.actions.SelectionProviderAction;
+
+
+
+public class EventDetailsDialogAction extends SelectionProviderAction{
+
+	/**
+	 * The shell in which to open the property dialog
+	 */
+	private Shell shell;
+	private ISelectionProvider provider;
+	private EventDetailsDialog propertyDialog;
+	private Comparator comparator;
+	/**
+	 * Creates a new action for opening a property dialog
+	 * on the elements from the given selection provider
+	 * @param shell - the shell in which the dialog will open
+	 * @param provider - the selection provider whose elements
+	 * the property dialog will describe
+	 */
+	public EventDetailsDialogAction(Shell shell, ISelectionProvider provider){
+       super(provider, "Test Text"); 
+		Assert.isNotNull(shell);
+		this.shell = shell;
+		this.provider = provider;
+		// setToolTipText
+		//WorkbenchHelp.setHelp
+	}
+	
+	public boolean resetSelection(byte sortType, int sortOrder){
+		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
+		if (element == null)
+			return false;
+		if (propertyDialog != null && propertyDialog.isOpen()){
+			propertyDialog.resetSelection(element, sortType, sortOrder);
+			return true;
+		}
+		return false;
+	}
+	public void resetSelection(){
+		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
+		if (element == null)
+			return;
+		if (propertyDialog != null && propertyDialog.isOpen())
+			propertyDialog.resetSelection(element);
+	}
+	
+	public void resetDialogButtons(){
+		if (propertyDialog != null && propertyDialog.isOpen())
+			propertyDialog.resetButtons();
+	}
+	
+	public void setComparator(Comparator comparator){
+		this.comparator = comparator;
+	}
+	public void run(){
+		if (propertyDialog != null && propertyDialog.isOpen()){
+			resetSelection();
+			return;
+		}
+		
+		//get initial selection
+		IAdaptable element = (IAdaptable) getStructuredSelection().getFirstElement();
+		if (element == null)
+			return;
+		
+		propertyDialog = new EventDetailsDialog(shell, element, provider);
+		propertyDialog.create();
+		propertyDialog.getShell().setText(XDebugUIPlugin.getString("EventDetailsDialog.title")); //$NON-NLS-1$
+		propertyDialog.setComparator(comparator);
+		propertyDialog.open();
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/FilterDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/FilterDialog.java
new file mode 100644
index 0000000..57b8828
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/FilterDialog.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IMemento;
+
+
+public class FilterDialog extends Dialog {
+	private Button limit;
+	private Text limitText;
+
+	private Button okButton;
+	private Button errorButton;
+	private Button warningButton;
+	private Button infoButton;
+	private Button showAllButton;
+	private IMemento memento;
+
+	public FilterDialog(Shell parentShell, IMemento memento) {
+		super(parentShell);
+		this.memento = memento;
+	}
+	
+	protected Control createDialogArea(Composite parent) {
+		Composite container = (Composite)super.createDialogArea(parent);		
+		createEventTypesGroup(container);
+		createLimitSection(container);
+		createSessionSection(container);
+		
+		Dialog.applyDialogFont(container);
+		return container;
+	}
+	
+	private void createEventTypesGroup(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setLayout(new GridLayout());
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 275;
+		group.setLayoutData(gd);
+		group.setText(XDebugUIPlugin.getString("LogView.FilterDialog.eventTypes")); //$NON-NLS-1$
+		
+		infoButton = new Button(group, SWT.CHECK);
+		infoButton.setText(XDebugUIPlugin.getString("LogView.FilterDialog.information")); //$NON-NLS-1$
+		infoButton.setSelection(memento.getString(LogView.P_LOG_INFO).equals("true")); //$NON-NLS-1$
+		
+		warningButton = new Button(group, SWT.CHECK);
+		warningButton.setText(XDebugUIPlugin.getString("LogView.FilterDialog.warning")); //$NON-NLS-1$
+		warningButton.setSelection(memento.getString(LogView.P_LOG_WARNING).equals("true")); //$NON-NLS-1$
+		
+		errorButton = new Button(group, SWT.CHECK);
+		errorButton.setText(XDebugUIPlugin.getString("LogView.FilterDialog.error")); //$NON-NLS-1$
+		errorButton.setSelection(memento.getString(LogView.P_LOG_ERROR).equals("true"));		 //$NON-NLS-1$
+	}
+	
+	private void createLimitSection(Composite parent) {
+		Composite comp = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		comp.setLayout(layout);
+		comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		limit = new Button(comp, SWT.CHECK);
+		limit.setText(XDebugUIPlugin.getString("LogView.FilterDialog.limitTo")); //$NON-NLS-1$
+		limit.setSelection(memento.getString(LogView.P_USE_LIMIT).equals("true")); //$NON-NLS-1$
+		limit.addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			limitText.setEnabled(((Button)e.getSource()).getSelection());
+		}});
+		
+		limitText = new Text(comp, SWT.BORDER);
+		limitText.addModifyListener(new ModifyListener(){
+			public void modifyText(ModifyEvent e) {
+				try {
+					if (okButton == null)
+						return;
+					Integer.parseInt(limitText.getText());
+					okButton.setEnabled(true);
+				} catch (NumberFormatException e1) {
+					okButton.setEnabled(false);
+				}
+			}});
+		limitText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		limitText.setText(memento.getString(LogView.P_LOG_LIMIT));
+		limitText.setEnabled(limit.getSelection());
+
+	}
+	
+	private void createSessionSection(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		container.setLayout(new GridLayout());
+		container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		Label label = new Label(container, SWT.NONE);
+		label.setText(XDebugUIPlugin.getString("LogView.FilterDialog.eventsLogged")); //$NON-NLS-1$
+		
+		showAllButton = new Button(container, SWT.RADIO);
+		showAllButton.setText(XDebugUIPlugin.getString("LogView.FilterDialog.allSessions")); //$NON-NLS-1$
+		GridData gd = new GridData();
+		gd.horizontalIndent = 20;
+		showAllButton.setLayoutData(gd);
+		
+		Button button = new Button(container, SWT.RADIO);
+		button.setText(XDebugUIPlugin.getString("LogView.FilterDialog.recentSession")); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalIndent = 20;
+		button.setLayoutData(gd);
+		
+		if (memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) { //$NON-NLS-1$
+			showAllButton.setSelection(true);
+		} else {
+			button.setSelection(true);
+		}
+	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		okButton = createButton(
+				parent,
+				IDialogConstants.OK_ID,
+				IDialogConstants.OK_LABEL,
+				true);
+		createButton(
+			parent,
+			IDialogConstants.CANCEL_ID,
+			IDialogConstants.CANCEL_LABEL,
+			false);
+	}
+	
+	protected void okPressed() {
+		memento.putString(LogView.P_LOG_INFO, infoButton.getSelection() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		memento.putString(LogView.P_LOG_WARNING, warningButton.getSelection() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		memento.putString(LogView.P_LOG_ERROR, errorButton.getSelection() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		memento.putString(LogView.P_LOG_LIMIT, limitText.getText());
+		memento.putString(LogView.P_USE_LIMIT, limit.getSelection() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		memento.putString(LogView.P_SHOW_ALL_SESSIONS, showAllButton.getSelection() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		super.okPressed();
+	}
+
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogEntry.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogEntry.java
new file mode 100644
index 0000000..b492240
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogEntry.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+
+public class LogEntry extends PlatformObject implements IWorkbenchAdapter {
+	private static final String KEY_ERROR = "LogView.severity.error"; //$NON-NLS-1$
+	private static final String KEY_WARNING = "LogView.severity.warning"; //$NON-NLS-1$
+	private static final String KEY_INFO = "LogView.severity.info"; //$NON-NLS-1$
+	private ArrayList children;
+	private LogEntry parent;
+	private String pluginId;
+	private int severity;
+	private int code;
+	private String date;
+	private String message;
+	private String stack;
+	private LogSession session;
+
+	public LogEntry() {
+	}
+
+	public LogSession getSession() {
+		return session;
+	}
+
+	void setSession(LogSession session) {
+		this.session = session;
+	}
+
+	public LogEntry(IStatus status) {
+		processStatus(status);
+	}
+	public int getSeverity() {
+		return severity;
+	}
+
+	public boolean isOK() {
+		return severity == IStatus.OK;
+	}
+	public int getCode() {
+		return code;
+	}
+	public String getPluginId() {
+		return pluginId;
+	}
+	public String getMessage() {
+		return message;
+	}
+	public String getStack() {
+		return stack;
+	}
+	public String getDate() {
+		return date;
+	}
+	public String getSeverityText() {
+		return getSeverityText(severity);
+	}
+	public boolean hasChildren() {
+		return children != null && children.size() > 0;
+	}
+	public String toString() {
+		return getSeverityText();
+	}
+	/**
+	 * @see IWorkbenchAdapter#getChildren(Object)
+	 */
+	public Object[] getChildren(Object parent) {
+		if (children == null)
+			return new Object[0];
+		return children.toArray();
+	}
+
+	/**
+	 * @see IWorkbenchAdapter#getImageDescriptor(Object)
+	 */
+	public ImageDescriptor getImageDescriptor(Object arg0) {
+		return null;
+	}
+
+	/**
+	 * @see IWorkbenchAdapter#getLabel(Object)
+	 */
+	public String getLabel(Object obj) {
+		return getSeverityText();
+	}
+
+	/**
+	 * @see IWorkbenchAdapter#getParent(Object)
+	 */
+	public Object getParent(Object obj) {
+		return parent;
+	}
+
+	void setParent(LogEntry parent) {
+		this.parent = parent;
+	}
+
+	private String getSeverityText(int severity) {
+		switch (severity) {
+			case IStatus.ERROR :
+				return XDebugUIPlugin.getString(KEY_ERROR);
+			case IStatus.WARNING :
+				return XDebugUIPlugin.getString(KEY_WARNING);
+			case IStatus.INFO :
+				return XDebugUIPlugin.getString(KEY_INFO);
+		}
+		return "?"; //$NON-NLS-1$
+	}
+
+	int processLogLine(String line, boolean root) {
+		//!ENTRY <pluginID> <severity> <code> <date>
+		//!SUBENTRY <depth> <pluginID> <severity> <code> <date>
+		StringTokenizer stok = new StringTokenizer(line, " ", true); //$NON-NLS-1$
+		StringBuffer dateBuffer = new StringBuffer();
+
+		int dateCount = 5;
+		int depth = 0;
+		for (int i = 0; stok.hasMoreTokens();) {
+			String token = stok.nextToken();
+			if (i >= dateCount) {
+				dateBuffer.append(token);
+				continue;
+			} else if (token.equals(" ")) //$NON-NLS-1$
+				continue;
+			switch (i) {
+				case 0 : // entry or subentry
+					if (root)
+						i += 2;
+					else
+						i++;
+					break;
+				case 1 : // depth
+					depth = parseInteger(token);
+					i++;
+					break;
+				case 2 :
+					pluginId = token;
+					i++;
+					break;
+				case 3 : // severity
+					severity = parseInteger(token);
+					i++;
+					break;
+				case 4 : // code
+					code = parseInteger(token);
+					i++;
+					break;
+			}
+		}
+		date = dateBuffer.toString().trim();
+		return depth;
+	}
+
+	private int parseInteger(String token) {
+		try {
+			return Integer.parseInt(token);
+		} catch (NumberFormatException e) {
+			return 0;
+		}
+	}
+
+	void setStack(String stack) {
+		this.stack = stack;
+	}
+	void setMessage(String message) {
+		this.message = message;
+	}
+
+	private void processStatus(IStatus status) {
+		pluginId = status.getPlugin();
+		severity = status.getSeverity();
+		code = status.getCode();
+		DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+		date = formatter.format(new Date());
+		message = status.getMessage();
+		Throwable throwable = status.getException();
+		if (throwable != null) {
+			StringWriter swriter = new StringWriter();
+			PrintWriter pwriter = new PrintWriter(swriter);
+			throwable.printStackTrace(pwriter);
+			pwriter.flush();
+			pwriter.close();
+			stack = swriter.toString();
+		}
+		IStatus[] schildren = status.getChildren();
+		if (schildren.length > 0) {
+			children = new ArrayList();
+			for (int i = 0; i < schildren.length; i++) {
+				LogEntry child = new LogEntry(schildren[i]);
+				addChild(child);
+			}
+		}
+	}
+	void addChild(LogEntry child) {
+		if (children == null)
+			children = new ArrayList();
+		children.add(child);
+		child.setParent(this);
+	}
+	public void write(PrintWriter writer) {
+		writer.print(getSeverityText());
+		if (date != null) {
+			writer.print(" "); //$NON-NLS-1$
+			writer.print(getDate());
+		}
+		if (message != null) {
+			writer.print(" "); //$NON-NLS-1$
+			writer.print(getMessage());
+		}
+		writer.println();
+		if (stack != null)
+			writer.println(stack);
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java
new file mode 100644
index 0000000..7a33d18
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogReader.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.ui.IMemento;
+
+class LogReader {
+	private static final int SESSION_STATE = 10;
+	public static final long MAX_FILE_LENGTH = 1024*1024;
+	private static final int ENTRY_STATE = 20;
+	private static final int SUBENTRY_STATE = 30;
+	private static final int MESSAGE_STATE = 40;
+	private static final int STACK_STATE = 50;
+	private static final int TEXT_STATE = 60;
+	private static final int UNKNOWN_STATE = 70;
+	
+	private static LogSession currentSession;
+	
+	public static void parseLargeFile(File file, ArrayList entries, IMemento memento) {
+		ArrayList parents = new ArrayList();
+		LogEntry current = null;
+		LogSession session = null;
+		int writerState = UNKNOWN_STATE;
+		StringWriter swriter = null;
+		PrintWriter writer = null;
+		int state = UNKNOWN_STATE;
+		currentSession = null;
+		RandomAccessFile random = null;
+		try {
+			random = new RandomAccessFile(file, "r"); //$NON-NLS-1$
+			random.seek(file.length() - MAX_FILE_LENGTH);
+			for (;;) {
+				String line = random.readLine();
+				if (line == null)
+					break;
+				
+				line = line.trim();
+				if (line.length() == 0)
+					continue;
+
+				if (line.startsWith("!SESSION")) { //$NON-NLS-1$
+					state = SESSION_STATE;
+				} else if (line.startsWith("!ENTRY")) { //$NON-NLS-1$
+					state = ENTRY_STATE;
+				} else if (line.startsWith("!SUBENTRY")) { //$NON-NLS-1$
+					state = SUBENTRY_STATE;
+				} else if (line.startsWith("!MESSAGE")) { //$NON-NLS-1$
+					state = MESSAGE_STATE;
+				} else if (line.startsWith("!STACK")) { //$NON-NLS-1$
+					state = STACK_STATE;
+				} else
+					state = TEXT_STATE;
+			
+				if (state == TEXT_STATE) {
+					if (writer != null)
+						writer.println(line);
+					continue;
+				}
+			
+				if (writer != null) {
+					if (writerState == STACK_STATE && current != null) {
+						current.setStack(swriter.toString());
+					} else if (writerState == SESSION_STATE && session != null) {
+						session.setSessionData(swriter.toString());
+					} else if (writerState == MESSAGE_STATE && current != null){
+						String message = current.getMessage() + swriter.toString();
+						message = message.trim();
+						current.setMessage(message);
+					}
+					writerState = UNKNOWN_STATE;
+					swriter = null;
+					writer.close();
+					writer = null;
+				}
+			
+				if (state == STACK_STATE) {
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					writerState = STACK_STATE;
+				} else if (state == SESSION_STATE) {
+					session = new LogSession();
+					session.processLogLine(line);
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					writerState = SESSION_STATE;
+					updateCurrentSession(session);
+					if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$
+						entries.clear();
+				} else if (state == ENTRY_STATE) {
+					LogEntry entry = new LogEntry();
+					entry.setSession(session);
+					entry.processLogLine(line, true);
+					setNewParent(parents, entry, 0);
+					current = entry;
+					addEntry(current, entries, memento, false);
+				} else if (state == SUBENTRY_STATE) {
+					LogEntry entry = new LogEntry();
+					entry.setSession(session);
+					int depth = entry.processLogLine(line, false);
+					setNewParent(parents, entry, depth);
+					current = entry;
+					LogEntry parent = (LogEntry) parents.get(depth - 1);
+					parent.addChild(entry);
+				} else if (state == MESSAGE_STATE) {
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					String message = ""; //$NON-NLS-1$
+					if (line.length() > 8)
+						message = line.substring(9).trim();
+					message = message.trim();
+					if (current != null)
+						current.setMessage(message);
+					writerState = MESSAGE_STATE;
+				}
+			}
+		} catch (FileNotFoundException e) {
+		} catch (IOException e) {
+		} finally {
+			try {
+				if (random != null)
+					random.close();
+			} catch (IOException e1) {
+			}
+		}
+	}
+	
+	public static void parseLogFile(File file, ArrayList entries, IMemento memento) {
+		ArrayList parents = new ArrayList();
+		LogEntry current = null;
+		LogSession session = null;
+		int writerState = UNKNOWN_STATE;
+		StringWriter swriter = null;
+		PrintWriter writer = null;
+		int state = UNKNOWN_STATE;
+		currentSession = null;
+		BufferedReader reader = null;
+		try {
+					
+			reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); //$NON-NLS-1$
+			while(reader.ready()) {
+				String line = reader.readLine();
+				if (line == null)
+					continue;
+				line = line.trim();
+				if (line.length() == 0)
+					continue;
+
+				if (line.startsWith("!SESSION")) { //$NON-NLS-1$
+					state = SESSION_STATE;
+				} else if (line.startsWith("!ENTRY")) { //$NON-NLS-1$
+					state = ENTRY_STATE;
+				} else if (line.startsWith("!SUBENTRY")) { //$NON-NLS-1$
+					state = SUBENTRY_STATE;
+				} else if (line.startsWith("!MESSAGE")) { //$NON-NLS-1$
+					state = MESSAGE_STATE;
+				} else if (line.startsWith("!STACK")) { //$NON-NLS-1$
+					state = STACK_STATE;
+				} else
+					state = TEXT_STATE;
+			
+				if (state == TEXT_STATE) {
+					if (writer != null)
+						writer.println(line);
+					continue;
+				}
+			
+				if (writer != null) {
+					if (writerState == STACK_STATE && current != null) {
+						current.setStack(swriter.toString());
+					} else if (writerState == SESSION_STATE && session != null) {
+						session.setSessionData(swriter.toString());
+					} else if (writerState == MESSAGE_STATE && current != null){
+						String message = current.getMessage() + swriter.toString();
+						message = message.trim();
+						current.setMessage(message);
+					}
+					writerState = UNKNOWN_STATE;
+					swriter = null;
+					writer.close();
+					writer = null;
+				}
+			
+				if (state == STACK_STATE) {
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					writerState = STACK_STATE;
+				} else if (state == SESSION_STATE) {
+					session = new LogSession();
+					session.processLogLine(line);
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					writerState = SESSION_STATE;
+					updateCurrentSession(session);
+					if (currentSession.equals(session) && !memento.getString(LogView.P_SHOW_ALL_SESSIONS).equals("true")) //$NON-NLS-1$
+						entries.clear();
+				} else if (state == ENTRY_STATE) {
+					LogEntry entry = new LogEntry();
+					entry.setSession(session);
+					entry.processLogLine(line, true);
+					setNewParent(parents, entry, 0);
+					current = entry;
+					addEntry(current, entries, memento, false);
+				} else if (state == SUBENTRY_STATE) {
+					LogEntry entry = new LogEntry();
+					entry.setSession(session);
+					int depth = entry.processLogLine(line, false);
+					setNewParent(parents, entry, depth);
+					current = entry;
+					LogEntry parent = (LogEntry) parents.get(depth - 1);
+					parent.addChild(entry);
+				} else if (state == MESSAGE_STATE) {
+					swriter = new StringWriter();
+					writer = new PrintWriter(swriter, true);
+					String message = ""; //$NON-NLS-1$
+					if (line.length() > 8)
+						message = line.substring(9).trim();
+					message = message.trim();
+					if (current != null)
+						current.setMessage(message);
+					writerState = MESSAGE_STATE;
+				}
+			}
+		} catch (FileNotFoundException e) {
+		} catch (IOException e) {
+		} finally {
+			try {
+				if (reader != null)
+					reader.close();
+			} catch (IOException e1) {
+			}
+		}
+	}
+		
+	private static void updateCurrentSession(LogSession session) {
+		if (currentSession == null) {
+			currentSession = session;
+			return;
+		}		
+		Date currentDate = currentSession.getDate();
+		Date sessionDate = session.getDate();		
+		if (currentDate == null && sessionDate != null)
+			currentSession = session;
+		else if (currentDate != null && sessionDate == null)
+			currentSession = session;
+		else if (currentDate != null && sessionDate != null && sessionDate.after(currentDate))
+			currentSession = session;	
+	}
+	
+	public static void addEntry(LogEntry current, ArrayList entries, IMemento memento, boolean useCurrentSession) {
+		int severity = current.getSeverity();
+		boolean doAdd = true;
+		switch(severity) {
+			case IStatus.INFO:
+				doAdd = memento.getString(LogView.P_LOG_INFO).equals("true"); //$NON-NLS-1$
+				break;
+			case IStatus.WARNING:
+				doAdd = memento.getString(LogView.P_LOG_WARNING).equals("true"); //$NON-NLS-1$
+				break;
+			case IStatus.ERROR:
+				doAdd = memento.getString(LogView.P_LOG_ERROR).equals("true"); //$NON-NLS-1$
+				break;
+		}
+		if (doAdd) {
+			if (useCurrentSession)
+				current.setSession(currentSession);
+			entries.add(0, current);
+			
+			if (memento.getString(LogView.P_USE_LIMIT).equals("true") //$NON-NLS-1$
+				&& entries.size() > memento.getInteger(LogView.P_LOG_LIMIT).intValue())
+				entries.remove(entries.size() - 1);
+		}
+	}
+
+	private static void setNewParent(
+		ArrayList parents,
+		LogEntry entry,
+		int depth) {
+		if (depth + 1 > parents.size())
+			parents.add(entry);
+		else
+			parents.set(depth, entry);
+	}
+	
+	public static void reset() {
+		currentSession = null;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java
new file mode 100644
index 0000000..f4adc8c
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogSession.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+public class LogSession {
+	private String sessionData;
+	private Date date;
+
+	/**
+	 * Constructor for LogSession.
+	 */
+	public LogSession() {
+	}
+
+	public Date getDate() {
+		return date;
+	}
+	
+	public void setDate(String dateString) {
+		SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+		try {
+			date = formatter.parse(dateString);
+		} catch (ParseException e) {
+		}
+	}
+	
+	public String getSessionData() {
+		return sessionData;
+	}
+
+	void setSessionData(String data) {
+		this.sessionData = data;
+	}
+	
+	public void processLogLine(String line) {
+		StringTokenizer tokenizer = new StringTokenizer(line);
+		if (tokenizer.countTokens() == 6) {
+			tokenizer.nextToken();
+			StringBuffer dateBuffer = new StringBuffer();
+			for (int i = 0; i < 4; i++) {
+				dateBuffer.append(tokenizer.nextToken());
+				dateBuffer.append(" "); //$NON-NLS-1$
+			}
+			setDate(dateBuffer.toString().trim());
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java
new file mode 100644
index 0000000..10fae63
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogView.java
@@ -0,0 +1,999 @@
+/***********************************************************************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ **********************************************************************************************************************************/
+
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.text.Collator;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages;
+
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableLayout;
+//import org.eclipse.jface.viewers.TableTreeViewer;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+//import org.eclipse.swt.custom.TableTree;
+//import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+//import org.eclipse.swt.widgets.Table;
+//import org.eclipse.swt.widgets.TableColumn;
+//import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+//import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.part.ViewPart;
+
+public class LogView extends ViewPart implements ILogListener {
+  public final static String ID_LOGVIEW = "net.sourceforge.phpdt.internal.debug.core.logview.LogView"; //$NON-NLS-1$
+
+  //private TableTreeViewer tableTreeViewer;
+  private /*Table*/TreeViewer tableTreeViewer;
+
+  private ArrayList logs = new ArrayList();
+
+  public static final String P_LOG_WARNING = "warning"; //$NON-NLS-1$
+
+  public static final String P_LOG_ERROR = "error"; //$NON-NLS-1$
+
+  public static final String P_LOG_INFO = "info"; //$NON-NLS-1$
+
+  public static final String P_LOG_LIMIT = "limit"; //$NON-NLS-1$
+
+  public static final String P_USE_LIMIT = "useLimit"; //$NON-NLS-1$
+
+  public static final String P_SHOW_ALL_SESSIONS = "allSessions"; //$NON-NLS-1$
+
+  private static final String P_COLUMN_1 = "column1"; //$NON-NLS-1$
+
+  private static final String P_COLUMN_2 = "column2"; //$NON-NLS-1$
+
+  private static final String P_COLUMN_3 = "column3"; //$NON-NLS-1$
+
+  private static final String P_COLUMN_4 = "column4"; //$NON-NLS-1$
+
+  public static final String P_ACTIVATE = "activate"; //$NON-NLS-1$
+
+  private int MESSAGE_ORDER = -1;
+
+  private int PLUGIN_ORDER = -1;
+
+  private int DATE_ORDER = -1;
+
+  public static byte MESSAGE = 0x0;
+
+  public static byte PLUGIN = 0x1;
+
+  public static byte DATE = 0x2;
+
+  private static int ASCENDING = 1;
+
+  private static int DESCENDING = -1;
+
+  private Action clearAction;
+
+  private Action copyAction;
+
+  private Action readLogAction;
+
+  private Action deleteLogAction;
+
+  private Action exportAction;
+
+  private Action importAction;
+
+  private Action activateViewAction;
+
+  private Action propertiesAction;
+
+  private Action viewLogAction;
+
+  private Action filterAction;
+
+  private Clipboard clipboard;
+
+  private IMemento memento;
+
+  private File inputFile;
+
+  private String directory;
+
+  private /*Table*/TreeColumn column0;
+
+  private TreeColumn column1;
+
+  private TreeColumn column2;
+
+  private TreeColumn column3;
+
+  private TreeColumn column4;
+
+  private static Font boldFont;
+
+  private Comparator comparator;
+
+  private Collator collator;
+
+  // hover text
+  private boolean canOpenTextShell;
+
+  private Text textLabel;
+
+  private Shell textShell;
+
+  private boolean firstEvent = true;
+
+  public LogView() {
+    logs = new ArrayList();
+    inputFile = Platform.getLogFileLocation().toFile();
+  }
+
+  public void createPartControl(Composite parent) {
+    readLogFile();
+    /*Table*/Tree tableTree = new /*Table*/Tree(parent, SWT.FULL_SELECTION);
+    
+    tableTree.setLayoutData(new GridData(GridData.FILL_BOTH));
+    createColumns(tableTree/*get getColumns()*//*.get getTable()*/);
+    createViewer(tableTree);
+    createPopupMenuManager(tableTree);
+    makeActions(tableTree/*.getTable()*/);
+    fillToolBar();
+    Platform.addLogListener(this);
+    getSite().setSelectionProvider(tableTreeViewer);
+    clipboard = new Clipboard(tableTree.getDisplay());
+    tableTreeViewer.getTree().setToolTipText(""); // setToolTipText/* getTableTree().getTable()*/./*setToolTipText*/(""); //$NON-NLS-1$
+    initializeFonts();
+    applyFonts();
+  }
+
+  private void initializeFonts() {
+    Font tableFont = tableTreeViewer.getTree().getFont(); // getTableTree().getFont();
+    FontData[] fontDataList = tableFont.getFontData();
+    FontData fontData;
+    if (fontDataList.length > 0)
+      fontData = fontDataList[0];
+    else
+      fontData = new FontData();
+    fontData.setStyle(SWT.BOLD);
+    boldFont = new Font(tableTreeViewer.getTree()/*getTableTree()*/.getDisplay(), fontData);
+  }
+
+  /*
+   * Set all rows where the tableTreeItem has children to have a <b>bold </b> font.
+   */
+  private void applyFonts() {
+    if (tableTreeViewer == null || tableTreeViewer.getTree()/*getTableTree()*/.isDisposed())
+      return;
+    int max = tableTreeViewer.getTree().getItemCount();
+    int index = 0, tableIndex = 0;
+    while (index < max) {
+      LogEntry entry = null; //(LogEntry) tableTreeViewer.get getElementAt(index);
+      if (entry == null)
+        return;
+      if (entry.hasChildren()) {
+        tableTreeViewer.getTree()/*getTableTree()*/.getItems()[index].setFont(boldFont);
+        tableIndex = applyChildFonts(entry, tableIndex);
+      } else {
+        tableTreeViewer.getTree()/*getTableTree()*/.getItems()[index].setFont(tableTreeViewer.getTree()/*getTableTree()*/.getFont());
+      }
+      index++;
+      tableIndex++;
+    }
+  }
+
+  private int applyChildFonts(LogEntry parent, int index) {
+    if (!tableTreeViewer.getExpandedState(parent) || !parent.hasChildren())
+      return index;
+    LogEntry[] children = getEntryChildren(parent);
+    for (int i = 0; i < children.length; i++) {
+      index++;
+      if (children[i].hasChildren()) {
+        /*TableItem*/ TreeItem tableItem = getTableItem(index);
+        if (tableItem != null) {
+          tableItem.setFont(boldFont);
+        }
+        index = applyChildFonts(children[i], index);
+      } else {
+        /*TableItem*/ TreeItem tableItem = getTableItem(index);
+        if (tableItem != null) {
+          tableItem.setFont(tableTreeViewer.getTree()/*getTableTree()*/.getFont());
+        }
+      }
+    }
+    return index;
+  }
+
+  private LogEntry[] getEntryChildren(LogEntry parent) {
+    Object[] entryChildren = parent.getChildren(parent);
+    if (comparator != null)
+      Arrays.sort(entryChildren, comparator);
+    LogEntry[] children = new LogEntry[entryChildren.length];
+    System.arraycopy(entryChildren, 0, children, 0, entryChildren.length);
+    return children;
+  }
+
+  private TreeItem /*TableItem*/ getTableItem(int index) {
+    /*TableItem[]*/ TreeItem[] tableItems = tableTreeViewer.getTree().getItems(); // /*getTableTree()*/.getTable().getItems();
+    if (index > tableItems.length - 1)
+      return null;
+    return tableItems[index];
+  }
+
+  private void fillToolBar() {
+    IActionBars bars = getViewSite().getActionBars();
+    bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
+    IToolBarManager toolBarManager = bars.getToolBarManager();
+    toolBarManager.add(exportAction);
+    toolBarManager.add(importAction);
+    toolBarManager.add(new Separator());
+    toolBarManager.add(clearAction);
+    toolBarManager.add(deleteLogAction);
+    toolBarManager.add(viewLogAction);
+    toolBarManager.add(readLogAction);
+    toolBarManager.add(new Separator());
+    IMenuManager mgr = bars.getMenuManager();
+    mgr.add(filterAction);
+    mgr.add(new Separator());
+    mgr.add(activateViewAction);
+  }
+
+  private void createViewer(/*Table*/Tree tableTree) {
+    tableTreeViewer = new /*Table*/TreeViewer(tableTree);
+    tableTreeViewer.setContentProvider(new LogViewContentProvider(this));
+    tableTreeViewer.setLabelProvider(new LogViewLabelProvider());
+    tableTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+      public void selectionChanged(SelectionChangedEvent e) {
+        handleSelectionChanged(e.getSelection());
+        if (propertiesAction.isEnabled())
+          ((EventDetailsDialogAction) propertiesAction).resetSelection();
+      }
+    });
+    tableTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
+      public void doubleClick(DoubleClickEvent event) {
+        ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
+        propertiesAction.run();
+      }
+    });
+    tableTreeViewer.addTreeListener(new ITreeViewerListener() {
+      public void treeCollapsed(TreeExpansionEvent event) {
+        applyFonts();
+      }
+
+      public void treeExpanded(TreeExpansionEvent event) {
+        applyFonts();
+      }
+    });
+    addMouseListeners();
+    tableTreeViewer.setInput(Platform.class);
+  }
+
+  private void createPopupMenuManager(/*Table*/Tree tableTree) {
+    MenuManager popupMenuManager = new MenuManager();
+    IMenuListener listener = new IMenuListener() {
+      public void menuAboutToShow(IMenuManager mng) {
+        fillContextMenu(mng);
+      }
+    };
+    popupMenuManager.addMenuListener(listener);
+    popupMenuManager.setRemoveAllWhenShown(true);
+    Menu menu = popupMenuManager.createContextMenu(tableTree);
+    tableTree.setMenu(menu);
+  }
+
+  private void createColumns(/*Table*/ Tree table) {
+    column0 = new TreeColumn(table, SWT.NULL);
+    column0.setText(""); //$NON-NLS-1$
+    column1 = new TreeColumn(table, SWT.NULL);
+    column1.setText(XDebugUIPlugin.getString("LogView.column.severity")); //$NON-NLS-1$
+    column2 = new TreeColumn(table, SWT.NULL);
+    column2.setText(XDebugUIPlugin.getString("LogView.column.message")); //$NON-NLS-1$
+    column2.addSelectionListener(new SelectionAdapter() {
+      public void widgetSelected(SelectionEvent e) {
+        MESSAGE_ORDER *= -1;
+        ViewerSorter sorter = getViewerSorter(MESSAGE);
+        tableTreeViewer.setSorter(sorter);
+        collator = sorter.getCollator();
+        boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(MESSAGE, MESSAGE_ORDER);
+        setComparator(MESSAGE);
+        if (!isComparatorSet)
+          ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
+        applyFonts();
+      }
+    });
+    column3 = new TreeColumn(table, SWT.NULL);
+    column3.setText(XDebugUIPlugin.getString("LogView.column.plugin"));  //$NON-NLS-1$
+    column3.addSelectionListener(new SelectionAdapter() {
+      public void widgetSelected(SelectionEvent e) {
+        PLUGIN_ORDER *= -1;
+        ViewerSorter sorter = getViewerSorter(PLUGIN);
+        tableTreeViewer.setSorter(sorter);
+        collator = sorter.getCollator();
+        boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(PLUGIN, PLUGIN_ORDER);
+        setComparator(PLUGIN);
+        if (!isComparatorSet)
+          ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
+        applyFonts();
+      }
+    });
+    column4 = new TreeColumn(table, SWT.NULL);
+    column4.setText(XDebugUIPlugin.getString("LogView.column.date")); //$NON-NLS-1$
+    column4.addSelectionListener(new SelectionAdapter() {
+      public void widgetSelected(SelectionEvent e) {
+        if (DATE_ORDER == ASCENDING) {
+          DATE_ORDER = DESCENDING;
+        } else {
+          DATE_ORDER = ASCENDING;
+        }
+        ViewerSorter sorter = getViewerSorter(DATE);
+        tableTreeViewer.setSorter(sorter);
+        collator = sorter.getCollator();
+        boolean isComparatorSet = ((EventDetailsDialogAction) propertiesAction).resetSelection(DATE, DATE_ORDER);
+        setComparator(DATE);
+        if (!isComparatorSet)
+          ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
+        applyFonts();
+      }
+    });
+    TableLayout tlayout = new TableLayout();
+    tlayout.addColumnData(new ColumnPixelData(21));
+    tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_1).intValue()));
+    tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_2).intValue()));
+    tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_3).intValue()));
+    tlayout.addColumnData(new ColumnPixelData(memento.getInteger(P_COLUMN_4).intValue()));
+    table.setLayout(tlayout);
+    table.setHeaderVisible(true);
+  }
+
+  private void makeActions(/*Table*/Tree table) {
+    propertiesAction = new EventDetailsDialogAction(table.getShell(), tableTreeViewer);
+    propertiesAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES));
+    propertiesAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_PROPERTIES));
+    propertiesAction.setToolTipText(XDebugUIPlugin.getString("LogView.properties.tooltip")); //$NON-NLS-1$
+    propertiesAction.setEnabled(false);
+    clearAction = new Action(XDebugUIPlugin.getString("LogView.clear")) { //$NON-NLS-1$
+      public void run() {
+        handleClear();
+      }
+    };
+    clearAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR));
+    clearAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_CLEAR));
+    clearAction.setToolTipText(XDebugUIPlugin.getString("LogView.clear.tooltip")); //$NON-NLS-1$
+    clearAction.setText(XDebugUIPlugin.getString("LogView.clear")); //$NON-NLS-1$
+    readLogAction = new Action(XDebugUIPlugin.getString("LogView.readLog.restore")) { //$NON-NLS-1$
+      public void run() {
+        inputFile = Platform.getLogFileLocation().toFile();
+        reloadLog();
+      }
+    };
+    readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore.tooltip")); //$NON-NLS-1$
+    readLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG));
+    readLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_READ_LOG));
+    deleteLogAction = new Action(XDebugUIPlugin.getString("LogView.delete")) { //$NON-NLS-1$
+      public void run() {
+        doDeleteLog();
+      }
+    };
+    deleteLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.delete.tooltip")); //$NON-NLS-1$
+    deleteLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG));
+    deleteLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_REMOVE_LOG));
+    deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
+    copyAction = new Action(XDebugUIPlugin.getString("LogView.copy")) { //$NON-NLS-1$
+      public void run() {
+        copyToClipboard(tableTreeViewer.getSelection());
+      }
+    };
+    copyAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
+    filterAction = new Action(XDebugUIPlugin.getString("LogView.filter")) { //$NON-NLS-1$
+      public void run() {
+        handleFilter();
+      }
+    };
+    filterAction.setToolTipText(XDebugUIPlugin.getString("LogView.filter")); //$NON-NLS-1$
+    filterAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER));
+    filterAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_FILTER));
+    exportAction = new Action(XDebugUIPlugin.getString("LogView.export")) { //$NON-NLS-1$
+      public void run() {
+        handleExport();
+      }
+    };
+    exportAction.setToolTipText(XDebugUIPlugin.getString("LogView.export.tooltip")); //$NON-NLS-1$
+    exportAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT));
+    exportAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_EXPORT));
+    importAction = new Action(XDebugUIPlugin.getString("LogView.import")) { //$NON-NLS-1$
+      public void run() {
+        handleImport();
+      }
+    };
+    importAction.setToolTipText(XDebugUIPlugin.getString("LogView.import.tooltip")); //$NON-NLS-1$
+    importAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT));
+    importAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_IMPORT));
+    activateViewAction = new Action(XDebugUIPlugin.getString("LogView.activate")) { //$NON-NLS-1$
+      public void run() {
+      }
+    };
+    activateViewAction.setChecked(memento.getString(P_ACTIVATE).equals("true")); //$NON-NLS-1$
+    viewLogAction = new Action(XDebugUIPlugin.getString("LogView.view.currentLog")) { //$NON-NLS-1$
+      public void run() {
+        if (inputFile.exists()) {
+          if (inputFile.length() > LogReader.MAX_FILE_LENGTH) {
+            OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile);
+            openDialog.create();
+            openDialog.open();
+          } else {
+            boolean canLaunch = Program.launch(inputFile.getAbsolutePath());
+            if (!canLaunch) {
+              Program p = Program.findProgram(".txt"); //$NON-NLS-1$
+              if (p != null)
+                p.execute(inputFile.getAbsolutePath());
+              else {
+                OpenLogDialog openDialog = new OpenLogDialog(getViewSite().getShell(), inputFile);
+                openDialog.create();
+                openDialog.open();
+              }
+            }
+          }
+        }
+      }
+    };
+    viewLogAction.setImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG));
+    viewLogAction.setDisabledImageDescriptor(XDebugUIPluginImages.getImageDescriptor(XDebugUIPluginImages.IMG_OPEN_LOG));
+    viewLogAction.setEnabled(inputFile.exists());
+    viewLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.view.currentLog.tooltip")); //$NON-NLS-1$
+  }
+
+  public void dispose() {
+    Platform.removeLogListener(this);
+    clipboard.dispose();
+    LogReader.reset();
+    boldFont.dispose();
+    super.dispose();
+  }
+
+  private void handleImport() {
+    FileDialog dialog = new FileDialog(getViewSite().getShell());
+    dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
+    if (directory != null)
+      dialog.setFilterPath(directory);
+    String path = dialog.open();
+    if (path != null && new Path(path).toFile().exists()) {
+      inputFile = new Path(path).toFile();
+      directory = inputFile.getParent();
+      IRunnableWithProgress op = new IRunnableWithProgress() {
+        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+          monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.importing"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+          readLogFile();
+        }
+      };
+      ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
+      try {
+        pmd.run(true, true, op);
+      } catch (InvocationTargetException e) {
+      } catch (InterruptedException e) {
+      } finally {
+        readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$
+        readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.reload")); //$NON-NLS-1$
+        asyncRefresh(false);
+        resetDialogButtons();
+      }
+    }
+  }
+
+  private void handleExport() {
+    FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE);
+    dialog.setFilterExtensions(new String[] { "*.log" }); //$NON-NLS-1$
+    if (directory != null)
+      dialog.setFilterPath(directory);
+    String path = dialog.open();
+    if (path != null) {
+      if (!path.endsWith(".log")) //$NON-NLS-1$
+        path += ".log"; //$NON-NLS-1$
+      File outputFile = new Path(path).toFile();
+      directory = outputFile.getParent();
+      if (outputFile.exists()) {
+    	  String message = "LogView.confirmOverwrite.message";
+//        String message = PHPDebugUIPlugin.getFormattedMessage("LogView.confirmOverwrite.message", //$NON-NLS-1$
+//            outputFile.toString());
+        if (!MessageDialog.openQuestion(getViewSite().getShell(), exportAction.getText(), message))
+          return;
+      }
+      copy(inputFile, outputFile);
+    }
+  }
+
+  private void copy(File inputFile, File outputFile) {
+    BufferedReader reader = null;
+    BufferedWriter writer = null;
+    try {
+      reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8")); //$NON-NLS-1$
+      writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); //$NON-NLS-1$
+      while (reader.ready()) {
+        writer.write(reader.readLine());
+        writer.write(System.getProperty("line.separator")); //$NON-NLS-1$
+      }
+    } catch (IOException e) {
+    } finally {
+      try {
+        if (reader != null)
+          reader.close();
+        if (writer != null)
+          writer.close();
+      } catch (IOException e1) {
+      }
+    }
+  }
+
+  private void handleFilter() {
+    FilterDialog dialog = new FilterDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), memento);
+    dialog.create();
+    dialog.getShell().setText(XDebugUIPlugin.getString("LogView.FilterDialog.title")); //$NON-NLS-1$
+    if (dialog.open() == FilterDialog.OK)
+      reloadLog();
+  }
+
+  private void doDeleteLog() {
+    String title = XDebugUIPlugin.getString("LogView.confirmDelete.title"); //$NON-NLS-1$
+    String message = XDebugUIPlugin.getString("LogView.confirmDelete.message"); //$NON-NLS-1$
+    if (!MessageDialog.openConfirm(tableTreeViewer.getControl().getShell(), title, message))
+      return;
+    if (inputFile.delete()) {
+      logs.clear();
+      asyncRefresh(false);
+      resetDialogButtons();
+    }
+  }
+
+  public void fillContextMenu(IMenuManager manager) {
+    manager.add(copyAction);
+    manager.add(new Separator());
+    manager.add(clearAction);
+    manager.add(deleteLogAction);
+    manager.add(viewLogAction);
+    manager.add(readLogAction);
+    manager.add(new Separator());
+    manager.add(exportAction);
+    manager.add(importAction);
+    manager.add(new Separator());
+    ((EventDetailsDialogAction) propertiesAction).setComparator(comparator);
+    manager.add(propertiesAction);
+  }
+
+  public LogEntry[] getLogs() {
+    return (LogEntry[]) logs.toArray(new LogEntry[logs.size()]);
+  }
+
+  protected void handleClear() {
+    BusyIndicator.showWhile(tableTreeViewer.getControl().getDisplay(), new Runnable() {
+      public void run() {
+        logs.clear();
+        asyncRefresh(false);
+        resetDialogButtons();
+      }
+    });
+  }
+
+  protected void reloadLog() {
+    IRunnableWithProgress op = new IRunnableWithProgress() {
+      public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+        monitor.beginTask(XDebugUIPlugin.getString("LogView.operation.reloading"), //$NON-NLS-1$
+            IProgressMonitor.UNKNOWN);
+        readLogFile();
+      }
+    };
+    ProgressMonitorDialog pmd = new ProgressMonitorDialog(getViewSite().getShell());
+    try {
+      pmd.run(true, true, op);
+    } catch (InvocationTargetException e) {
+    } catch (InterruptedException e) {
+    } finally {
+      readLogAction.setText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$
+      readLogAction.setToolTipText(XDebugUIPlugin.getString("LogView.readLog.restore")); //$NON-NLS-1$
+      asyncRefresh(false);
+      resetDialogButtons();
+    }
+  }
+
+  private void readLogFile() {
+    logs.clear();
+    if (!inputFile.exists())
+      return;
+    if (inputFile.length() > LogReader.MAX_FILE_LENGTH)
+      LogReader.parseLargeFile(inputFile, logs, memento);
+    else
+      LogReader.parseLogFile(inputFile, logs, memento);
+  }
+
+  public void logging(IStatus status, String plugin) { 
+    if (!inputFile.equals(Platform.getLogFileLocation().toFile()))
+      return;
+    if (firstEvent) {
+      readLogFile();
+      asyncRefresh();
+      firstEvent = false;
+    } else {
+      pushStatus(status);
+    }
+  }
+
+  private void pushStatus(IStatus status) {
+      LogEntry entry = new LogEntry(status);
+      LogReader.addEntry(entry, logs, memento, true);
+      asyncRefresh();
+  }
+
+  private void asyncRefresh() {
+    asyncRefresh(true);
+  }
+
+  private void asyncRefresh(final boolean activate) {
+    final Control control = tableTreeViewer.getControl();
+    if (control.isDisposed())
+      return;
+    Display display = control.getDisplay();
+    final ViewPart view = this;
+    if (display != null) {
+      display.asyncExec(new Runnable() {
+        public void run() {
+          if (!control.isDisposed()) {
+            tableTreeViewer.refresh();
+            deleteLogAction.setEnabled(inputFile.exists() && inputFile.equals(Platform.getLogFileLocation().toFile()));
+            viewLogAction.setEnabled(inputFile.exists());
+            if (activate && activateViewAction.isChecked()) {
+              //IWorkbenchPage page = XDebugCorePlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+            	IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+              if (page != null)
+                page.bringToTop(view);
+            }
+          }
+          applyFonts();
+        }
+      });
+    }
+  }
+
+  public void setFocus() {
+    if (tableTreeViewer != null && !tableTreeViewer.getTree()/*getTableTree()*/.isDisposed())
+      tableTreeViewer.getTree().setFocus(); ///*getTableTree()*/.getTable().setFocus();
+  }
+
+  private void handleSelectionChanged(ISelection selection) {
+    updateStatus(selection);
+    copyAction.setEnabled(!selection.isEmpty());
+    propertiesAction.setEnabled(!selection.isEmpty());
+  }
+
+  private void updateStatus(ISelection selection) {
+    IStatusLineManager status = getViewSite().getActionBars().getStatusLineManager();
+    if (selection.isEmpty())
+      status.setMessage(null);
+    else {
+      LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
+      status.setMessage(((LogViewLabelProvider) tableTreeViewer.getLabelProvider()).getColumnText(entry, 2));
+    }
+  }
+
+  private void copyToClipboard(ISelection selection) {
+    StringWriter writer = new StringWriter();
+    PrintWriter pwriter = new PrintWriter(writer);
+    if (selection.isEmpty())
+      return;
+    LogEntry entry = (LogEntry) ((IStructuredSelection) selection).getFirstElement();
+    entry.write(pwriter);
+    pwriter.flush();
+    String textVersion = writer.toString();
+    try {
+      pwriter.close();
+      writer.close();
+    } catch (IOException e) {
+    }
+    if (textVersion.trim().length() > 0) {
+      // set the clipboard contents
+      clipboard.setContents(new Object[] { textVersion }, new Transfer[] { TextTransfer.getInstance() });
+    }
+  }
+
+  public void init(IViewSite site, IMemento memento) throws PartInitException {
+    super.init(site, memento);
+    if (memento == null)
+      this.memento = XMLMemento.createWriteRoot("LOGVIEW"); //$NON-NLS-1$
+    else
+      this.memento = memento;
+    initializeMemento();
+  }
+
+  private void initializeMemento() {
+    if (memento.getString(P_USE_LIMIT) == null)
+      memento.putString(P_USE_LIMIT, "true"); //$NON-NLS-1$
+    if (memento.getInteger(P_LOG_LIMIT) == null)
+      memento.putInteger(P_LOG_LIMIT, 50);
+    if (memento.getString(P_LOG_INFO) == null)
+      memento.putString(P_LOG_INFO, "true"); //$NON-NLS-1$
+    if (memento.getString(P_LOG_WARNING) == null)
+      memento.putString(P_LOG_WARNING, "true"); //$NON-NLS-1$
+    if (memento.getString(P_LOG_ERROR) == null)
+      memento.putString(P_LOG_ERROR, "true"); //$NON-NLS-1$
+    if (memento.getString(P_SHOW_ALL_SESSIONS) == null)
+      memento.putString(P_SHOW_ALL_SESSIONS, "true"); //$NON-NLS-1$
+    Integer width = memento.getInteger(P_COLUMN_1);
+    if (width == null || width.intValue() == 0)
+      memento.putInteger(P_COLUMN_1, 20);
+    width = memento.getInteger(P_COLUMN_2);
+    if (width == null || width.intValue() == 0)
+      memento.putInteger(P_COLUMN_2, 300);
+    width = memento.getInteger(P_COLUMN_3);
+    if (width == null || width.intValue() == 0)
+      memento.putInteger(P_COLUMN_3, 150);
+    width = memento.getInteger(P_COLUMN_4);
+    if (width == null || width.intValue() == 0)
+      memento.putInteger(P_COLUMN_4, 150);
+    if (memento.getString(P_ACTIVATE) == null)
+      memento.putString(P_ACTIVATE, "true"); //$NON-NLS-1$
+  }
+
+  public void saveState(IMemento memento) {
+    if (this.memento == null || memento == null)
+      return;
+    this.memento.putInteger(P_COLUMN_1, column1.getWidth());
+    this.memento.putInteger(P_COLUMN_2, column2.getWidth());
+    this.memento.putInteger(P_COLUMN_3, column3.getWidth());
+    this.memento.putInteger(P_COLUMN_4, column4.getWidth());
+    this.memento.putString(P_ACTIVATE, activateViewAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+    memento.putMemento(this.memento);
+  }
+
+  private void addMouseListeners() {
+    Listener tableListener = new Listener() {
+      public void handleEvent(Event e) {
+        switch (e.type) {
+        case SWT.MouseMove:
+          onMouseMove(e);
+          break;
+        case SWT.MouseHover:
+          onMouseHover(e);
+          break;
+        case SWT.MouseDown:
+          onMouseDown(e);
+          break;
+        }
+      }
+    };
+    int[] tableEvents = new int[] { SWT.MouseDown, SWT.MouseMove, SWT.MouseHover };
+    for (int i = 0; i < tableEvents.length; i++) {
+      tableTreeViewer.getTree().addListener(tableEvents[i], tableListener);
+    }
+  }
+
+  private void makeHoverShell() {
+    Control control = tableTreeViewer.getControl();
+    textShell = new Shell(control.getShell(), SWT.NO_FOCUS | SWT.ON_TOP);
+    Display display = textShell.getDisplay();
+    textShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+    GridLayout layout = new GridLayout(1, false);
+    int border = ((control.getShell().getStyle() & SWT.NO_TRIM) == 0) ? 0 : 1;
+    layout.marginHeight = border;
+    layout.marginWidth = border;
+    textShell.setLayout(layout);
+    textShell.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    Composite shellComposite = new Composite(textShell, SWT.NONE);
+    layout = new GridLayout();
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    shellComposite.setLayout(layout);
+    shellComposite.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING));
+    textLabel = new Text(shellComposite, SWT.WRAP | SWT.MULTI);
+    GridData gd = new GridData(GridData.FILL_BOTH);
+    gd.widthHint = 100;
+    gd.grabExcessHorizontalSpace = true;
+    textLabel.setLayoutData(gd);
+    Color c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND);
+    textLabel.setBackground(c);
+    c = control.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND);
+    textLabel.setForeground(c);
+    textLabel.setEditable(false);
+    textShell.addDisposeListener(new DisposeListener() {
+      public void widgetDisposed(DisposeEvent e) {
+        onTextShellDispose(e);
+      }
+    });
+  }
+
+  void onTextShellDispose(DisposeEvent e) {
+    canOpenTextShell = true;
+    setFocus();
+  }
+
+  void onMouseDown(Event e) {
+    if (textShell != null && !textShell.isDisposed() && !textShell.isFocusControl()) {
+      textShell.close();
+      canOpenTextShell = true;
+    }
+  }
+
+  void onMouseHover(Event e) {
+    if (!canOpenTextShell)
+      return;
+    canOpenTextShell = false;
+    Point point = new Point(e.x, e.y);
+    /*Table*/Tree table = tableTreeViewer.getTree()/*getTableTree()*/;
+    /*Table*/TreeItem item = table.getItem(point);
+    if (item == null)
+      return;
+    String message = ((LogEntry) item.getData()).getStack();
+    if (message == null)
+      return;
+    makeHoverShell();
+    textLabel.setText(message);
+    int x = point.x + 5;
+    int y = point.y - (table.getItemHeight() * 2) - 20;
+    textShell.setLocation(table.toDisplay(x, y));
+    textShell.setSize(tableTreeViewer.getTree()/*getTableTree()*/.getSize().x - x, 125);
+    textShell.open();
+    setFocus();
+  }
+
+  void onMouseMove(Event e) {
+    if (textShell != null && !textShell.isDisposed()) {
+      textShell.close();
+      canOpenTextShell = textShell.isDisposed() && e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
+    } else {
+      canOpenTextShell = e.x > column0.getWidth() && e.x < (column0.getWidth() + column1.getWidth());
+    }
+  }
+
+  public Comparator getComparator() {
+    return comparator;
+  }
+
+  private void setComparator(byte sortType) {
+    if (sortType == DATE) {
+      comparator = new Comparator() {
+        public int compare(Object e1, Object e2) {
+          try {
+            SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+            Date date1 = formatter.parse(((LogEntry) e1).getDate());
+            Date date2 = formatter.parse(((LogEntry) e2).getDate());
+            if (DATE_ORDER == ASCENDING)
+              return date1.before(date2) ? -1 : 1;
+            return date1.after(date2) ? -1 : 1;
+          } catch (ParseException e) {
+          }
+          return 0;
+        }
+      };
+    } else if (sortType == PLUGIN) {
+      comparator = new Comparator() {
+        public int compare(Object e1, Object e2) {
+          LogEntry entry1 = (LogEntry) e1;
+          LogEntry entry2 = (LogEntry) e2;
+          return collator.compare(entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
+        }
+      };
+    } else {
+      comparator = new Comparator() {
+        public int compare(Object e1, Object e2) {
+          LogEntry entry1 = (LogEntry) e1;
+          LogEntry entry2 = (LogEntry) e2;
+          return collator.compare(entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
+        }
+      };
+    }
+  }
+
+  private ViewerSorter getViewerSorter(byte sortType) {
+    if (sortType == PLUGIN) {
+      return new ViewerSorter() {
+        public int compare(Viewer viewer, Object e1, Object e2) {
+          LogEntry entry1 = (LogEntry) e1;
+          LogEntry entry2 = (LogEntry) e2;
+          return super.compare(viewer, entry1.getPluginId(), entry2.getPluginId()) * PLUGIN_ORDER;
+        }
+      };
+    } else if (sortType == MESSAGE) {
+      return new ViewerSorter() {
+        public int compare(Viewer viewer, Object e1, Object e2) {
+          LogEntry entry1 = (LogEntry) e1;
+          LogEntry entry2 = (LogEntry) e2;
+          return super.compare(viewer, entry1.getMessage(), entry2.getMessage()) * MESSAGE_ORDER;
+        }
+      };
+    } else {
+      return new ViewerSorter() {
+        public int compare(Viewer viewer, Object e1, Object e2) {
+          try {
+            SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss.SS"); //$NON-NLS-1$
+            Date date1 = formatter.parse(((LogEntry) e1).getDate());
+            Date date2 = formatter.parse(((LogEntry) e2).getDate());
+            if (DATE_ORDER == ASCENDING)
+              return date1.before(date2) ? -1 : 1;
+            return date1.after(date2) ? -1 : 1;
+          } catch (ParseException e) {
+          }
+          return 0;
+        }
+      };
+    }
+  }
+
+  private void resetDialogButtons() {
+    ((EventDetailsDialogAction) propertiesAction).resetDialogButtons();
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java
new file mode 100644
index 0000000..3a12f46
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewContentProvider.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class LogViewContentProvider
+	implements ITreeContentProvider, IStructuredContentProvider {
+	private LogView logView;
+
+	public LogViewContentProvider(LogView logView) {
+		this.logView = logView;
+	}
+	public void dispose() {
+	}
+	public Object[] getChildren(Object element) {
+		return ((LogEntry) element).getChildren(element);
+	}
+	public Object[] getElements(Object element) {
+		return logView.getLogs();
+	}
+	public Object getParent(Object element) {
+		return ((LogEntry) element).getParent(element);
+	}
+	public boolean hasChildren(Object element) {
+		return ((LogEntry) element).hasChildren();
+	}
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	}
+	public boolean isDeleted(Object element) {
+		return false;
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java
new file mode 100644
index 0000000..2cc65c3
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/LogViewLabelProvider.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPluginImages;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+public class LogViewLabelProvider
+	extends LabelProvider
+	implements ITableLabelProvider {
+	private Image infoImage;
+	private Image errorImage;
+	private Image warningImage;
+	private Image errorWithStackImage;
+
+	public LogViewLabelProvider() {
+		errorImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_ERROR_ST_OBJ);
+		warningImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_WARNING_ST_OBJ);
+		infoImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_INFO_ST_OBJ);
+		errorWithStackImage = XDebugUIPluginImages.get(XDebugUIPluginImages.IMG_ERROR_STACK_OBJ);
+	}
+	public void dispose() {
+		errorImage.dispose();
+		infoImage.dispose();
+		warningImage.dispose();
+		errorWithStackImage.dispose();
+		super.dispose();
+	}
+	public Image getColumnImage(Object element, int columnIndex) {
+		LogEntry entry = (LogEntry) element;
+		if (columnIndex == 1) {
+			switch (entry.getSeverity()) {
+				case IStatus.INFO :
+					return infoImage;
+				case IStatus.WARNING :
+					return warningImage;
+				case IStatus.ERROR :
+					return (entry.getStack() == null ? errorImage : errorWithStackImage);
+			}
+		}
+		return null;
+	}
+	
+	public String getColumnText(Object element, int columnIndex) {
+		LogEntry entry = (LogEntry) element;
+		switch (columnIndex) {
+			case 2 :
+				return entry.getMessage();
+			case 3 :
+				return entry.getPluginId();
+			case 4 :
+				return entry.getDate();
+		}
+		return ""; //$NON-NLS-1$
+	}
+}
diff --git a/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java
new file mode 100644
index 0000000..4ebef63
--- /dev/null
+++ b/net.sourceforge.phpeclipse.xdebug.ui/src/net/sourceforge/phpeclipse/xdebug/ui/views/logview/OpenLogDialog.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+
+//import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
+import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Displays the error log in non-Win32 platforms - see bug 55314.
+ */
+public final class OpenLogDialog extends Dialog {
+    // input log file
+    private File logFile;
+    // location/size configuration
+    private IDialogSettings dialogSettings;
+    private Point dialogLocation;
+    private Point dialogSize;
+    private int DEFAULT_WIDTH = 750;
+    private int DEFAULT_HEIGHT = 800;
+
+    public OpenLogDialog(Shell parentShell, File logFile) {
+        super(parentShell);
+        this.logFile = logFile;
+        setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN | SWT.MODELESS);
+
+    }
+
+    /*
+     * (non-Javadoc) Method declared on Window.
+     */
+    protected void configureShell(Shell newShell) {
+        super.configureShell(newShell);
+        newShell.setText(XDebugUIPlugin.getString("OpenLogDialog.title")); //$NON-NLS-1$
+        readConfiguration();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on Dialog.
+     */
+    protected void createButtonsForButtonBar(Composite parent) {
+        createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL,
+                true);
+    }
+
+    public void create() {
+        super.create();
+        // dialog location
+        if (dialogLocation != null)
+            getShell().setLocation(dialogLocation);
+        // dialog size
+        if (dialogSize != null)
+            getShell().setSize(dialogSize);
+        else
+            getShell().setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+        getButton(IDialogConstants.CLOSE_ID).setFocus();
+    }
+
+    /*
+     * (non-Javadoc) Method declared on Dialog.
+     */
+    protected Control createDialogArea(Composite parent) {
+        Composite outer = (Composite) super.createDialogArea(parent);
+        Text text = new Text(outer, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL
+                | SWT.NO_FOCUS | SWT.H_SCROLL);
+        text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+        GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+                | GridData.VERTICAL_ALIGN_FILL);
+        gridData.grabExcessVerticalSpace = true;
+        gridData.grabExcessHorizontalSpace = true;
+        text.setLayoutData(gridData);
+        text.setText(getLogSummary());
+        return outer;
+    }
+
+    private String getLogSummary() {
+        StringWriter out = new StringWriter();
+        PrintWriter writer = new PrintWriter(out);
+        if (logFile.length() > LogReader.MAX_FILE_LENGTH) {
+            readLargeFileWithMonitor(writer);
+        } else {
+            readFileWithMonitor(writer);
+        }
+        writer.close();
+        return out.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+     */
+    protected void buttonPressed(int buttonId) {
+        if (buttonId == IDialogConstants.CLOSE_ID) {
+            storeSettings();
+            close();
+        }
+        super.buttonPressed(buttonId);
+    }
+
+    //--------------- configuration handling --------------
+    /**
+     * Stores the current state in the dialog settings.
+     * 
+     * @since 2.0
+     */
+    private void storeSettings() {
+        writeConfiguration();
+    }
+
+    /**
+     * Returns the dialog settings object used to share state between several
+     * event detail dialogs.
+     * 
+     * @return the dialog settings to be used
+     */
+    private IDialogSettings getDialogSettings() {
+//        IDialogSettings settings = XDebugCorePlugin.getDefault().getDialogSettings();
+        IDialogSettings settings = getDialogSettings();
+        dialogSettings = settings.getSection(getClass().getName());
+        if (dialogSettings == null)
+            dialogSettings = settings.addNewSection(getClass().getName());
+        return dialogSettings;
+    }
+
+    /**
+     * Initializes itself from the dialog settings with the same state as at the
+     * previous invocation.
+     */
+    private void readConfiguration() {
+        IDialogSettings s = getDialogSettings();
+        try {
+            int x = s.getInt("x"); //$NON-NLS-1$
+            int y = s.getInt("y"); //$NON-NLS-1$
+            dialogLocation = new Point(x, y);
+            x = s.getInt("width"); //$NON-NLS-1$
+            y = s.getInt("height"); //$NON-NLS-1$
+            dialogSize = new Point(x, y);
+        } catch (NumberFormatException e) {
+            dialogLocation = null;
+            dialogSize = null;
+        }
+    }
+
+    private void writeConfiguration() {
+        IDialogSettings s = getDialogSettings();
+        Point location = getShell().getLocation();
+        s.put("x", location.x); //$NON-NLS-1$
+        s.put("y", location.y); //$NON-NLS-1$
+        Point size = getShell().getSize();
+        s.put("width", size.x); //$NON-NLS-1$
+        s.put("height", size.y); //$NON-NLS-1$
+    }
+
+    // reading file within MAX_FILE_LENGTH size
+    private void readFile(PrintWriter writer) throws FileNotFoundException, IOException {
+        BufferedReader bReader = new BufferedReader(new FileReader(logFile));
+        while (bReader.ready())
+            writer.println(bReader.readLine());
+    }
+
+    // reading large files
+    private void readLargeFile(PrintWriter writer) throws FileNotFoundException,
+            IOException {
+        RandomAccessFile random = null;
+        boolean hasStarted = false;
+        try {
+            random = new RandomAccessFile(logFile, "r"); //$NON-NLS-1$
+            random.seek(logFile.length() - LogReader.MAX_FILE_LENGTH);
+            for (;;) {
+                String line = random.readLine();
+                if (line == null)
+                    break;
+                line = line.trim();
+                if (line.length() == 0)
+                    continue;
+                if (!hasStarted
+                        && (line.startsWith("!ENTRY") || line.startsWith("!SESSION"))) //$NON-NLS-1$ //$NON-NLS-2$
+                    hasStarted = true;
+                if (hasStarted)
+                    writer.println(line);
+                continue;
+            }
+        } finally {
+            try {
+                if (random != null)
+                    random.close();
+            } catch (IOException e1) {
+            }
+        }
+    }
+
+    private void readLargeFileWithMonitor(final PrintWriter writer) {
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+            public void run(IProgressMonitor monitor) throws InvocationTargetException,
+                    InterruptedException {
+                monitor
+                        .beginTask(
+                                XDebugUIPlugin.getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+                try {
+                    readLargeFile(writer);
+                } catch (IOException e) {
+                    writer.println(XDebugUIPlugin.getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$
+                }
+            }
+        };
+        ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell());
+        try {
+            dialog.run(true, true, runnable);
+        } catch (InvocationTargetException e) {
+        } catch (InterruptedException e) {
+        }
+    }
+
+    private void readFileWithMonitor(final PrintWriter writer) {
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+            public void run(IProgressMonitor monitor) throws InvocationTargetException,
+                    InterruptedException {
+                monitor
+                        .beginTask(
+                                XDebugUIPlugin
+                                        .getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+                try {
+                    readFile(writer);
+                } catch (IOException e) {
+                    writer.println(XDebugUIPlugin
+                            .getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$
+                }
+            }
+        };
+        ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell());
+        try {
+            dialog.run(true, true, runnable);
+        } catch (InvocationTargetException e) {
+        } catch (InterruptedException e) {
+        }
+    }
+}