diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
index ffee2e86c1024589ad4bfb811a06dde527f8693d..6c1ae64c45e368f4a3756cb6048ae4fa3388a6ff 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
@@ -17,7 +17,10 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.base.ui.annotation.view;
 
+import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
+
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -30,6 +33,7 @@ import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -50,6 +54,7 @@ import org.fortiss.tooling.base.model.element.IModelElement;
 import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
 import org.fortiss.tooling.base.ui.annotation.editingsupport.ElementNameEditingSupport;
 import org.fortiss.tooling.base.ui.annotation.valueprovider.IAnnotationValueProvider;
+import org.fortiss.tooling.base.ui.widget.ExtendedCCombo;
 import org.fortiss.tooling.kernel.model.INamedElement;
 import org.fortiss.tooling.kernel.model.IProjectRootElement;
 
@@ -81,23 +86,11 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	 */
 	private final static String MULTIINSTANCE_NAME_SEPARATOR = ":";
 
-	/** Widget for editing of filter text. */
-	private Text filterText;
-
-	/** Filter hint text. */
-	private static final String FILTER_HINT_TEXT = "type filter text";
-
-	/** Filter pattern */
-	private String filterPattern;
+	/** Row an column filter for annotations */
+	AnnotationFilter annotationFilter;
 
-	/** Flag whether columns should be filtered. */
-	boolean filterColumns;
-
-	/**
-	 * Flag whether the displayed rows should be restricted to the currently selected model element
-	 * type.
-	 */
-	boolean restrictToSelectedModelElementType;
+	/** Widget for filter options */
+	private AnnotationFilterWidget filterWidget;
 
 	/**
 	 * Last set of {@link AnnotationEntry}s used to {@link #update(Collection)} the
@@ -228,39 +221,14 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	 */
 	private class HierarchicalNameComparator extends ViewerComparator {
 
-		/** Computes the level of an {@link IModelElement} in the tree */
-		private int getLevel(EObject o) {
-			int level = 0;
-			while(o.eContainer() != null) {
-				level++;
-				o = o.eContainer();
-			}
-
-			return level;
-		}
-
-		/**
-		 * Returns the ancestor of the {@link IModelElement} {@code modelElement} that is
-		 * {@code levelsUp} levels above model element in the hierarchy, or {@code null}, in case
-		 * {@code levelsUp} > depth(modelElement}.
-		 */
-		private EObject getAncestor(EObject o, int levelsUp) {
-			while(o.eContainer() != null && levelsUp > 0) {
-				o = o.eContainer();
-				levelsUp--;
-			}
-			return o;
-
-		}
-
 		/** {@inheritDoc} */
 		@Override
 		public int compare(Viewer viewer, Object o1, Object o2) {
 			if(o1 instanceof AnnotationEntry && o2 instanceof AnnotationEntry) {
 				IModelElement modelElement1 = ((AnnotationEntry)o1).getModelElement();
 				IModelElement modelElement2 = ((AnnotationEntry)o2).getModelElement();
-				int modelElement1Level = getLevel(modelElement1);
-				int modelElement2Level = getLevel(modelElement2);
+				int modelElement1Level = getModelElementLevel(modelElement1);
+				int modelElement2Level = getModelElementLevel(modelElement2);
 
 				EObject e1 = modelElement1;
 				EObject e2 = modelElement2;
@@ -269,7 +237,8 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 					// Element1 is higher than element2: Get ancestor of element2 that is at the
 					// level as the element1.
 					EObject ancestor =
-							getAncestor(modelElement2, modelElement2Level - modelElement1Level);
+							getModelElementAncestor(modelElement2, modelElement2Level -
+									modelElement1Level);
 
 					if(modelElement1 == ancestor) {
 						// Element1 is offspring of element2
@@ -282,7 +251,8 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 					// Element2 is higher than element1: Get ancestor of element1 that is at the
 					// level as the element2.
 					EObject ancestor =
-							getAncestor(modelElement1, modelElement1Level - modelElement2Level);
+							getModelElementAncestor(modelElement1, modelElement1Level -
+									modelElement2Level);
 
 					if(modelElement2 == ancestor) {
 						// Element2 is offspring of element1
@@ -315,16 +285,45 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		}
 	}
 
-	// Based on org.fortiss.af3.scheduling.ui.specificationsEditor.ComponentResourceTableBackend
-	/** Filters rows of the {@link GenericAnnotationView} based on the components' names. */
-	private class ComponentNamesRowFilter extends ViewerFilter {
-		/** Flag if the filter is active */
-		private boolean active = true;
+	/**
+	 * Row and column filter for the {@link GenericAnnotationView}. Row filtering is realized by
+	 * inheriting {@link ViewerFilter}, whereas for column filtering is supported by
+	 * {@link AnnotationFilter#passesColumnFilter(ColumnHandle)} that is evaluated in
+	 * {@link GenericAnnotationView#update(Collection)}.
+	 */
+	private class AnnotationFilter extends ViewerFilter {
+		/** Filter hint text. */
+		private static final String FILTER_HINT_TEXT = "type filter text";
 
-		/** (De-)activates the filter */
-		public void setActive(boolean active) {
-			this.active = active;
-		}
+		/** Hierarchy filter option: all model elements from any level */
+		private static final String HIERARCHY_LEVELS_ALL = "Show all levels";
+
+		/** Hierarchy filter option: all model elements from current level */
+		private static final String HIERARCHY_LEVELS_CURRENT = "Show current level";
+
+		/** Hierarchy filter option: currently selected model element and its offspring */
+		private static final String HIERARCHY_LEVELS_SELECTED_SUBMODEL = "Show selected sub-model";
+
+		/** Current model element / annotation name filter pattern */
+		private String filterPattern;
+
+		/** Flag whether columns / annotation names should be filtered. */
+		private boolean filterColumnName;
+
+		/** Flag whether rows / model element names should be filtered */
+		private boolean filterRowName;
+
+		/**
+		 * Flag whether the displayed rows should be restricted to the currently selected model
+		 * element type.
+		 */
+		boolean restrictToSelectedModelElementType;
+
+		/** Row filter option based on hierarchy level of model element. */
+		private String hierarchyLevelFilter;
+
+		/** Column filter option based on annotation type */
+		private Class<? extends IAnnotatedSpecification> annotationTypeFilter;
 
 		/** {@inheritDoc} */
 		@Override
@@ -338,38 +337,464 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 				return true;
 			}
 
-			return (!active || passesFilter(
-					((INamedElement)annotationEntry.getModelElement()).getName(), filterPattern)) &&
-					(!restrictToSelectedModelElementType || getCurrentlySelectedObject() == null ||
-							getCurrentlySelectedObject() instanceof IProjectRootElement || annotationEntry
-							.getModelElement().getClass()
-							.equals(getCurrentlySelectedObject().getClass()));
+			return passesRowFilter(annotationEntry);
+		}
+
+		/**
+		 * Returns {@code true} if a given {@code input} passes an case-insensitive filter specified
+		 * by {@code filterString}.
+		 */
+		private boolean passesNameFilter(String input) {
+			// Null-filter accepts every input
+			if(filterPattern == null || filterPattern.equals(FILTER_HINT_TEXT)) {
+				return true;
+			}
+
+			// Null-input cannot be accepted by a non-null filter
+			if(input == null) {
+				return false;
+			}
+			return input.toLowerCase().contains(filterPattern.toLowerCase());
+		}
+
+		/**
+		 * Returns {@code true} if given annotation entry matches the currently selected model
+		 * element (or if this particular filter option is turned off).
+		 */
+		private boolean passesSelectedElementTypeFilter(AnnotationEntry annotationEntry) {
+			if(getCurrentlySelectedObject() == null ||
+					getCurrentlySelectedObject() instanceof IProjectRootElement) {
+				return true;
+			}
+
+			int currentlySelectedObjectLevel = getModelElementLevel(getCurrentlySelectedObject());
+			int modelElementLevel = getModelElementLevel(annotationEntry.getModelElement());
+
+			if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_CURRENT)) {
+				if((getModelElementLevel(annotationEntry.getModelElement()) != currentlySelectedObjectLevel) ||
+						(getCurrentlySelectedObject().eContainer() != getModelElementAncestor(
+								annotationEntry.getModelElement(), modelElementLevel -
+										(currentlySelectedObjectLevel - 1)))) {
+					return false;
+				}
+			}
+			if(hierarchyLevelFilter.equals(HIERARCHY_LEVELS_SELECTED_SUBMODEL)) {
+				if(modelElementLevel < currentlySelectedObjectLevel) {
+					return false;
+				}
+
+				if((modelElementLevel > currentlySelectedObjectLevel) &&
+						((getCurrentlySelectedObject() != getModelElementAncestor(
+								annotationEntry.getModelElement(), modelElementLevel -
+										currentlySelectedObjectLevel))) ||
+						(getCurrentlySelectedObject() != getModelElementAncestor(
+								annotationEntry.getModelElement(), modelElementLevel -
+										(currentlySelectedObjectLevel - 0)))) {
+					return false;
+				}
+
+			}
+
+			return !restrictToSelectedModelElementType ||
+					annotationEntry.getModelElement().getClass()
+							.equals(getCurrentlySelectedObject().getClass());
+		}
+
+		/** Returns true if the given specification passes the current annotation type filter */
+		private boolean passesAnnotationTypeFilter(IAnnotatedSpecification spec) {
+			return annotationTypeFilter == null || spec.getClass().equals(annotationTypeFilter);
+		}
+
+		/**
+		 * Returns {@code true} if the column represented by the given column is visible in the
+		 * view.
+		 */
+		public boolean passesColumnFilter(ColumnHandle columnHandle) {
+			return (!filterColumnName || passesNameFilter(getColumnName(columnHandle))) &&
+					passesSelectedElementTypeFilter(columnHandle.getEntry()) &&
+					passesAnnotationTypeFilter(columnHandle.getAnnotatedSpecification());
+		}
+
+		/**
+		 * Returns {@code true} if the rows represented by {@code annotationEntry} are visible
+		 * in the view.
+		 */
+		public boolean passesRowFilter(AnnotationEntry annotationEntry) {
+			if(!(annotationEntry.getModelElement() instanceof INamedElement)) {
+				return true;
+			}
+
+			return (!filterRowName || passesNameFilter(((INamedElement)annotationEntry
+					.getModelElement()).getName())) &&
+					passesSelectedElementTypeFilter(annotationEntry);
+		}
+
+		/** Sets the model element / annotation name filter pattern. */
+		public void setNameFilterPattern(String filterPattern) {
+			this.filterPattern = filterPattern;
+		}
+
+		/** Sets the flag whether rows should be filtered by name. */
+		public void setFilterRowName(boolean filterRowName) {
+			this.filterRowName = filterRowName;
+		}
+
+		/** Sets the flag whether columns should be filtered by name. */
+		public void setColumnRowName(boolean filterColumnName) {
+			this.filterColumnName = filterColumnName;
+		}
+
+		/** Sets the flag whether the view should be filtered by the selected model element type. */
+		public void
+				setRestrictToSelectedModelElementType(boolean restrictToSelectedModelElementType) {
+			this.restrictToSelectedModelElementType = restrictToSelectedModelElementType;
+		}
+
+		/** Sets the model element hierarchy level filter option. */
+		public void setHierarchyLevelFilter(String hierarchyLevelFilter) {
+			this.hierarchyLevelFilter = hierarchyLevelFilter;
+		}
+
+		/** Sets the annotation type filter option. */
+		public void setAnnotationTypeFilter(
+				Class<? extends IAnnotatedSpecification> annotationTypeFilter) {
+			this.annotationTypeFilter = annotationTypeFilter;
 		}
 	}
 
