From 3f0ba2aad4f1724cccfedefa79330e7ab46158e3 Mon Sep 17 00:00:00 2001
From: axelcl <axelcl>
Date: Mon, 13 Dec 2004 20:22:00 +0000
Subject: [PATCH] Added filters to the PHp OutlinePage

---
 net.sourceforge.phpeclipse/plugin.properties       |    4 +
 net.sourceforge.phpeclipse/plugin.xml              |   26 +-
 .../sourceforge/phpdt/internal/ui/PHPUiImages.java |    4 +
 .../phpdt/internal/ui/filters/ClassFilter.java     |   39 +
 .../internal/ui/filters/ClosedProjectFilter.java   |   36 +
 .../internal/ui/filters/CustomFiltersDialog.java   |  420 +++++++++++
 .../phpdt/internal/ui/filters/FieldsFilter.java    |   25 +
 .../internal/ui/filters/FilterDescriptor.java      |  278 ++++++++
 .../phpdt/internal/ui/filters/FilterMessages.java  |   64 ++
 .../internal/ui/filters/FilterMessages.properties  |   24 +
 .../ui/filters/ImportDeclarationFilter.java        |   32 +
 .../phpdt/internal/ui/filters/InterfaceFilter.java |   39 +
 .../phpdt/internal/ui/filters/JavaFileFilter.java  |   46 ++
 .../internal/ui/filters/NamePatternFilter.java     |   98 +++
 .../internal/ui/filters/NonJavaElementFilter.java  |   50 ++
 .../internal/ui/filters/NonJavaProjectsFilter.java |   37 +
 .../phpdt/internal/ui/filters/NonPublicFilter.java |   25 +
 .../internal/ui/filters/NonPublicTypeFilter.java   |   41 ++
 .../ui/filters/NonSharedProjectFilter.java         |   47 ++
 .../internal/ui/filters/OutputFolderFilter.java    |   77 ++
 .../phpdt/internal/ui/filters/StaticsFilter.java   |   25 +
 .../phpdt/ui/actions/CustomFiltersActionGroup.java |  733 ++++++++++++++++++++
 .../phpeclipse/phpeditor/JavaOutlinePage.java      |   53 +--
 23 files changed, 2179 insertions(+), 44 deletions(-)
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java
 create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java

diff --git a/net.sourceforge.phpeclipse/plugin.properties b/net.sourceforge.phpeclipse/plugin.properties
index 7cddd75..83a4ccf 100644
--- a/net.sourceforge.phpeclipse/plugin.properties
+++ b/net.sourceforge.phpeclipse/plugin.properties
@@ -4,6 +4,7 @@
 pluginName=PHPEclipse Tools Core
 providerName=phpeclipse.de
 naturePHP.name=PHP Project
+elementFiltersName=PHPElement Filters
 phpProblemName=PHP Problem
 transientPHPProblemName=Transient PHP Problem
 phpTaskName=PHP Task
@@ -405,6 +406,9 @@ OccurrenceAnnotation.label= PHP Marker Occurrences
 
 phpEditorFontDefiniton.label= Java Editor Text Font
 phpEditorFontDefintion.description= The Java editor text font is used by Java editors.
+#--- filter 
+HideImportDeclaration.label= Import declarations
+HideImportDeclaration.description= Hides all import declarations
 
 #--- templates
 templates.php.contextType.name= php
diff --git a/net.sourceforge.phpeclipse/plugin.xml b/net.sourceforge.phpeclipse/plugin.xml
index 72dcc0d..cf3c6f1 100644
--- a/net.sourceforge.phpeclipse/plugin.xml
+++ b/net.sourceforge.phpeclipse/plugin.xml
@@ -3,7 +3,7 @@
 <plugin
    id="net.sourceforge.phpeclipse"
    name="%pluginName"
-   version="1.1.1"
+   version="1.1.2"
    provider-name="%providerName"
    class="net.sourceforge.phpeclipse.PHPeclipsePlugin">
     
@@ -29,6 +29,7 @@
       <import plugin="org.eclipse.ui.editors"/>
       <import plugin="org.eclipse.ui.externaltools"/>
       <import plugin="org.eclipse.help"/>
+      <import plugin="org.eclipse.team.core"/>
       <import plugin="org.eclipse.swt"/>
       <import plugin="org.eclipse.search"/>
       <import plugin="org.eclipse.update.ui"/>
@@ -93,8 +94,9 @@
     <persistent value="true"/>
 </extension>
 
-   <extension-point id="phpEditorTextHovers" name="%phpEditorTextHoversName" schema="schema/phpEditorTextHovers.exsd"/> 
-   <extension-point id="foldingStructureProviders" name="%foldingStructureProvidersExtensionPoint" schema="schema/foldingStructureProviders.exsd"/>
+<extension-point id="phpElementFilters" name="%elementFiltersName" schema="schema/phpElementFilters.exsd"/>
+<extension-point id="phpEditorTextHovers" name="%phpEditorTextHoversName" schema="schema/phpEditorTextHovers.exsd"/> 
+<extension-point id="foldingStructureProviders" name="%foldingStructureProvidersExtensionPoint" schema="schema/foldingStructureProviders.exsd"/>
    
   <extension
 	point="org.eclipse.ui.decorators">
@@ -1084,7 +1086,7 @@
             id="net.sourceforge.phpeclipse.phpeditor.QuickFixRulerMenuAction">
          <action
                label="%Dummy.label"
-               helpContextId="org.eclipse.jdt.ui.quick_fix_action"
+               helpContextId="net.sourceforge.phpeclipse.quick_fix_action"
                class="net.sourceforge.phpeclipse.phpeditor.JavaSelectRulerAction"
                menubarPath="additions"
                id="net.sourceforge.phpeclipse.phpeditor.JavaSelectRulerMenuAction">
@@ -1834,6 +1836,22 @@
 	</extension>
 	
 <!-- =========================================================================== -->