-	/**
-	 * Returns {@code true} if a given {@code input} passes an case-insensitive filter specified by
-	 * {@code filterString}.
-	 */
-	private static boolean passesFilter(String input, String filterString) {
-		// Null-filter accepts every input
-		if(filterString == null || filterString.equals(FILTER_HINT_TEXT)) {
-			return true;
+	/** Widget to set content filters for the {@link GenericAnnotationView}. */
+	private class AnnotationFilterWidget extends Composite {
+		/** Annotation type filter: all annotations */
+		private static final String ANNOTATION_TYPE_ANY = "Show all annotations";
+
+		/** Combo box Column filter option based on annotation type */
+		private ExtendedCCombo<Class<? extends IAnnotatedSpecification>> filterAnnotationTypeCombo;
+
+		/** Constructs a new {@link AnnotationFilterWidget} */
+		public AnnotationFilterWidget(Composite parent, int style, final GenericAnnotationView view) {
+			super(parent, style);
+
+			GridLayout layout = new GridLayout(4, false);
+			layout.horizontalSpacing = 50;
+			setLayout(layout);
+
+			// Row 1: name filter scope / labels
+			Composite nameFilterScopeComposite = createNameFilterScopeComposite(this, view);
+			nameFilterScopeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true,
+					1, 1));
+
+			final Label modelElementTypefilterLabel = new Label(this, SWT.NULL);
+			modelElementTypefilterLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
+					true, 1, 1));
+			modelElementTypefilterLabel.setText("Filter model element type:");
+
+			final Label hierarchyLevelFilterLabel = new Label(this, SWT.NULL);
+			hierarchyLevelFilterLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true,
+					1, 1));
+			hierarchyLevelFilterLabel.setText("Filter model element hierarchy level:");
+
+			final Label annotationTypeFilterLabel = new Label(this, SWT.NULL);
+			annotationTypeFilterLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true,
+					1, 1));
+			annotationTypeFilterLabel.setText("Filter annotation type:");
+
+			// Row 2: controls
+			Text nameFilterText = createNameFilterText(this, view);
+			nameFilterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
+
+			Button modelElementTypeFilterButton =
+					createModelElementTypeFilterOptionsCheckButton(this, view);
+			modelElementTypeFilterButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
+					true, 1, 1));
+
+			CCombo hierarchyLevelFilterCombo =
+					createHierarchyLevelFilterOptionsComboBox(this, view);
+			hierarchyLevelFilterCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true,
+					1, 1));
+
+			ExtendedCCombo<Class<? extends IAnnotatedSpecification>> annotationTypeFilterCombo =
+					createAnnotationTypeFilterOptionsComboBox(this, view);
+			annotationTypeFilterCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true,
+					1, 1));
 		}
 
-		// Null-input cannot be accepted by a non-null filter
-		if(input == null) {
-			return false;
+		/**
+		 * Creates the {@link Text} input box for setting the pattern to filter the
+		 * {@link GenericAnnotationView} for model element or annotation names
+		 */
+		private Text createNameFilterText(Composite parent, final GenericAnnotationView view) {
+			// Text input field for filter pattern
+			final Text nameFilterText =
+					new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
+			view.getAnnotationFilter();
+			nameFilterText.setText(AnnotationFilter.FILTER_HINT_TEXT);
+			nameFilterText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY));
+
+			// Observe changes of filter pattern
+			nameFilterText.addModifyListener(new ModifyListener() {
+				@Override
+				public void modifyText(ModifyEvent e) {
+					String filterPattern = nameFilterText.getText();
+					if(filterPattern.isEmpty()) {
+						nameFilterText.setText(AnnotationFilter.FILTER_HINT_TEXT);
+						nameFilterText.selectAll();
+						filterPattern = AnnotationFilter.FILTER_HINT_TEXT;
+					}
+					if(filterPattern.equals(AnnotationFilter.FILTER_HINT_TEXT)) {
+						nameFilterText.setForeground(Display.getCurrent().getSystemColor(
+								SWT.COLOR_DARK_GRAY));
+					} else {
+						nameFilterText.setForeground(Display.getCurrent().getSystemColor(
+								SWT.COLOR_WIDGET_FOREGROUND));
+					}
+					view.getAnnotationFilter().setNameFilterPattern(filterPattern);
+					view.update();
+				}
+			});
+
+			// Select the filter pattern if it is equal to the FILTER_HINT_TEXT
+			TextFocusListener textSelectionOnFocusListener = new TextFocusListener() {
+
+				@Override
+				protected void focusOut(Text text, Event e) {
+					text.clearSelection();
+
+				}
+
+				@Override
+				protected void focusIn(Text text, Event e) {
+					if(text.getText().equals(AnnotationFilter.FILTER_HINT_TEXT) &&
+							(e.type != SWT.MouseUp || text.getSelectionCount() == 0)) {
+						text.selectAll();
+					}
+
+				}
+			};
+			nameFilterText.addListener(SWT.FocusIn, textSelectionOnFocusListener);
+			nameFilterText.addListener(SWT.FocusOut, textSelectionOnFocusListener);
+			nameFilterText.addListener(SWT.MouseDown, textSelectionOnFocusListener);
+			nameFilterText.addListener(SWT.MouseUp, textSelectionOnFocusListener);
+
+			return nameFilterText;
+		}
+
+		/**
+		 * Creates a {@link Composite} that contains radio buttons to set the scope of the name
+		 * filter (model element names or annotation names).
+		 */
+		private Composite createNameFilterScopeComposite(Composite parent,
+				final GenericAnnotationView view) {
+			Composite nameFilterScopeComposite = new Composite(parent, SWT.NULL);
+			nameFilterScopeComposite.setLayout(new RowLayout());
+
+			// Radio buttons to select between row and column name filtering
+			final Label filterLabel = new Label(nameFilterScopeComposite, SWT.NULL);
+			filterLabel.setText("Filter ");
+
+			final Button filterComponentNamesButton =
+					new Button(nameFilterScopeComposite, SWT.RADIO);
+			filterComponentNamesButton.setText("component");
+			filterComponentNamesButton.setSelection(true);
+			view.getAnnotationFilter().setFilterRowName(true);
+
+			filterComponentNamesButton.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					// widgetSelected() is also fired when the selection is removed from the radio
+					// button, so check, if this is the button that just obtained the selection
+					if(!((Button)e.getSource()).getSelection()) {
+						return;
+					}
+					view.getAnnotationFilter().setFilterRowName(true);
+					view.getAnnotationFilter().setColumnRowName(false);
+					view.update();
+				}
+			});
+
+			final Button filterAnnotationNamesButton =
+					new Button(nameFilterScopeComposite, SWT.RADIO);
+			filterAnnotationNamesButton.setText("annotation names:");
+			filterAnnotationNamesButton.setSelection(false);
+
+			filterAnnotationNamesButton.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					// widgetSelected() is also fired when the selection is removed from the radio
+					// button, so check, if this is the button that just obtained the selection
+					if(!((Button)e.getSource()).getSelection()) {
+						return;
+					}
+					view.getAnnotationFilter().setFilterRowName(false);
+					view.getAnnotationFilter().setColumnRowName(true);
+					view.update();
+				}
+			});
+
+			return nameFilterScopeComposite;
+		}
+
+		/**
+		 * Returns a {@link Button} for setting the options for filtering the
+		 * {@link GenericAnnotationView} for the currently selected model element type.
+		 * 
+		 * @param view
+		 *            {@link GenericAnnotationView} to be filtered.
+		 */
+		private Button createModelElementTypeFilterOptionsCheckButton(Composite parent,
+				final GenericAnnotationView view) {
+
+			// Check box to restrict view to currently selected model element type
+			final Button filterModelElementTypeButton = new Button(parent, SWT.CHECK);
+
+			filterModelElementTypeButton.setText("Show only selected model element type.");
+			filterModelElementTypeButton.setSelection(false);
+
+			filterModelElementTypeButton.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					// widgetSelected() is also fired when the selection is removed from the radio
+					// button, so check, if this is the button that just obtained the selection
+					view.getAnnotationFilter().setRestrictToSelectedModelElementType(
+							((Button)e.getSource()).getSelection());
+					view.update();
+				}
+			});
+
+			return filterModelElementTypeButton;
+		}
+
+		/**
+		 * Returns a {@link CCombo} for setting the options for filtering the
+		 * {@link GenericAnnotationView} for the model element hierarchy level.
+		 */
+		private CCombo createHierarchyLevelFilterOptionsComboBox(Composite parent,
+				final GenericAnnotationView view) {
+
+			// Combo box to select component hierarchy level filter
+			final CCombo filterHierarchyLevelCombo = new CCombo(parent, SWT.READ_ONLY);
+
+			filterHierarchyLevelCombo.add(AnnotationFilter.HIERARCHY_LEVELS_ALL);
+			filterHierarchyLevelCombo.add(AnnotationFilter.HIERARCHY_LEVELS_CURRENT);
+			filterHierarchyLevelCombo.add(AnnotationFilter.HIERARCHY_LEVELS_SELECTED_SUBMODEL);
+			filterHierarchyLevelCombo.select(0);
+
+			view.getAnnotationFilter().setHierarchyLevelFilter(filterHierarchyLevelCombo.getText());
+
+			filterHierarchyLevelCombo.addSelectionListener(new SelectionAdapter() {
+				/** {@inheritDoc} */
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					view.getAnnotationFilter().setHierarchyLevelFilter(
+							filterHierarchyLevelCombo.getText());
+					view.update();
+				}
+			});
+
+			return filterHierarchyLevelCombo;
+		}
+
+		/**
+		 * Returns an {@link ExtendedCCombo} for setting the options for filtering the
+		 * {@link GenericAnnotationView} for the annotation type.
+		 */
+		private ExtendedCCombo<Class<? extends IAnnotatedSpecification>>
+				createAnnotationTypeFilterOptionsComboBox(Composite parent,
+						final GenericAnnotationView view) {
+
+			// // Combo box to select annotation type filter
+			filterAnnotationTypeCombo =
+					new ExtendedCCombo<Class<? extends IAnnotatedSpecification>>(parent,
+							SWT.READ_ONLY);
+			updateAnnotationTypeFilterOptionsComboBox(lastAnnotationEntries, view);
+
+			filterAnnotationTypeCombo.addSelectionListener(new SelectionAdapter() {
+				/** {@inheritDoc} */
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					view.getAnnotationFilter().setAnnotationTypeFilter(
+							filterAnnotationTypeCombo.getObject(filterAnnotationTypeCombo
+									.getSelectionIndex()));
+					view.update();
+				}
+			});
+
+			return filterAnnotationTypeCombo;
+		}
+
+		/**
+		 * Update the combobox that can be used to configure the annotation type filter based on the
+		 * annotations contained in the current set of annotation entries / model elements (before
+		 * filtering).
+		 */
+		public void updateAnnotationTypeFilterOptionsComboBox(
+				Collection<AnnotationEntry> annotationEntries, GenericAnnotationView view) {
+			String currentSelection = filterAnnotationTypeCombo.getText();
+			filterAnnotationTypeCombo.removeAll();
+			filterAnnotationTypeCombo.add(ANNOTATION_TYPE_ANY, null);
+
+			if(annotationEntries != null) {
+				// Set needed to ensure that each IAnnotatedSpecification which may be contributed
+				// by more than one AnnotationEntry is added exactly once to the ComboBox.
+				Set<Class<? extends IAnnotatedSpecification>> annotatedSpecificationClasses =
+						new HashSet<Class<? extends IAnnotatedSpecification>>();
+
+				for(AnnotationEntry annotationEntry : annotationEntries) {
+					for(IAnnotatedSpecification spec : pickInstanceOf(
+							IAnnotatedSpecification.class, annotationEntry.getSpecificationsList())) {
+						if(!annotatedSpecificationClasses.contains(spec.getClass())) {
+							filterAnnotationTypeCombo.add(
+									"Show " +
+											annotationEntry.getSpecificationAnnotationName(spec
+													.getClass()), spec.getClass());
+							annotatedSpecificationClasses.add(spec.getClass());
+						}
+					}
+				}
+			}
+
+			// If possible, maintain selected element
+			int index = filterAnnotationTypeCombo.indexOf(currentSelection);
+			if(index == -1) {
+				filterAnnotationTypeCombo.select(0);
+				view.getAnnotationFilter().setAnnotationTypeFilter(
+						filterAnnotationTypeCombo.getObject(0));
+			} else {
+				filterAnnotationTypeCombo.select(index);
+			}
+
+			// Adjust size to new content
+			filterAnnotationTypeCombo.pack(true);
 		}