+<!-- Filter Support                                                              -->
+<!-- =========================================================================== -->
+   <extension
+         point="net.sourceforge.phpeclipse.phpElementFilters">
+<!-- Outline Page -->
+      <filter
+            targetId="net.sourceforge.phpeclipse.JavaOutlinePage"
+            name="%HideImportDeclaration.label"
+            enabled="false"
+            description="%HideImportDeclaration.description"
+            class="net.sourceforge.phpdt.internal.ui.filters.ImportDeclarationFilter"
+            id="net.sourceforge.phpeclipse.JavaOutlinePage.ImportDeclarationFilter">
+      </filter>
+   </extension>
+   
+<!-- =========================================================================== -->
 <!-- Templates                                                                   -->
 <!-- =========================================================================== -->
    <extension
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java
index fec960b..d4836ab 100644
--- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java
@@ -102,11 +102,15 @@ public class PHPUiImages {
 		private static final String T_WIZBAN= "wizban"; 	//$NON-NLS-1$
 		private static final String T_CLCL= "clcl16"; 	//$NON-NLS-1$
 		private static final String T_DLCL= "dlcl16"; 	//$NON-NLS-1$
+		private static final String T_ELCL= "elcl16"; 	//$NON-NLS-1$
 		private static final String T_CTOOL= "ctool16"; 	//$NON-NLS-1$
 		private static final String T_CVIEW= "cview16"; //$NON-NLS-1$
 	
 	public static final ImageDescriptor DESC_WIZBAN_NEWCLASS= create(T_WIZBAN, "newclass_wiz.gif"); 			//$NON-NLS-1$
 		
+	public static final ImageDescriptor DESC_ELCL_FILTER= create(T_ELCL, "filter_ps.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_DLCL_FILTER= create(T_DLCL, "filter_ps.gif"); //$NON-NLS-1$
+
 	/*
 	 * Available cached Images in the Java plugin image registry.
 	 */
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java
new file mode 100644
index 0000000..93ff9e2
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClassFilter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+
+/**
+ * Filters classes
+ */
+public class ClassFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IType) {
+			try {
+				return ((IType)element).isInterface();
+			} catch (JavaModelException ex) {
+				return true;
+			}
+		}
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java
new file mode 100644
index 0000000..80d07cd
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ClosedProjectFilter.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import org.eclipse.core.resources.IResource;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+/**
+ * Filters closed projects
+ */
+public class ClosedProjectFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IJavaElement) 
+			return ((IJavaElement)element).getJavaProject().getProject().isOpen();
+		if (element instanceof IResource)
+			return ((IResource)element).getProject().isOpen();
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java
new file mode 100644
index 0000000..7a3fa53
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/CustomFiltersDialog.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+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.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+public class CustomFiltersDialog extends SelectionDialog {
+
+	private static final String SEPARATOR= ",";  //$NON-NLS-1$
+
+	private String fViewId;
+	private boolean fEnablePatterns;
+	private String[] fPatterns;
+	private String[] fEnabledFilterIds;
+
+	private FilterDescriptor[] fBuiltInFilters;
+
+	private CheckboxTableViewer fCheckBoxList;
+	private Button fEnableUserDefinedPatterns;
+	private Text fUserDefinedPatterns;
+
+	private Stack fFilterDescriptorChangeHistory;
+
+	
+	/**
+	 * Creates a dialog to customize Java element filters.
+	 * 
+	 * @param shell the parent shell
+	 * @param viewId the id of the view
+	 * @param enablePatterns <code>true</code> if pattern filters are enabled
+	 * @param patterns the filter patterns
+	 * @param enabledFilterIds the Ids of the enabled filters
+	 */
+	public CustomFiltersDialog(
+			Shell shell,
+			String viewId,
+			boolean enablePatterns,
+			String[] patterns,
+			String[] enabledFilterIds) {
+
+		super(shell);
+		Assert.isNotNull(viewId);
+		Assert.isNotNull(patterns);
+		Assert.isNotNull(enabledFilterIds);
+
+		fViewId= viewId;
+		fPatterns= patterns;
+		fEnablePatterns= enablePatterns;
+		fEnabledFilterIds= enabledFilterIds;
+
+		fBuiltInFilters= FilterDescriptor.getFilterDescriptors(fViewId);
+		fFilterDescriptorChangeHistory= new Stack();
+		setShellStyle(getShellStyle() | SWT.RESIZE);
+	}
+
+	protected void configureShell(Shell shell) {
+		setTitle(FilterMessages.getString("CustomFiltersDialog.title"));  //$NON-NLS-1$
+		setMessage(FilterMessages.getString("CustomFiltersDialog.filterList.label")); //$NON-NLS-1$
+		super.configureShell(shell);
+		WorkbenchHelp.setHelp(shell, IJavaHelpContextIds.CUSTOM_FILTERS_DIALOG);
+	}
+
+	/**
+	 * Overrides method in Dialog
+	 * 
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+	 */	
+	protected Control createDialogArea(Composite parent) {
+		initializeDialogUnits(parent);
+		// create a composite with standard margins and spacing
+		Composite composite= new Composite(parent, SWT.NONE);
+		GridLayout layout= new GridLayout();
+		layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+		layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+		layout.verticalSpacing= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+		layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		composite.setFont(parent.getFont());
+		Composite group= composite;
+		
+		// Checkbox
+		fEnableUserDefinedPatterns= new Button(group, SWT.CHECK);
+		fEnableUserDefinedPatterns.setFocus();
+		fEnableUserDefinedPatterns.setText(FilterMessages.getString("CustomFiltersDialog.enableUserDefinedPattern")); //$NON-NLS-1$
+		
+		// Pattern	field
+		fUserDefinedPatterns= new Text(group, SWT.SINGLE | SWT.BORDER);
+		GridData  data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+		data.widthHint= convertWidthInCharsToPixels(59);
+		fUserDefinedPatterns.setLayoutData(data);
+		String patterns= convertToString(fPatterns, SEPARATOR);
+		fUserDefinedPatterns.setText(patterns);
+
+		// Info text
+		final Label info= new Label(group, SWT.LEFT);
+		info.setText(FilterMessages.getString("CustomFiltersDialog.patternInfo")); //$NON-NLS-1$
+
+		// Enabling / disabling of pattern group
+		fEnableUserDefinedPatterns.setSelection(fEnablePatterns);
+		fUserDefinedPatterns.setEnabled(fEnablePatterns);
+		info.setEnabled(fEnablePatterns);
+		fEnableUserDefinedPatterns.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				boolean state= fEnableUserDefinedPatterns.getSelection();
+				fUserDefinedPatterns.setEnabled(state);
+				info.setEnabled(fEnableUserDefinedPatterns.getSelection());
+				if (state)
+					fUserDefinedPatterns.setFocus();
+			}
+		});
+
+		// Filters provided by extension point
+		if (fBuiltInFilters.length > 0)
+			createCheckBoxList(group);
+				
+		applyDialogFont(parent);		
+		return parent;
+	}
+
+	private void createCheckBoxList(Composite parent) {
+		// Filler
+		new Label(parent, SWT.NONE);
+		
+		Label info= new Label(parent, SWT.LEFT);
+		info.setText(FilterMessages.getString("CustomFiltersDialog.filterList.label"));  //$NON-NLS-1$
+		
+		fCheckBoxList= CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
+		GridData data= new GridData(GridData.FILL_BOTH);
+		data.heightHint= fCheckBoxList.getTable().getItemHeight() * 10;
+		fCheckBoxList.getTable().setLayoutData(data);
+
+		fCheckBoxList.setLabelProvider(createLabelPrivder());
+		fCheckBoxList.setContentProvider(new ArrayContentProvider());
+
+		fCheckBoxList.setInput(fBuiltInFilters);
+		setInitialSelections(getEnabledFilterDescriptors());
+		
+		List initialSelection= getInitialElementSelections();
+		if (initialSelection != null && !initialSelection.isEmpty())
+			checkInitialSelections();
+
+		// Description
+		info= new Label(parent, SWT.LEFT);
+		info.setText(FilterMessages.getString("CustomFiltersDialog.description.label"));  //$NON-NLS-1$
+		final Text description= new Text(parent, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.heightHint= convertHeightInCharsToPixels(3);
+		description.setLayoutData(data);
+		fCheckBoxList.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				ISelection selection= event.getSelection();
+				if (selection instanceof IStructuredSelection) {
+					Object selectedElement= ((IStructuredSelection)selection).getFirstElement();
+					if (selectedElement instanceof FilterDescriptor)
+						description.setText(((FilterDescriptor)selectedElement).getDescription());
+				}
+			}
+		});
+		fCheckBoxList.addCheckStateListener(new ICheckStateListener() {
+			/*
+			 * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+			 */
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				Object element= event.getElement();
+				if (element instanceof FilterDescriptor) {
+					// renew if already touched
+					if (fFilterDescriptorChangeHistory.contains(element))
+						fFilterDescriptorChangeHistory.remove(element);
+					fFilterDescriptorChangeHistory.push(element);
+				}
+			}});
+
+		addSelectionButtons(parent);
+	}
+
+	private void addSelectionButtons(Composite composite) {
+		Composite buttonComposite= new Composite(composite, SWT.RIGHT);
+		GridLayout layout= new GridLayout();
+		layout.numColumns= 2;
+		buttonComposite.setLayout(layout);
+		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
+		data.grabExcessHorizontalSpace= true;
+		composite.setData(data);
+
+		// Select All button
+		String label= FilterMessages.getString("CustomFiltersDialog.SelectAllButton.label"); //$NON-NLS-1$
+		Button selectButton= createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, label, false);
+		SWTUtil.setButtonDimensionHint(selectButton);
+		SelectionListener listener= new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				fCheckBoxList.setAllChecked(true);
+				fFilterDescriptorChangeHistory.clear();
+				for (int i= 0; i < fBuiltInFilters.length; i++)
+					fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
+			}
+		};
+		selectButton.addSelectionListener(listener);
+
+		// De-select All button
+		label= FilterMessages.getString("CustomFiltersDialog.DeselectAllButton.label"); //$NON-NLS-1$
+		Button deselectButton= createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, label, false);
+		SWTUtil.setButtonDimensionHint(deselectButton);
+		listener= new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				fCheckBoxList.setAllChecked(false);
+				fFilterDescriptorChangeHistory.clear();
+				for (int i= 0; i < fBuiltInFilters.length; i++)
+					fFilterDescriptorChangeHistory.push(fBuiltInFilters[i]);
+			}
+		};
+		deselectButton.addSelectionListener(listener);
+	}
+
+	private void checkInitialSelections() {
+		Iterator itemsToCheck= getInitialElementSelections().iterator();
+		while (itemsToCheck.hasNext())
+			fCheckBoxList.setChecked(itemsToCheck.next(),true);
+	}
+
+	protected void okPressed() {
+		if (fBuiltInFilters != null) {
+			ArrayList result= new ArrayList();
+			for (int i= 0; i < fBuiltInFilters.length; ++i) {
+				if (fCheckBoxList.getChecked(fBuiltInFilters[i]))
+					result.add(fBuiltInFilters[i]);
+			}
+			setResult(result);
+		}
+		super.okPressed();
+	}
+	
+	private ILabelProvider createLabelPrivder() {
+		return 
+			new LabelProvider() {
+				public Image getImage(Object element) {
+					return null;
+				}
+				public String getText(Object element) {
+					if (element instanceof FilterDescriptor)
+						return ((FilterDescriptor)element).getName();
+					else
+						return null;
+				}
+			};
+	}
+
+	// ---------- result handling ----------
+	
+	protected void setResult(List newResult) {
+		super.setResult(newResult);
+		if (fUserDefinedPatterns.getText().length() > 0) {
+			fEnablePatterns= fEnableUserDefinedPatterns.getSelection();
+			fPatterns= convertFromString(fUserDefinedPatterns.getText(), SEPARATOR);
+		} else {
+			fEnablePatterns= false;
+			fPatterns= new String[0];
+		}			
+	}
+
+
+	/**
+	 * @return the patterns which have been entered by the user
+	 */
+	public String[] getUserDefinedPatterns() {
+		return fPatterns;
+	}
+
+	/**
+	 * @return the Ids of the enabled built-in filters
+	 */
+	public String[] getEnabledFilterIds() {
+		Object[] result= getResult();
+		Set enabledIds= new HashSet(result.length);
+		for (int i= 0; i < result.length; i++)
+			enabledIds.add(((FilterDescriptor)result[i]).getId());
+		return (String[]) enabledIds.toArray(new String[enabledIds.size()]);
+	}
+
+	/**
+	 * @return <code>true</code> if the user-defined patterns are disabled
+	 */
+	public boolean areUserDefinedPatternsEnabled() {
+		return fEnablePatterns;
+	}
+	
+	/**
+	 * @return a stack with the filter descriptor check history
+	 * @since 3.0
+	 */
+	public Stack getFilterDescriptorChangeHistory() {
+		return fFilterDescriptorChangeHistory;
+	}
+
+	private FilterDescriptor[] getEnabledFilterDescriptors() {
+		FilterDescriptor[] filterDescs= fBuiltInFilters;
+		List result= new ArrayList(filterDescs.length);
+		List enabledFilterIds= Arrays.asList(fEnabledFilterIds);
+		for (int i= 0; i < filterDescs.length; i++) {
+			String id= filterDescs[i].getId();
+			if (enabledFilterIds.contains(id))
+				result.add(filterDescs[i]);
+		}
+		return (FilterDescriptor[])result.toArray(new FilterDescriptor[result.size()]);
+	}
+
+
+	public static String[] convertFromString(String patterns, String separator) {
+		StringTokenizer tokenizer= new StringTokenizer(patterns, separator, true);
+		int tokenCount= tokenizer.countTokens();
+		List result= new ArrayList(tokenCount);
+		boolean escape= false;
+		boolean append= false;
+		while (tokenizer.hasMoreTokens()) {
+			String token= tokenizer.nextToken().trim();
+			if (separator.equals(token)) {
+				if (!escape)
+					escape= true;
+				else {
+					addPattern(result, separator);
+					append= true;
+				}
+			} else  {
+				if (!append)
+ 					result.add(token);
+				else
+					addPattern(result, token);
+				append= false;
+				escape= false;
+			}
+		}
+		return (String[])result.toArray(new String[result.size()]);
+	}
+	
+	private static void addPattern(List list, String pattern) {
+		if (list.isEmpty())
+			list.add(pattern);
+		else {
+			int index= list.size() - 1;
+			list.set(index, ((String)list.get(index)) + pattern);
+		}
+	}
+
+	public static String convertToString(String[] patterns, String separator) {
+		int length= patterns.length;
+		StringBuffer strBuf= new StringBuffer();
+		if (length > 0)
+			strBuf.append(escapeSeparator(patterns[0], separator));
+		else
+			return ""; //$NON-NLS-1$
+		int i= 1;
+		while (i < length) {
+			strBuf.append(separator);
+			strBuf.append(" "); //$NON-NLS-1$
+			strBuf.append(escapeSeparator(patterns[i++], separator));
+		}
+		return strBuf.toString();
+	}
+	
+	private static String escapeSeparator(String pattern, String separator) {
+		int length= pattern.length();
+		StringBuffer buf= new StringBuffer(length);
+		for (int i= 0; i < length; i++) {
+			char ch= pattern.charAt(i); //$NON-NLS-1$
+			if (separator.equals(String.valueOf(ch)))
+				buf.append(ch);
+			buf.append(ch);
+		}
+		return buf.toString();
+		
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java
new file mode 100644
index 0000000..ad3fd39
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FieldsFilter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Fields filter.
+ * 
+ * @since 3.0
+ */
+public class FieldsFilter extends MemberFilter {
+	public FieldsFilter() {
+		addFilter(MemberFilter.FILTER_FIELDS);
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java
new file mode 100644
index 0000000..249c97c
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterDescriptor.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.activities.WorkbenchActivityHelper;
+
+/**
+ * Represents a custom filter which is provided by the
+ * "org.eclipse.jdt.ui.javaElementFilters" extension point.
+ * 
+ * since 2.0
+ */
+public class FilterDescriptor implements Comparable, IPluginContribution {
+
+	private static String PATTERN_FILTER_ID_PREFIX= "_patternFilterId_"; //$NON-NLS-1$
+
+
+	private static final String EXTENSION_POINT_NAME= "phpElementFilters"; //$NON-NLS-1$
+
+	private static final String FILTER_TAG= "filter"; //$NON-NLS-1$
+
+	private static final String PATTERN_ATTRIBUTE= "pattern"; //$NON-NLS-1$	
+	private static final String ID_ATTRIBUTE= "id"; //$NON-NLS-1$
+	/**
+	 * @deprecated as of 3.0 use {@link FilterDescriptor#TARGET_ID_ATTRIBUTE}
+	 */
+	private static final String VIEW_ID_ATTRIBUTE= "viewId"; //$NON-NLS-1$
+	private static final String TARGET_ID_ATTRIBUTE= "targetId"; //$NON-NLS-1$
+	private static final String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
+	private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
+	private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
+	private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$	
+	/**
+	 * @deprecated	use "enabled" instead
+	 */
+	private static final String SELECTED_ATTRIBUTE= "selected"; //$NON-NLS-1$
+
+	private static FilterDescriptor[] fgFilterDescriptors;
+
+
+	private IConfigurationElement fElement;
+
+	/**
+	 * Returns all contributed Java element filters.
+	 */
+	public static FilterDescriptor[] getFilterDescriptors() {
+		if (fgFilterDescriptors == null) {
+			IExtensionRegistry registry= Platform.getExtensionRegistry();
+			IConfigurationElement[] elements= registry.getConfigurationElementsFor(PHPeclipsePlugin.PLUGIN_ID, EXTENSION_POINT_NAME);
+			fgFilterDescriptors= createFilterDescriptors(elements);
+		}	
+		return fgFilterDescriptors;
+	} 
+	/**
+	 * Returns all Java element filters which
+	 * are contributed to the given view.
+	 */
+	public static FilterDescriptor[] getFilterDescriptors(String targetId) {
+		FilterDescriptor[] filterDescs= FilterDescriptor.getFilterDescriptors();
+		List result= new ArrayList(filterDescs.length);
+		for (int i= 0; i < filterDescs.length; i++) {
+			String tid= filterDescs[i].getTargetId();
+			if (WorkbenchActivityHelper.filterItem(filterDescs[i]))
+				continue;
+			if (tid == null || tid.equals(targetId))
+				result.add(filterDescs[i]);
+		}
+		return (FilterDescriptor[])result.toArray(new FilterDescriptor[result.size()]);
+	}
+	
+	/**
+	 * Creates a new filter descriptor for the given configuration element.
+	 */
+	private FilterDescriptor(IConfigurationElement element) {
+		fElement= element;
+		// it is either a pattern filter or a custom filter
+		Assert.isTrue(isPatternFilter() ^ isCustomFilter(), "An extension for extension-point org.eclipse.jdt.ui.javaElementFilters does not specify a correct filter"); //$NON-NLS-1$
+		Assert.isNotNull(getId(), "An extension for extension-point org.eclipse.jdt.ui.javaElementFilters does not provide a valid ID"); //$NON-NLS-1$
+		Assert.isNotNull(getName(), "An extension for extension-point org.eclipse.jdt.ui.javaElementFilters does not provide a valid name"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates a new <code>ViewerFilter</code>.
+	 * This method is only valid for viewer filters.
+	 */
+	public ViewerFilter createViewerFilter() {
+		if (!isCustomFilter())
+			return null;
+		
+		final ViewerFilter[] result= new ViewerFilter[1];
+		String message= FilterMessages.getFormattedString("FilterDescriptor.filterCreationError.message", getId()); //$NON-NLS-1$
+		ISafeRunnable code= new SafeRunnable(message) {
+			/*
+			 * @see org.eclipse.core.runtime.ISafeRunnable#run()
+			 */
+			public void run() throws Exception {
+				result[0]= (ViewerFilter)fElement.createExecutableExtension(CLASS_ATTRIBUTE);
+			}
+			
+		};
+		Platform.run(code);
+		return result[0];
+	}
+	
+	//---- XML Attribute accessors ---------------------------------------------
+	
+	/**
+	 * Returns the filter's id.
+	 * <p>
+	 * This attribute is mandatory for custom filters.
+	 * The ID for pattern filters is
+	 * PATTERN_FILTER_ID_PREFIX plus the pattern itself.
+	 * </p>
+	 */
+	public String getId() {
+		if (isPatternFilter()) {
+			String targetId= getTargetId();
+			if (targetId == null)
+				return PATTERN_FILTER_ID_PREFIX + getPattern();
+			else
+				return targetId + PATTERN_FILTER_ID_PREFIX + getPattern();
+		} else
+			return fElement.getAttribute(ID_ATTRIBUTE);
+	}
+	
+	/**
+	 * Returns the filter's name.
+	 * <p>
+	 * If the name of a pattern filter is missing
+	 * then the pattern is used as its name.
+	 * </p>
+	 */
+	public String getName() {
+		String name= fElement.getAttribute(NAME_ATTRIBUTE);
+		if (name == null && isPatternFilter())
+			name= getPattern();
+		return name;
+	}
+
+	/**
+	 * Returns the filter's pattern.
+	 * 
+	 * @return the pattern string or <code>null</code> if it's not a pattern filter
+	 */
+	public String getPattern() {
+		return fElement.getAttribute(PATTERN_ATTRIBUTE);
+	}
+
+	/**
+	 * Returns the filter's viewId.
+	 * 
+	 * @return the view ID or <code>null</code> if the filter is for all views
+	 * @since 3.0
+	 */
+	public String getTargetId() {
+		String tid= fElement.getAttribute(TARGET_ID_ATTRIBUTE);
+		
+		if (tid != null)
+			return tid;
+		
+		// Backwards compatibility code
+		return fElement.getAttribute(VIEW_ID_ATTRIBUTE);
+		
+	}
+
+	/**
+	 * Returns the filter's description.
+	 * 
+	 * @return the description or <code>null</code> if no description is provided
+	 */
+	public String getDescription() {
+		String description= fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
+		if (description == null)
+			description= ""; //$NON-NLS-1$
+		return description;
+	}
+
+	/**
+	 * @return <code>true</code> if this filter is a custom filter.
+	 */
+	public boolean isPatternFilter() {
+		return getPattern() != null;
+	}
+
+	/**
+	 * @return <code>true</code> if this filter is a pattern filter.
+	 */
+	public boolean isCustomFilter() {
+		return fElement.getAttribute(CLASS_ATTRIBUTE) != null;
+	}
+
+	/**
+	 * Returns <code>true</code> if the filter
+	 * is initially enabled.
+	 * 
+	 * This attribute is optional and defaults to <code>true</code>.
+	 */
+	public boolean isEnabled() {
+		String strVal= fElement.getAttribute(ENABLED_ATTRIBUTE);
+		if (strVal == null)
+			// backward compatibility
+			strVal= fElement.getAttribute(SELECTED_ATTRIBUTE);
+		return strVal == null || Boolean.valueOf(strVal).booleanValue();
+	}
+
+	/* 
+	 * Implements a method from IComparable 
+	 */ 
+	public int compareTo(Object o) {
+		if (o instanceof FilterDescriptor)
+			return Collator.getInstance().compare(getName(), ((FilterDescriptor)o).getName());
+		else
+			return Integer.MIN_VALUE;
+	}
+
+	//---- initialization ---------------------------------------------------
+	
+	/**
+	 * Creates the filter descriptors.
+	 */
+	private static FilterDescriptor[] createFilterDescriptors(IConfigurationElement[] elements) {
+		List result= new ArrayList(5);
+		Set descIds= new HashSet(5);
+		for (int i= 0; i < elements.length; i++) {
+			final IConfigurationElement element= elements[i];
+			if (FILTER_TAG.equals(element.getName())) {
+
+				final FilterDescriptor[] desc= new FilterDescriptor[1];
+				Platform.run(new SafeRunnable(FilterMessages.getString("FilterDescriptor.filterDescriptionCreationError.message")) { //$NON-NLS-1$
+					public void run() throws Exception {
+						desc[0]= new FilterDescriptor(element);
+					}
+				});
+
+				if (desc[0] != null && !descIds.contains(desc[0].getId())) {
+					result.add(desc[0]);
+					descIds.add(desc[0].getId());
+				}
+			}
+		}
+		Collections.sort(result);
+		return (FilterDescriptor[])result.toArray(new FilterDescriptor[result.size()]);
+	}
+	
+	public String getLocalId() {
+		return fElement.getAttribute(ID_ATTRIBUTE);
+	}
+
+    public String getPluginId() {
+        return fElement.getDeclaringExtension().getNamespace();
+    }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java
new file mode 100644
index 0000000..df8ba85
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class FilterMessages {
+
+	private static final String RESOURCE_BUNDLE= FilterMessages.class.getName();
+
+	private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+	private FilterMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+		}
+	}
+	/**
+	 * Gets a string from the resource bundle and formats it with the argument
+	 * 
+	 * @param key	the string used to get the bundle value, must not be null
+	 */
+	public static String getFormattedString(String key, Object[] args) {
+		String format= null;
+		try {
+			format= fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+		}
+		return MessageFormat.format(format, args);
+	}
+
+	/**
+	 * Gets a string from the resource bundle and formats it with the argument
+	 * 
+	 * @param key	the string used to get the bundle value, must not be null
+	 */
+	public static String getFormattedString(String key, Object arg) {
+		String format= null;
+		try {
+			format= fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+		}
+		if (arg == null)
+			arg= ""; //$NON-NLS-1$
+		return MessageFormat.format(format, new Object[] { arg });
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties
new file mode 100644
index 0000000..7687a76
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/FilterMessages.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# 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
+###############################################################################
+
+CustomFiltersDialog.title= Java Element Filters
+CustomFiltersDialog.patternInfo= The patterns are separated by comma, where\n* = any string, ? = any character, ,, = ,
+CustomFiltersDialog.enableUserDefinedPattern= &Name filter patterns (matching names will be hidden):
+CustomFiltersDialog.filterList.label= S&elect the elements to exclude from the view:
+CustomFiltersDialog.description.label= Filter description:
+CustomFiltersDialog.SelectAllButton.label= &Select All
+CustomFiltersDialog.DeselectAllButton.label= &Deselect All
+
+OpenCustomFiltersDialogAction.text= &Filters...
+
+FilterDescriptor.filterDescriptionCreationError.message= One of the extensions for extension-point org.eclipse.jdt.ui.javaElementFilters is incorrect.
+FilterDescriptor.filterCreationError.title= Filter Creation Error
+FilterDescriptor.filterCreationError.message= The org.eclipse.jdt.ui.javaElementFilters plug-in extension "{0}" specifies a viewer filter class which does not exist.
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java
new file mode 100644
index 0000000..7d65e9d
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/ImportDeclarationFilter.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IImportContainer;
+import net.sourceforge.phpdt.core.IImportDeclaration;
+
+
+/**
+ * Filters import declarations
+ */
+public class ImportDeclarationFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		return !((element instanceof IImportContainer) || (element instanceof IImportDeclaration));
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java
new file mode 100644
index 0000000..b95bf6c
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/InterfaceFilter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+
+/**
+ * Filters interfaces
+ */
+public class InterfaceFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IType) {
+			try {
+				return !((IType)element).isInterface();
+			} catch (JavaModelException ex) {
+				return true;
+			}
+		}
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java
new file mode 100644
index 0000000..bb0cb66
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/JavaFileFilter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+
+/**
+ * Filters out all compilation units and class files elements.
+ */
+public class JavaFileFilter  extends ViewerFilter {
+	
+	/**
+	 * Returns the result of this filter, when applied to the
+	 * given inputs.
+	 *
+	 * @param inputs the set of elements to 
+	 * @return Returns true if element should be included in filtered set
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof ICompilationUnit)
+			return false;
+//		if (element instanceof IClassFile)
+//			return false;
+			
+//		if (element instanceof IPackageFragment)
+//			try {
+//				return ((IPackageFragment)element).getNonJavaResources().length > 0;
+//			} catch (JavaModelException ex) {
+//				return true;
+//			}
+		return true;			
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java
new file mode 100644
index 0000000..3fbb87f
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NamePatternFilter.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+import net.sourceforge.phpdt.internal.ui.util.StringMatcher;
+
+/**
+ * The NamePatternFilter selects the elements which
+ * match the given string patterns.
+ * <p>
+ * The following characters have special meaning:
+ *   ? => any character
+ *   * => any string
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class NamePatternFilter extends ViewerFilter {
+	private String[] fPatterns;
+	private StringMatcher[] fMatchers;
+	
+	/**
+	 * Return the currently configured StringMatchers.
+	 */
+	private StringMatcher[] getMatchers() {
+		return fMatchers;
+	}
+	
+	/**
+	 * Gets the patterns for the receiver.
+	 */
+	public String[] getPatterns() {
+		return fPatterns;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * Method declared on ViewerFilter.
+	 */
+	public boolean select(Viewer viewer, Object parentElement, Object element) {
+		String matchName= null;
+		if (element instanceof IJavaElement) {
+			matchName= ((IJavaElement) element).getElementName();
+		} else if (element instanceof IAdaptable) {
+			IAdaptable adaptable= (IAdaptable) element;
+			IJavaElement javaElement= (IJavaElement)adaptable.getAdapter(IJavaElement.class);
+			if (javaElement != null)
+				matchName= javaElement.getElementName();
+			else {
+				IResource resource= (IResource)adaptable.getAdapter(IResource.class);
+				if (resource != null)
+					matchName= resource.getName();
+			}
+		}
+		if (matchName != null) {
+			StringMatcher[] testMatchers= getMatchers();
+			for (int i = 0; i < testMatchers.length; i++) {
+				if (testMatchers[i].match(matchName))
+					return false;
+			}
+			return true;
+		}
+		return true;
+	}
+	
+	/**
+	 * Sets the patterns to filter out for the receiver.
+	 * <p>
+	 * The following characters have special meaning:
+	 *   ? => any character
+	 *   * => any string
+	 * </p>
+	 */
+	public void setPatterns(String[] newPatterns) {
+		fPatterns = newPatterns;
+		fMatchers = new StringMatcher[newPatterns.length];
+		for (int i = 0; i < newPatterns.length; i++) {
+			//Reset the matchers to prevent constructor overhead
+			fMatchers[i]= new StringMatcher(newPatterns[i], true, false);
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java
new file mode 100644
index 0000000..e33067b
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaElementFilter.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+
+
+/**
+ * Filters out all non-Java elements.
+ */
+public class NonJavaElementFilter  extends ViewerFilter {
+	
+	/**
+	 * Returns the result of this filter, when applied to the
+	 * given inputs.
+	 *
+	 * @param inputs the set of elements to 
+	 * @return Returns true if element should be included in filtered set
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IJavaElement)
+			return true;
+		
+		if (element instanceof IResource) {
+			IProject project= ((IResource)element).getProject(); 
+			return project == null || !project.isOpen();
+		}
+
+		// Exclude all IStorage elements which are neither Java elements nor resources
+		if (element instanceof IStorage)
+			return false;
+			
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java
new file mode 100644
index 0000000..d491667
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonJavaProjectsFilter.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.core.resources.IProject;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+
+/**
+ * Filters non-java projects
+ */
+public class NonJavaProjectsFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IJavaProject)
+			return true;
+		else if (element instanceof IProject)
+			return !((IProject)element).isOpen();
+
+		return true; 
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java
new file mode 100644
index 0000000..ad9a2d3
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicFilter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Non-public member filter.
+ * 
+ * @since 3.0
+ */
+public class NonPublicFilter extends MemberFilter {
+	public NonPublicFilter() {
+		addFilter(MemberFilter.FILTER_NONPUBLIC);
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java
new file mode 100644
index 0000000..08fe91f
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonPublicTypeFilter.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+
+/**
+ * Filters non-public types
+ */
+public class NonPublicTypeFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IType) {
+			IType type= (IType)element;
+			try {
+				return Flags.isPublic(type.getFlags());
+			} catch (JavaModelException ex) {
+				return true;
+			}
+		}
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java
new file mode 100644
index 0000000..cbeda16
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/NonSharedProjectFilter.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import org.eclipse.core.resources.IProject;
+
+import org.eclipse.team.core.RepositoryProvider;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import net.sourceforge.phpdt.core.IJavaProject;
+
+/**
+ * Filters non-shared projects and Java projects. Non-shared projects are
+ * projects that are not controlled by a team provider.
+ * 
+ * @since 2.1
+ */
+public class NonSharedProjectFilter extends ViewerFilter {
+
+	/*
+	 * @see ViewerFilter
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IProject)
+			return isSharedProject((IProject)element);
+		
+		if (element instanceof IJavaProject)
+			return isSharedProject(((IJavaProject)element).getProject());
+
+		return true;
+	}
+	
+	private boolean isSharedProject(IProject project) {
+		return !project.isAccessible() || RepositoryProvider.isShared(project);
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java
new file mode 100644
index 0000000..c9c4781
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/OutputFolderFilter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+
+import net.sourceforge.phpdt.core.IClasspathEntry;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+
+/** 
+ * Filters out all output folders.
+ * <p>
+ * Note: Folder which are direct children of a Java element
+ * are already filtered by the Java Model.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public class OutputFolderFilter extends ViewerFilter {
+	
+	/**
+	 * Returns the result of this filter, when applied to the
+	 * given element.
+	 *
+	 * @param element the element to test 
+	 * @return <code>true</code> if element should be included
+	 * @since 3.0
+	 */
+	public boolean select(Viewer viewer, Object parent, Object element) {
+		if (element instanceof IFolder) {
+			IFolder folder= (IFolder)element;
+			IProject proj= folder.getProject();
+			try {
+				if (!proj.hasNature(PHPeclipsePlugin.PHP_NATURE_ID))
+					return true;
+				
+				IJavaProject jProject= JavaCore.create(folder.getProject());
+				if (jProject == null || !jProject.exists())
+					return true;
+				
+				// Check default output location
+				IPath defaultOutputLocation= jProject.getOutputLocation();
+				IPath folderPath= folder.getFullPath();
+				if (defaultOutputLocation != null && defaultOutputLocation.equals(folderPath))
+					return false;
+				
+				// Check output location for each class path entry
+				IClasspathEntry[] cpEntries= jProject.getRawClasspath();
+				for (int i= 0, length= cpEntries.length; i < length; i++) {
+					IPath outputLocation= cpEntries[i].getOutputLocation();
+					if (outputLocation != null && outputLocation.equals(folderPath))
+						return false;
+				}
+			} catch (CoreException ex) {
+				return true;
+			}
+		}
+		return true;
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java
new file mode 100644
index 0000000..6179f48
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/filters/StaticsFilter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.phpdt.internal.ui.filters;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.MemberFilter;
+
+/**
+ * Statics filter.
+ * 
+ * @since 3.0
+ */
+public class StaticsFilter extends MemberFilter {
+	public StaticsFilter() {
+		addFilter(MemberFilter.FILTER_STATIC);
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java
new file mode 100644
index 0000000..2ca32ae
--- /dev/null
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/CustomFiltersActionGroup.java
@@ -0,0 +1,733 @@
+/*******************************************************************************
+ * 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.phpdt.ui.actions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.filters.CustomFiltersDialog;
+import net.sourceforge.phpdt.internal.ui.filters.FilterDescriptor;
+import net.sourceforge.phpdt.internal.ui.filters.FilterMessages;
+import net.sourceforge.phpdt.internal.ui.filters.NamePatternFilter;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.actions.ActionGroup;
+
+/**
+ * Action group to add the filter action to a view part's tool bar
+ * menu.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class CustomFiltersActionGroup extends ActionGroup {
+
+	class ShowFilterDialogAction extends Action {
+		ShowFilterDialogAction() {
+			setText(FilterMessages.getString("OpenCustomFiltersDialogAction.text")); //$NON-NLS-1$
+			setImageDescriptor(PHPUiImages.DESC_ELCL_FILTER);
+			setDisabledImageDescriptor(PHPUiImages.DESC_DLCL_FILTER);
+		}
+		
+		public void run() {
+			openDialog();
+		}
+	}
+
+	/**
+	 * Menu contribution item which shows and lets check and uncheck filters.
+	 * 
+	 * @since 3.0
+	 */
+	class FilterActionMenuContributionItem extends ContributionItem {
+
+		private int fItemNumber;
+		private boolean fState;
+		private String fFilterId;
+		private String fFilterName;
+		private CustomFiltersActionGroup fActionGroup;
+
+		/**
+		 * Constructor for FilterActionMenuContributionItem.
+		 * 
+		 * @param actionGroup 	the action group
+		 * @param filterId		the id of the filter
+		 * @param filterName	the name of the filter
+		 * @param state			the initial state of the filter
+		 * @param itemNumber	the menu item index
+		 */
+		public FilterActionMenuContributionItem(CustomFiltersActionGroup actionGroup, String filterId, String filterName, boolean state, int itemNumber) {
+			super(filterId);
+			Assert.isNotNull(actionGroup);
+			Assert.isNotNull(filterId);
+			Assert.isNotNull(filterName);
+			fActionGroup= actionGroup;
+			fFilterId= filterId;
+			fFilterName= filterName;
+			fState= state;
+			fItemNumber= itemNumber;
+		}
+
+		/*
+		 * Overrides method from ContributionItem.
+		 */
+		public void fill(Menu menu, int index) {
+			MenuItem mi= new MenuItem(menu, SWT.CHECK, index);
+			mi.setText("&" + fItemNumber + " " + fFilterName);  //$NON-NLS-1$  //$NON-NLS-2$
+			/*
+			 * XXX: Don't set the image - would look bad because other menu items don't provide image
+			 * XXX: Get working set specific image name from XML - would need to cache icons
+			 */
+//			mi.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVA_WORKING_SET));
+			mi.setSelection(fState);
+			mi.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					fState= !fState;
+					fActionGroup.setFilter(fFilterId, fState);
+				}
+			});
+		}
+	
+		/*
+		 * @see org.eclipse.jface.action.IContributionItem#isDynamic()
+		 */
+		public boolean isDynamic() {
+			return true;
+		}
+	}
+
+	private static final String TAG_CUSTOM_FILTERS = "customFilters"; //$NON-NLS-1$
+	private static final String TAG_USER_DEFINED_PATTERNS_ENABLED= "userDefinedPatternsEnabled"; //$NON-NLS-1$
+	private static final String TAG_USER_DEFINED_PATTERNS= "userDefinedPatterns"; //$NON-NLS-1$
+	private static final String TAG_XML_DEFINED_FILTERS= "xmlDefinedFilters"; //$NON-NLS-1$
+	private static final String TAG_LRU_FILTERS = "lastRecentlyUsedFilters"; //$NON-NLS-1$
+
+	private static final String TAG_CHILD= "child"; //$NON-NLS-1$
+	private static final String TAG_PATTERN= "pattern"; //$NON-NLS-1$
+	private static final String TAG_FILTER_ID= "filterId"; //$NON-NLS-1$
+	private static final String TAG_IS_ENABLED= "isEnabled"; //$NON-NLS-1$
+
+	private static final String SEPARATOR= ",";  //$NON-NLS-1$
+
+	private static final int MAX_FILTER_MENU_ENTRIES= 3;
+	private static final String RECENT_FILTERS_GROUP_NAME= "recentFiltersGroup"; //$NON-NLS-1$
+
+	private StructuredViewer fViewer;
+
+	private NamePatternFilter fPatternFilter;
+	private Map fInstalledBuiltInFilters;
+	
+	private Map fEnabledFilterIds;
+	private boolean fUserDefinedPatternsEnabled;
+	private String[] fUserDefinedPatterns;
+	/**
+	 * Recently changed filter Ids stack with oldest on top (i.e. at the end).
+	 *
+	 * @since 3.0
+	 */
+	private Stack fLRUFilterIdsStack; 
+	/**
+	 * Handle to menu manager to dynamically update
+	 * the last recently used filters.
+	 * 
+	 * @since 3.0
+	 */
+	private IMenuManager fMenuManager;
+	/**
+	 * The menu listener which dynamically updates
+	 * the last recently used filters.
+	 * 
+	 * @since 3.0
+	 */
+	private IMenuListener fMenuListener;
+	/**
+	 * Filter Ids used in the last view menu invocation.
+	 * 
+	 * @since 3.0
+	 */
+	private String[] fFilterIdsUsedInLastViewMenu;
+	private HashMap fFilterDescriptorMap;
+	private String fTargetId;
+	
+	/**
+	 * Creates a new <code>CustomFiltersActionGroup</code>.
+	 * 
+	 * @param part		the view part that owns this action group
+	 * @param viewer	the viewer to be filtered
+	 */
+	public CustomFiltersActionGroup(IViewPart part, StructuredViewer viewer) {
+		this(part.getViewSite().getId(), viewer);
+	}
+
+	/**
+	 * Creates a new <code>CustomFiltersActionGroup</code>.
+	 * 
+	 * @param ownerId	the id of this action group's owner
+	 * @param viewer	the viewer to be filtered
+	 */
+	public CustomFiltersActionGroup(String ownerId, StructuredViewer viewer) {
+		Assert.isNotNull(ownerId);
+		Assert.isNotNull(viewer);
+		fTargetId= ownerId;
+		fViewer= viewer;
+
+		fLRUFilterIdsStack= new Stack();
+
+		initializeWithPluginContributions();
+		initializeWithViewDefaults();
+		
+		installFilters();
+	}
+	
+	/*
+	 * Method declared on ActionGroup.
+	 */
+	public void fillActionBars(IActionBars actionBars) {
+		fillToolBar(actionBars.getToolBarManager());
+		fillViewMenu(actionBars.getMenuManager());
+	}
+
+	public String[] removeFiltersFor(Object parent, Object element, IContentProvider contentProvider) {
+	    String[] enabledFilters= getEnabledFilterIds();
+	    Set newFilters= new HashSet();
+	    for (int i= 0; i < enabledFilters.length; i++) {
+            String filterName= enabledFilters[i];
+            ViewerFilter filter= (ViewerFilter) fInstalledBuiltInFilters.get(filterName);
+            if (filter == null)
+                newFilters.add(filterName);
+           else if (isSelected(parent, element, contentProvider, filter)) 
+                newFilters.add(filterName);
+        }
+	    if (newFilters.size() == enabledFilters.length)
+	        return new String[0];
+	    return (String[])newFilters.toArray(new String[newFilters.size()]);
+	}
+	
+	public void setFilters(String[] newFilters) {
+	    setEnabledFilterIds(newFilters);
+	    updateViewerFilters(true);
+	}
+	
+	private boolean isSelected(Object parent, Object element, IContentProvider contentProvider, ViewerFilter filter) {
+	    if (contentProvider instanceof ITreeContentProvider) {
+	        // the element and all its parents have to be selected
+	        ITreeContentProvider provider = (ITreeContentProvider) contentProvider;
+	        while (element != null && !(element instanceof IJavaModel)) {
+	            if (!filter.select(fViewer, parent, element)) 
+	                return false;
+	            element= provider.getParent( element);
+	        }
+	        return true;
+	    } 
+	    return filter.select(fViewer, parent, element);
+	}
+
+    /**
+	 * Sets the enable state of the given filter.
+	 * 
+	 * @param filterId the id of the filter
+	 * @param state the filter state
+	 */
+	private void setFilter(String filterId, boolean state) {
+		// Renew filter id in LRU stack
+		fLRUFilterIdsStack.remove(filterId);
+		fLRUFilterIdsStack.add(0, filterId);
+		
+		fEnabledFilterIds.put(filterId, new Boolean(state));
+		storeViewDefaults();
+		
+		updateViewerFilters(true);
+	}
+	
+	private String[] getEnabledFilterIds() {
+		Set enabledFilterIds= new HashSet(fEnabledFilterIds.size());
+		Iterator iter= fEnabledFilterIds.entrySet().iterator();
+		while (iter.hasNext()) {
+			Map.Entry entry= (Map.Entry)iter.next();
+			String id= (String)entry.getKey();
+			boolean isEnabled= ((Boolean)entry.getValue()).booleanValue();
+			if (isEnabled)
+				enabledFilterIds.add(id);
+		}
+		return (String[])enabledFilterIds.toArray(new String[enabledFilterIds.size()]);
+	}
+
+	
+	private void setEnabledFilterIds(String[] enabledIds) {
+		Iterator iter= fEnabledFilterIds.keySet().iterator();
+		while (iter.hasNext()) {
+			String id= (String)iter.next();
+			fEnabledFilterIds.put(id, Boolean.FALSE);
+		}
+		for (int i= 0; i < enabledIds.length; i++)
+			fEnabledFilterIds.put(enabledIds[i], Boolean.TRUE);
+	}
+
+	private void setUserDefinedPatterns(String[] patterns) {
+		fUserDefinedPatterns= patterns;
+		cleanUpPatternDuplicates();
+	}
+
+	/**
+	 * Sets the recently changed filters.
+	 * 
+	 * @param changeHistory the change history
+	 * @since 3.0
+	 */
+	private void setRecentlyChangedFilters(Stack changeHistory) {
+		Stack oldestFirstStack= new Stack();
+		
+		int length= Math.min(changeHistory.size(), MAX_FILTER_MENU_ENTRIES);
+		for (int i= 0; i < length; i++)
+			oldestFirstStack.push(((FilterDescriptor)changeHistory.pop()).getId());
+		
+		length= Math.min(fLRUFilterIdsStack.size(), MAX_FILTER_MENU_ENTRIES - oldestFirstStack.size());
+		int NEWEST= 0;
+		for (int i= 0; i < length; i++) {
+			Object filter= fLRUFilterIdsStack.remove(NEWEST);
+			if (!oldestFirstStack.contains(filter))
+				oldestFirstStack.push(filter);
+		}
+		fLRUFilterIdsStack= oldestFirstStack;
+	}
+	
+	private boolean areUserDefinedPatternsEnabled() {
+		return fUserDefinedPatternsEnabled;
+	}
+
+	private void setUserDefinedPatternsEnabled(boolean state) {
+		fUserDefinedPatternsEnabled= state;
+	}
+
+	private void fillToolBar(IToolBarManager tooBar) {
+	}
+
+	/**
+	 * Fills the given view menu with the entries managed by the
+	 * group.
+	 * 
+	 * @param viewMenu the menu to fill
+	 */
+	public void fillViewMenu(IMenuManager viewMenu) {
+		/*
+		 * Don't change the separator group name.
+		 * Using this name ensures that other filters
+		 * get contributed to the same group.
+		 */
+		viewMenu.add(new Separator("filters")); //$NON-NLS-1$
+		viewMenu.add(new GroupMarker(RECENT_FILTERS_GROUP_NAME));
+		viewMenu.add(new ShowFilterDialogAction());
+
+		fMenuManager= viewMenu;
+		fMenuListener= new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+				removePreviousLRUFilterActions(manager);
+				addLRUFilterActions(manager);
+			}
+		};
+		fMenuManager.addMenuListener(fMenuListener);
+	}
+
+	private void removePreviousLRUFilterActions(IMenuManager mm) {
+		if (fFilterIdsUsedInLastViewMenu == null)
+			return;
+		
+		for (int i= 0; i < fFilterIdsUsedInLastViewMenu.length; i++)
+			mm.remove(fFilterIdsUsedInLastViewMenu[i]);
+	}
+
+	private void addLRUFilterActions(IMenuManager mm) {
+		if (fLRUFilterIdsStack.isEmpty()) {
+			fFilterIdsUsedInLastViewMenu= null;
+			return;
+		}
+		
+		SortedSet sortedFilters= new TreeSet(fLRUFilterIdsStack);
+		String[] recentlyChangedFilterIds= (String[])sortedFilters.toArray(new String[sortedFilters.size()]);
+		
+		fFilterIdsUsedInLastViewMenu= new String[recentlyChangedFilterIds.length];
+		for (int i= 0; i < recentlyChangedFilterIds.length; i++) {
+			String id= recentlyChangedFilterIds[i];
+			fFilterIdsUsedInLastViewMenu[i]= id;
+			boolean state= fEnabledFilterIds.containsKey(id) && ((Boolean)fEnabledFilterIds.get(id)).booleanValue();
+			FilterDescriptor filterDesc= (FilterDescriptor)fFilterDescriptorMap.get(id);
+			if (filterDesc != null) {
+				IContributionItem item= new FilterActionMenuContributionItem(this, id, filterDesc.getName(), state, i+1);
+				mm.insertBefore(RECENT_FILTERS_GROUP_NAME, item);
+			}
+		}
+	}
+
+	/*
+	 * Method declared on ActionGroup.
+	 */
+	public void dispose() {
+		if (fMenuManager != null)
+			fMenuManager.removeMenuListener(fMenuListener);
+		super.dispose();
+	}
+	
+	private void initializeWithPluginContributions() {
+		fUserDefinedPatterns= new String[0];
+		fUserDefinedPatternsEnabled= false;
+
+		FilterDescriptor[] filterDescs= FilterDescriptor.getFilterDescriptors(fTargetId);
+		fFilterDescriptorMap= new HashMap(filterDescs.length);
+		fEnabledFilterIds= new HashMap(filterDescs.length);
+		for (int i= 0; i < filterDescs.length; i++) {
+			String id= filterDescs[i].getId();
+			Boolean isEnabled= new Boolean(filterDescs[i].isEnabled());
+			if (fEnabledFilterIds.containsKey(id))
+				PHPeclipsePlugin.logErrorMessage("WARNING: Duplicate id for extension-point \"org.eclipse.jdt.ui.javaElementFilters\""); //$NON-NLS-1$
+			fEnabledFilterIds.put(id, isEnabled);
+			fFilterDescriptorMap.put(id, filterDescs[i]);
+		}
+	}
+
+	// ---------- viewer filter handling ----------
+	
+	private void installFilters() {
+		fInstalledBuiltInFilters= new HashMap(fEnabledFilterIds.size());
+		fPatternFilter= new NamePatternFilter();
+		fPatternFilter.setPatterns(getUserAndBuiltInPatterns());
+		fViewer.addFilter(fPatternFilter);
+		updateBuiltInFilters();
+	}
+
+	private void updateViewerFilters(boolean refresh) {
+		String[] patterns= getUserAndBuiltInPatterns();
+		fPatternFilter.setPatterns(patterns);
+		fViewer.getControl().setRedraw(false);
+		updateBuiltInFilters();
+		if (refresh)
+			fViewer.refresh();
+		fViewer.getControl().setRedraw(true);
+	}
+	
+	private void updateBuiltInFilters() {
+		Set installedFilters= fInstalledBuiltInFilters.keySet();
+		Set filtersToAdd= new HashSet(fEnabledFilterIds.size());
+		Set filtersToRemove= new HashSet(fEnabledFilterIds.size());
+		Iterator iter= fEnabledFilterIds.entrySet().iterator();
+		while (iter.hasNext()) {
+			Map.Entry entry= (Map.Entry)iter.next();
+			String id= (String)entry.getKey();
+			boolean isEnabled= ((Boolean)entry.getValue()).booleanValue();
+			if (isEnabled && !installedFilters.contains(id))
+				filtersToAdd.add(id);
+			else if (!isEnabled && installedFilters.contains(id))
+				filtersToRemove.add(id);
+		}
+		
+		// Install the filters
+		FilterDescriptor[] filterDescs= FilterDescriptor.getFilterDescriptors(fTargetId);
+		for (int i= 0; i < filterDescs.length; i++) {
+			String id= filterDescs[i].getId();
+			// just to double check - id should denote a custom filter anyway
+			boolean isCustomFilter= filterDescs[i].isCustomFilter();
+			if (isCustomFilter) {
+				if (filtersToAdd.contains(id)) {
+					ViewerFilter filter= filterDescs[i].createViewerFilter();
+					if (filter != null) {
+						fViewer.addFilter(filter);
+						fInstalledBuiltInFilters.put(id, filter);
+					}
+				}
+				if (filtersToRemove.contains(id)) {
+					fViewer.removeFilter((ViewerFilter)fInstalledBuiltInFilters.get(id));
+					fInstalledBuiltInFilters.remove(id);
+				}
+			}
+		}
+	}
+
+	private String[] getUserAndBuiltInPatterns() {
+		List patterns= new ArrayList(fUserDefinedPatterns.length);
+		if (areUserDefinedPatternsEnabled())
+			patterns.addAll(Arrays.asList(fUserDefinedPatterns));
+		FilterDescriptor[] filterDescs= FilterDescriptor.getFilterDescriptors(fTargetId);
+		for (int i= 0; i < filterDescs.length; i++) {
+			String id= filterDescs[i].getId();
+			boolean isPatternFilter= filterDescs[i].isPatternFilter();
+			Object isEnabled= fEnabledFilterIds.get(id);
+			if (isEnabled != null && isPatternFilter && ((Boolean)isEnabled).booleanValue())
+				patterns.add(filterDescs[i].getPattern());
+		}
+		return (String[])patterns.toArray(new String[patterns.size()]);
+	}
+
+	// ---------- view kind/defaults persistency ----------
+		
+	private void initializeWithViewDefaults() {
+		// get default values for view
+		IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore();
+
+		// XXX: can be removed once bug 22533 is fixed.
+		if (!store.contains(getPreferenceKey("TAG_DUMMY_TO_TEST_EXISTENCE")))//$NON-NLS-1$
+			return;
+
+		// XXX: Uncomment once bug 22533 is fixed.
+//		if (!store.contains(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED)))
+//			return;
+		
+		fUserDefinedPatternsEnabled= store.getBoolean(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED));
+		setUserDefinedPatterns(CustomFiltersDialog.convertFromString(store.getString(getPreferenceKey(TAG_USER_DEFINED_PATTERNS)), SEPARATOR));
+
+		Iterator iter= fEnabledFilterIds.keySet().iterator();
+		while (iter.hasNext()) {
+			String id= (String)iter.next();
+			Boolean isEnabled= new Boolean(store.getBoolean(id));
+			fEnabledFilterIds.put(id, isEnabled);
+		}
+		
+		fLRUFilterIdsStack.clear();
+		String lruFilterIds= store.getString(TAG_LRU_FILTERS);
+		StringTokenizer tokenizer= new StringTokenizer(lruFilterIds, SEPARATOR);
+		while (tokenizer.hasMoreTokens()) {
+			String id= tokenizer.nextToken();
+			if (fFilterDescriptorMap.containsKey(id) && !fLRUFilterIdsStack.contains(id))
+				fLRUFilterIdsStack.push(id);
+		}
+	}
+
+	private void storeViewDefaults() {
+		// get default values for view
+		IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore();
+
+		// XXX: can be removed once bug 22533 is fixed.
+		store.setValue(getPreferenceKey("TAG_DUMMY_TO_TEST_EXISTENCE"), "storedViewPreferences");//$NON-NLS-1$//$NON-NLS-2$
+		
+		store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS_ENABLED), fUserDefinedPatternsEnabled);
+		store.setValue(getPreferenceKey(TAG_USER_DEFINED_PATTERNS), CustomFiltersDialog.convertToString(fUserDefinedPatterns ,SEPARATOR));
+
+		Iterator iter= fEnabledFilterIds.entrySet().iterator();
+		while (iter.hasNext()) {
+			Map.Entry entry= (Map.Entry)iter.next();
+			String id= (String)entry.getKey();
+			boolean isEnabled= ((Boolean)entry.getValue()).booleanValue();
+			store.setValue(id, isEnabled);
+		}
+
+		StringBuffer buf= new StringBuffer(fLRUFilterIdsStack.size() * 20);
+		iter= fLRUFilterIdsStack.iterator();
+		while (iter.hasNext()) {
+			buf.append((String)iter.next());
+			buf.append(SEPARATOR);
+		}
+		store.setValue(TAG_LRU_FILTERS, buf.toString());
+	}
+	
+	private String getPreferenceKey(String tag) {
+		return "CustomFiltersActionGroup." + fTargetId + '.' + tag; //$NON-NLS-1$
+	}
+
+	// ---------- view instance persistency ----------
+
+	/**
+	 * Saves the state of the custom filters in a memento.
+	 * 
+	 * @param memento the memento into which the state is saved
+	 */
+	public void saveState(IMemento memento) {
+		IMemento customFilters= memento.createChild(TAG_CUSTOM_FILTERS);
+		customFilters.putString(TAG_USER_DEFINED_PATTERNS_ENABLED, new Boolean(fUserDefinedPatternsEnabled).toString());
+		saveUserDefinedPatterns(customFilters);
+		saveXmlDefinedFilters(customFilters);
+		saveLRUFilters(customFilters);
+	}
+
+	private void saveXmlDefinedFilters(IMemento memento) {
+		if(fEnabledFilterIds != null && !fEnabledFilterIds.isEmpty()) {
+			IMemento xmlDefinedFilters= memento.createChild(TAG_XML_DEFINED_FILTERS);
+			Iterator iter= fEnabledFilterIds.entrySet().iterator();
+			while (iter.hasNext()) {
+				Map.Entry entry= (Map.Entry)iter.next();
+				String id= (String)entry.getKey();
+				Boolean isEnabled= (Boolean)entry.getValue();
+				IMemento child= xmlDefinedFilters.createChild(TAG_CHILD);
+				child.putString(TAG_FILTER_ID, id);
+				child.putString(TAG_IS_ENABLED, isEnabled.toString());
+			}
+		}
+	}
+	/**
+	 * Stores the last recently used filter Ids into
+	 * the given memento
+	 * 
+	 * @param memento the memento into which to store the LRU filter Ids
+	 * @since 3.0
+	 */
+	private void saveLRUFilters(IMemento memento) {
+		if(fLRUFilterIdsStack != null && !fLRUFilterIdsStack.isEmpty()) {
+			IMemento lruFilters= memento.createChild(TAG_LRU_FILTERS);
+			Iterator iter= fLRUFilterIdsStack.iterator();
+			while (iter.hasNext()) {
+				String id= (String)iter.next();
+				IMemento child= lruFilters.createChild(TAG_CHILD);
+				child.putString(TAG_FILTER_ID, id);
+			}
+		}
+	}
+
+	private void saveUserDefinedPatterns(IMemento memento) {
+		if(fUserDefinedPatterns != null && fUserDefinedPatterns.length > 0) {
+			IMemento userDefinedPatterns= memento.createChild(TAG_USER_DEFINED_PATTERNS);
+			for (int i= 0; i < fUserDefinedPatterns.length; i++) {
+				IMemento child= userDefinedPatterns.createChild(TAG_CHILD);
+				child.putString(TAG_PATTERN, fUserDefinedPatterns[i]);
+			}
+		}
+	}
+
+	/**
+	 * Restores the state of the filter actions from a memento.
+	 * <p>
+	 * Note: This method does not refresh the viewer.
+	 * </p>
+	 * 
+	 * @param memento the memento from which the state is restored
+	 */	
+	public void restoreState(IMemento memento) {
+		if (memento == null)
+			return;
+		IMemento customFilters= memento.getChild(TAG_CUSTOM_FILTERS);
+		if (customFilters == null)
+			return;
+		String userDefinedPatternsEnabled= customFilters.getString(TAG_USER_DEFINED_PATTERNS_ENABLED);
+		if (userDefinedPatternsEnabled == null)
+			return;
+
+		fUserDefinedPatternsEnabled= Boolean.valueOf(userDefinedPatternsEnabled).booleanValue();
+		restoreUserDefinedPatterns(customFilters);
+		restoreXmlDefinedFilters(customFilters);
+		restoreLRUFilters(customFilters);
+		
+		updateViewerFilters(false);
+	}
+
+	private void restoreUserDefinedPatterns(IMemento memento) {
+		IMemento userDefinedPatterns= memento.getChild(TAG_USER_DEFINED_PATTERNS);
+		if(userDefinedPatterns != null) {	
+			IMemento children[]= userDefinedPatterns.getChildren(TAG_CHILD);
+			String[] patterns= new String[children.length];
+			for (int i = 0; i < children.length; i++)
+				patterns[i]= children[i].getString(TAG_PATTERN);
+
+			setUserDefinedPatterns(patterns);
+		} else
+			setUserDefinedPatterns(new String[0]);
+	}
+
+	private void restoreXmlDefinedFilters(IMemento memento) {
+		IMemento xmlDefinedFilters= memento.getChild(TAG_XML_DEFINED_FILTERS);
+		if(xmlDefinedFilters != null) {
+			IMemento[] children= xmlDefinedFilters.getChildren(TAG_CHILD);
+			for (int i= 0; i < children.length; i++) {
+				String id= children[i].getString(TAG_FILTER_ID);
+				Boolean isEnabled= new Boolean(children[i].getString(TAG_IS_ENABLED));
+				fEnabledFilterIds.put(id, isEnabled);
+			}
+		}
+	}
+
+	private void restoreLRUFilters(IMemento memento) {
+		IMemento lruFilters= memento.getChild(TAG_LRU_FILTERS);
+		fLRUFilterIdsStack.clear();
+		if(lruFilters != null) {
+			IMemento[] children= lruFilters.getChildren(TAG_CHILD);
+			for (int i= 0; i < children.length; i++) {
+				String id= children[i].getString(TAG_FILTER_ID);
+				if (fFilterDescriptorMap.containsKey(id) && !fLRUFilterIdsStack.contains(id))
+					fLRUFilterIdsStack.push(id);
+			}
+		}
+	}
+
+	private void cleanUpPatternDuplicates() {
+		if (!areUserDefinedPatternsEnabled())
+			return;
+		List userDefinedPatterns= new ArrayList(Arrays.asList(fUserDefinedPatterns));
+		FilterDescriptor[] filters= FilterDescriptor.getFilterDescriptors(fTargetId);
+
+		for (int i= 0; i < filters.length; i++) {
+			if (filters[i].isPatternFilter()) {
+				String pattern= filters[i].getPattern();
+				if (userDefinedPatterns.contains(pattern)) {
+					fEnabledFilterIds.put(filters[i].getId(), Boolean.TRUE);
+					boolean hasMore= true;
+					while (hasMore)
+						hasMore= userDefinedPatterns.remove(pattern);
+				}
+			}
+		}
+		fUserDefinedPatterns= (String[])userDefinedPatterns.toArray(new String[userDefinedPatterns.size()]);
+		setUserDefinedPatternsEnabled(fUserDefinedPatternsEnabled && fUserDefinedPatterns.length > 0);
+	}
+	
+	// ---------- dialog related code ----------
+
+	private void openDialog() {
+		CustomFiltersDialog dialog= new CustomFiltersDialog(
+			fViewer.getControl().getShell(),
+			fTargetId,
+			areUserDefinedPatternsEnabled(),
+			fUserDefinedPatterns,
+			getEnabledFilterIds());
+		
+		if (dialog.open() == Window.OK) {
+			setEnabledFilterIds(dialog.getEnabledFilterIds());
+			setUserDefinedPatternsEnabled(dialog.areUserDefinedPatternsEnabled());
+			setUserDefinedPatterns(dialog.getUserDefinedPatterns());
+			setRecentlyChangedFilters(dialog.getFilterDescriptorChangeHistory());
+
+			storeViewDefaults();
+
+			updateViewerFilters(true);
+		}
+	}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java
index d1a475e..ed2a133 100644
--- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java
+++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaOutlinePage.java
@@ -41,6 +41,7 @@ import net.sourceforge.phpdt.ui.JavaElementSorter;
 import net.sourceforge.phpdt.ui.JavaUI;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
+import net.sourceforge.phpdt.ui.actions.CustomFiltersActionGroup;
 import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
 import net.sourceforge.phpdt.ui.actions.MemberFilterActionGroup;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
@@ -97,7 +98,6 @@ import org.eclipse.ui.part.IShowInTargetList;
 import org.eclipse.ui.part.Page;
 import org.eclipse.ui.part.ShowInContext;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
-import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
 import org.eclipse.ui.texteditor.IUpdate;
 import org.eclipse.ui.texteditor.TextEditorAction;
 import org.eclipse.ui.texteditor.TextOperationAction;
@@ -366,26 +366,6 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
 			refresh(true);
 		}
 	}
-//    public void reconcile(IJavaElementDelta delta) {
-//      fReorderedMembers = false;
-//      if (getSorter() == null) {
-//        if (fTopLevelTypeOnly && delta.getElement() instanceof IType && (delta.getKind() & IJavaElementDelta.ADDED) != 0) {
-//          refresh(true);
-//
-//        } else {
-//          Widget w = findItem(fInput);
-//          if (w != null && !w.isDisposed())
-//            update(w, delta);
-//          if (fReorderedMembers) {
-//            refresh(false);
-//            fReorderedMembers = false;
-//          }
-//        }
-//      } else {
-//        // just for now
-//        refresh(true);
-//      }
-//    }
 
     /*
      * @see TreeViewer#internalExpandToLevel
@@ -829,7 +809,7 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
 	 * Custom filter action group.
 	 * @since 3.0
 	 */
-//  private CustomFiltersActionGroup fCustomFiltersActionGroup;
+  private CustomFiltersActionGroup fCustomFiltersActionGroup;
 	
   public JavaOutlinePage(String contextMenuID, PHPEditor editor) {
     super();
@@ -876,21 +856,6 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
     return type.exists() ? type : null;
   }
 
-  /**
-   * Returns the primary type of a class file.
-   * 
-   * @param classFile
-   *          the class file
-   * @return returns the primary type of the class file, or <code>null</code> if is does not have one
-   */
-  //	protected IType getMainType(IClassFile classFile) {
-  //		try {
-  //			IType type= classFile.getType();
-  //			return type != null && type.exists() ? type : null;
-  //		} catch (JavaModelException e) {
-  //			return null;
-  //		}
-  //	}
   /*
    * (non-Javadoc) Method declared on Page
    */
@@ -962,10 +927,10 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
     if (toolBarManager != null) {
       toolBarManager.add(new LexicalSortingAction());
 
-      fMemberFilterActionGroup = new MemberFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage"); //$NON-NLS-1$
+      fMemberFilterActionGroup = new MemberFilterActionGroup(fOutlineViewer, "net.sourceforge.phpeclipse.JavaOutlinePage"); //$NON-NLS-1$
       fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
-
-      //		fCustomFiltersActionGroup.fillActionBars(actionBars);
+ 
+      fCustomFiltersActionGroup.fillActionBars(actionBars);
 
       IMenuManager menu = actionBars.getMenuManager();
       menu.add(new Separator("EndFilterGroup")); //$NON-NLS-1$
@@ -1045,6 +1010,9 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
       fOutlineViewer.addPostSelectionChangedListener(updater);
     }
 
+//  Custom filter group
+	fCustomFiltersActionGroup= new CustomFiltersActionGroup("net.sourceforge.phpeclipse.JavaOutlinePage", fOutlineViewer); //$NON-NLS-1$
+
     registerToolbarActions(bars);
 
     fOutlineViewer.setInput(fInput);
@@ -1067,6 +1035,11 @@ public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdapt
       fMemberFilterActionGroup = null;
     }
 
+    if (fCustomFiltersActionGroup != null) {
+		fCustomFiltersActionGroup.dispose();
+		fCustomFiltersActionGroup= null;
+	}
+    
     fEditor.outlinePageClosed();
     fEditor = null;
 
-- 
1.7.1