-		return input.toLowerCase().contains(filterString.toLowerCase());
 	}
 
-	/** Returns {@code true} if the column represented by the given column is visible in the view. */
-	private boolean passesFilter(ColumnHandle columnHandle, String filterPattern) {
-		if(!filterColumns) {
-			return true;
+	/** Returns the view's {@link AnnotationFilter}. */
+	private AnnotationFilter getAnnotationFilter() {
+		return annotationFilter;
+	}
+
+	/** Computes the level of an {@link IModelElement} in the tree */
+	private int getModelElementLevel(EObject o) {
+		int level = 0;
+		while(o.eContainer() != null) {
+			level++;
+			o = o.eContainer();
+		}
+
+		return level;
+	}
+
+	/**
+	 * Returns the ancestor of the {@link IModelElement} {@code modelElement} that is
+	 * {@code levelsUp} levels above model element in the hierarchy, or {@code null}, in case
+	 * {@code levelsUp} > depth(modelElement}.
+	 */
+	private EObject getModelElementAncestor(EObject o, int levelsUp) {
+		while(o.eContainer() != null && levelsUp > 0) {
+			o = o.eContainer();
+			levelsUp--;
 		}
-		return passesFilter(getColumnName(columnHandle), filterPattern);
+		return o;
+
 	}
 
 	/** Updates the table after a filter change */
@@ -386,6 +811,8 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	/** {@inheritDoc} */
 	@Override
 	protected void update(Collection<AnnotationEntry> annotationEntries) {
+		filterWidget.updateAnnotationTypeFilterOptionsComboBox(annotationEntries, this);
+
 		// Remember last annotation entries (required to re-draw table after changing the
 		// column/annotation filter
 		lastAnnotationEntries = annotationEntries;
@@ -422,7 +849,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 					for(String instanceKey : entry.getInstanceKeys(spec.getClass())) {
 						ColumnHandle columnHandle =
 								new ColumnHandle(entry, spec, instanceKey, false);
-						if(passesFilter(columnHandle, filterPattern)) {
+						if(annotationFilter.passesColumnFilter(columnHandle)) {
 							sortedColumnHandles.add(columnHandle);
 						}
 					}
@@ -438,7 +865,7 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 							new ColumnHandle(entry, spec, null,
 									entry.allowsDynamicAnnotationInstances(spec.getClass()));
 
-					if(passesFilter(columnHandle, filterPattern)) {
+					if(annotationFilter.passesColumnFilter(columnHandle)) {
 						sortedColumnHandles.add(columnHandle);
 					}
 
@@ -456,138 +883,6 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 		tableViewer.refresh();
 	}
 
-	/** Creates the UI controls for the column and row filter. */
-	private void createFilter(Composite rootComposite) {
-		// Rows (= components) are filtered using a specialized ViewerFilter.
-		// Since the data model is an array of AnnotationEntries, columns (= annotations)
-		// cannot be filtered using such a filter, and require the reconstruction of the
-		// table, with an implementation of the filter in update(Set<AnnotationEntry>).
-		final ComponentNamesRowFilter rowfilter = new ComponentNamesRowFilter();
-		rowfilter.setActive(true);
-		tableViewer.addFilter(rowfilter);
-
-		// Composite for filter GUI controls
-		Composite filterComposite = new Composite(rootComposite, SWT.NULL);
-		filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
-		filterComposite.setLayout(new GridLayout(2, false));
-
-		// Text input field for filter pattern
-		filterText =
-				new Text(filterComposite, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
-		filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
-		filterText.setText(FILTER_HINT_TEXT);
-		filterText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY));
-
-		// Observe changes of filter pattern
-		filterText.addModifyListener(new ModifyListener() {
-			@Override
-			public void modifyText(ModifyEvent e) {
-				filterPattern = filterText.getText();
-				if(filterPattern.isEmpty()) {
-					filterText.setText(FILTER_HINT_TEXT);
-					filterText.selectAll();
-					filterPattern = FILTER_HINT_TEXT;
-				}
-				if(filterPattern.equals(FILTER_HINT_TEXT)) {
-					filterText.setForeground(Display.getCurrent().getSystemColor(
-							SWT.COLOR_DARK_GRAY));
-				} else {
-					filterText.setForeground(Display.getCurrent().getSystemColor(
-							SWT.COLOR_WIDGET_FOREGROUND));
-				}
-				update();
-			}
-		});
-
-		// Select the filter pattern if it is equal to the FILTER_HINT_TEXT
-		TextFocusListener textSelectionOnFocusListener = new TextFocusListener() {
-
-			@Override
-			protected void focusOut(Text text, Event e) {
-				text.clearSelection();
-
-			}
-
-			@Override
-			protected void focusIn(Text text, Event e) {
-				if(text.getText().equals(FILTER_HINT_TEXT) &&
-						(e.type != SWT.MouseUp || text.getSelectionCount() == 0)) {
-					text.selectAll();
-				}
-
-			}
-		};
-		filterText.addListener(SWT.FocusIn, textSelectionOnFocusListener);
-		filterText.addListener(SWT.FocusOut, textSelectionOnFocusListener);
-		filterText.addListener(SWT.MouseDown, textSelectionOnFocusListener);
-		filterText.addListener(SWT.MouseUp, textSelectionOnFocusListener);
-
-		// Filter options
-		Composite filterOptionsComposite = new Composite(filterComposite, SWT.NULL);
-		filterOptionsComposite
-				.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
-		filterOptionsComposite.setLayout(new RowLayout());
-
-		// Radio buttons to select between row and column filtering
-		final Label filterLabel = new Label(filterOptionsComposite, SWT.NULL);
-		filterLabel.setText("Filter ");
-
-		final Button filterComponentNamesButton = new Button(filterOptionsComposite, SWT.RADIO);
-		filterComponentNamesButton.setText("component");
-		filterComponentNamesButton.setSelection(true);
-		filterComponentNamesButton.addSelectionListener(new SelectionAdapter() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				// widgetSelected() is also fired when the selection is removed from the radio
-				// button, so check, if this is the button that just obtained the selection
-				if(!((Button)e.getSource()).getSelection()) {
-					return;
-				}
-				rowfilter.setActive(true);
-				filterColumns = false;
-				update();
-			}
-		});
-
-		final Button filterAnnotationNamesButton = new Button(filterOptionsComposite, SWT.RADIO);
-		filterAnnotationNamesButton.setText("annotation names.");
-		filterAnnotationNamesButton.setSelection(false);
-		filterAnnotationNamesButton.addSelectionListener(new SelectionAdapter() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				// widgetSelected() is also fired when the selection is removed from the radio
-				// button, so check, if this is the button that just obtained the selection
-				if(!((Button)e.getSource()).getSelection()) {
-					return;
-				}
-				rowfilter.setActive(false);
-				filterColumns = true;
-				update();
-			}
-		});
-
-		final Label spacerLabel = new Label(filterOptionsComposite, SWT.NULL);
-		spacerLabel.setText("  ");
-
-		// Check box to restrict view to currently selected model element type
-		final Button filterModelElementType = new Button(filterOptionsComposite, SWT.CHECK);
-		filterModelElementType.setText("Show only selected model element type.");
-		filterModelElementType.setSelection(false);
-		filterModelElementType.addSelectionListener(new SelectionAdapter() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				// widgetSelected() is also fired when the selection is removed from the radio
-				// button, so check, if this is the button that just obtained the selection
-				restrictToSelectedModelElementType = ((Button)e.getSource()).getSelection();
-				update();
-			}
-		});
-
-	}
-
 	/** {@inheritDoc} */
 	@Override
 	public void createPartControl(Composite parent) {
@@ -605,7 +900,17 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 
 		tableViewer.setComparator(new HierarchicalNameComparator());
 
-		createFilter(rootComposite);
+		// Rows (= components) are filtered using a specialized ViewerFilter.
+		// Since the data model is an array of AnnotationEntries, columns (= annotations)
+		// cannot be filtered using such a filter, and require the reconstruction of the
+		// table, with an implementation of the filter in update(Set<AnnotationEntry>).
+		annotationFilter = new AnnotationFilter();
+		tableViewer.addFilter(annotationFilter);
+
+		// Add filter widget
+		filterWidget = new AnnotationFilterWidget(rootComposite, SWT.NULL, this);
+		filterWidget.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
 	}
 
 	/** Creates the (leading) column which displays the model elements */