finished event handling in RowHideShowLayer and created GlazedListsRowHideShowLayer
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
index 0054dfa..04191ed 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
@@ -56,68 +56,77 @@
 	public void handleLayerEvent(ILayerEvent event) {
 		if (event instanceof IStructuralChangeEvent) {
 			IStructuralChangeEvent structuralChangeEvent = (IStructuralChangeEvent) event;
-			if (structuralChangeEvent.isVerticalStructureChanged() && structuralChangeEvent.convertToLocal(this)) {
+			if (structuralChangeEvent.isVerticalStructureChanged()) {
 				Collection<StructuralDiff> rowDiffs = structuralChangeEvent.getRowDiffs();
-				if (rowDiffs != null) {
-					List<Integer> toRemove = new ArrayList<Integer>();
-					for (Iterator<StructuralDiff> diffIterator = rowDiffs.iterator(); diffIterator.hasNext();) {
-						StructuralDiff rowDiff = diffIterator.next();
-						if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.DELETE)) {
-							Range beforePositionRange = rowDiff.getBeforePositionRange();
-							for (Iterator<Integer> it = this.hiddenRowIndexes.iterator(); it.hasNext();) {
-								Integer hiddenRow = it.next();
-								if (hiddenRow == beforePositionRange.start) {
-									toRemove.add(hiddenRow);
-									diffIterator.remove();
-									//FIXME modify other row indexes
-								}
-							}
-						}
-					}
-					
-					handleVerticalStructureUpdates(rowDiffs);
+				if (rowDiffs != null && !rowDiffs.isEmpty()) {
+					handleRowDelete(rowDiffs);
+					handleRowInsert(rowDiffs);
 				}
 			}
 		}
 		super.handleLayerEvent(event);
 	}
 	
-	
-	protected void handleVerticalStructureUpdates(Collection<StructuralDiff> rowDiffs) {
-		for (StructuralDiff rowDiff : rowDiffs) {
+	/**
+	 * Will check for events that indicate that a rows has been deleted. In that case the stored
+	 * hidden indexes need to be updated because the index of the rows might have changed.
+	 * E.g. Row with index 3 is hidden in this layer, deleting row at index 1 will cause the row at index
+	 * 3 to be moved at index 2. Without transforming the index regarding the delete event, the wrong
+	 * row would be hidden.
+	 * @param rowDiffs The collection of {@link StructuralDiff}s to handle
+	 */
+	protected void handleRowDelete(Collection<StructuralDiff> rowDiffs) {
+		List<Integer> toRemove = new ArrayList<Integer>();
+		for (Iterator<StructuralDiff> diffIterator = rowDiffs.iterator(); diffIterator.hasNext();) {
+			StructuralDiff rowDiff = diffIterator.next();
 			if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.DELETE)) {
 				Range beforePositionRange = rowDiff.getBeforePositionRange();
-				Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
-				for (Integer hiddenRow : this.hiddenRowIndexes) {
-					if (hiddenRow != beforePositionRange.start) {
-						//the deleted row was not hidden before
-						//if it was hidden it will not be added to the new collection
-						if (hiddenRow > beforePositionRange.start) {
-							//if the hidden row was before the deleted row
-							//we need to lower the index because of missing a row
-							modifiedHiddenRows.add(hiddenRow-1);
-						}
-						else {
-							modifiedHiddenRows.add(hiddenRow);
-						}
-					}
-				}
-				RowHideShowLayer.this.hiddenRowIndexes.clear();
-				RowHideShowLayer.this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+				toRemove.add(underlyingLayer.getRowIndexByPosition(beforePositionRange.start));
 			}
-			else if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.ADD)) {
+		}
+		//remove the hidden row indexes that are deleted 
+		this.hiddenRowIndexes.removeAll(toRemove);
+		
+		//modify hidden row indexes regarding the deleted rows
+		Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
+		for (Integer hiddenRow : this.hiddenRowIndexes) {
+			//check number of removed indexes that are lower than the current one
+			int deletedBefore = 0;
+			for (Integer removed : toRemove) {
+				if (removed < hiddenRow) {
+					deletedBefore++;
+				}
+			}
+			modifiedHiddenRows.add(hiddenRow-deletedBefore);
+		}
+		this.hiddenRowIndexes.clear();
+		this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+	}
+	
+	/**
+	 * Will check for events that indicate that a rows are added. In that case the stored
+	 * hidden indexes need to be updated because the index of the rows might have changed.
+	 * E.g. Row with index 3 is hidden in this layer, adding a row at index 1 will cause the row at index
+	 * 3 to be moved to index 4. Without transforming the index regarding the add event, the wrong
+	 * row would be hidden.
+	 * @param rowDiffs The collection of {@link StructuralDiff}s to handle
+	 */
+	protected void handleRowInsert(Collection<StructuralDiff> rowDiffs) {
+		for (StructuralDiff rowDiff : rowDiffs) {
+			if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.ADD)) {
 				Range beforePositionRange = rowDiff.getBeforePositionRange();
 				Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
+				int beforeIndex = underlyingLayer.getRowIndexByPosition(beforePositionRange.start);
 				for (Integer hiddenRow : this.hiddenRowIndexes) {
-					if (hiddenRow >= beforePositionRange.start) {
+					if (hiddenRow >= beforeIndex) {
 						modifiedHiddenRows.add(hiddenRow+1);
 					}
 					else {
 						modifiedHiddenRows.add(hiddenRow);
 					}
 				}
-				RowHideShowLayer.this.hiddenRowIndexes.clear();
-				RowHideShowLayer.this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+				this.hiddenRowIndexes.clear();
+				this.hiddenRowIndexes.addAll(modifiedHiddenRows);
 			}
 		}
 	}
@@ -175,24 +184,11 @@
 		fireLayerEvent(new HideRowPositionsEvent(this, rowPositions));
 	}
 	
-	public void showRowIndexes(int[] rowIndexes) {
-		Set<Integer> rowIndexesSet = new HashSet<Integer>();
-		for (int i = 0; i < rowIndexes.length; i++) {
-			rowIndexesSet.add(Integer.valueOf(rowIndexes[i]));
-		}
-		hiddenRowIndexes.removeAll(rowIndexesSet);
+	public void showRowIndexes(Collection<Integer> rowIndexes) {
+		hiddenRowIndexes.removeAll(rowIndexes);
 		invalidateCache();
 		fireLayerEvent(new ShowRowPositionsEvent(this, getRowPositionsByIndexes(rowIndexes)));
 	}
-	
-	protected void showRowIndexes(Collection<Integer> rowIndexes) {
-		for (int rowIndex : rowIndexes) {
-			hiddenRowIndexes.remove(Integer.valueOf(rowIndex));
-		}
-		invalidateCache();
-		// Since we are exposing this method for showing individual rows, a structure event must be fired here.
-		fireLayerEvent(new ShowRowPositionsEvent(this, rowIndexes));
-	}
 
 	public void showAllRows() {
 		Collection<Integer> hiddenRows = new ArrayList<Integer>(hiddenRowIndexes);
@@ -201,7 +197,7 @@
 		fireLayerEvent(new ShowRowPositionsEvent(this, hiddenRows));
 	}
 	
-	private Collection<Integer> getRowPositionsByIndexes(int[] rowIndexes) {
+	private Collection<Integer> getRowPositionsByIndexes(Collection<Integer> rowIndexes) {
 		Collection<Integer> rowPositions = new HashSet<Integer>();
 		for (int rowIndex : rowIndexes) {
 			rowPositions.add(Integer.valueOf(getRowPositionByIndex(rowIndex)));
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
index 8dbbe85..6c9e176 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
@@ -10,23 +10,39 @@
  ******************************************************************************/
 package org.eclipse.nebula.widgets.nattable.hideshow.command;
 
+import java.util.ArrayList;
+import java.util.Collection;
+
 import org.eclipse.nebula.widgets.nattable.command.AbstractContextFreeCommand;
 
+/**
+ * Command for showing hidden rows again.
+ */
 public class MultiRowShowCommand extends AbstractContextFreeCommand {
 
-	private final int[] rowIndexes;
+	/**
+	 * The indexes of the rows that should be showed again.
+	 */
+	private final Collection<Integer> rowIndexes;
 
-	public MultiRowShowCommand(int[] rowIndexes) {
+	/**
+	 * 
+	 * @param rowIndexes The indexes of the rows that should be showed again.
+	 */
+	public MultiRowShowCommand(Collection<Integer> rowIndexes) {
 		this.rowIndexes = rowIndexes;
 	}
 
-	protected MultiRowShowCommand(MultiRowShowCommand command) {
-		rowIndexes = new int[command.rowIndexes.length];
-		System.arraycopy(command.rowIndexes, 0, rowIndexes, 0, command.rowIndexes.length);
-	}
-
-	public int[] getRowIndexes() {
+	/**
+	 * 
+	 * @return The indexes of the rows that should be showed again.
+	 */
+	public Collection<Integer> getRowIndexes() {
 		return rowIndexes;
 	}
 	
+	@Override
+	public MultiRowShowCommand cloneCommand() {
+		return new MultiRowShowCommand(new ArrayList<Integer>(this.rowIndexes));
+	}
 }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
index 5a0563e..911cb4d 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
@@ -27,8 +27,7 @@
 
 	@Override
 	protected boolean doCommand(MultiRowShowCommand command) {
-		int[] columnIndexes = command.getRowIndexes();
-		rowHideShowLayer.showRowIndexes(columnIndexes);
+		rowHideShowLayer.showRowIndexes(command.getRowIndexes());
 		return true;
 	}
 
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
index f110629..9b376f3 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
@@ -12,7 +12,6 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
@@ -134,10 +133,6 @@
 	 * @param parentIndex The index of the row that shows the node that should be collapsed
 	 */
 	public void collapseTreeRow(int parentIndex) {
-		//TODO remember the hidden rows before collapse because they will be deleted
-		//when using GlazedLists for collapse and therefore need to be restored on expand
-//		storeHiddenRowStates(this.treeRowModel.getChildIndexes(parentIndex));
-		
 		List<Integer> rowIndexes = this.treeRowModel.collapse(parentIndex);
 		List<Integer> rowPositions = new ArrayList<Integer>();
 		for (Integer rowIndex : rowIndexes) {
@@ -160,10 +155,6 @@
 		List<Integer> rowIndexes = 	this.treeRowModel.expand(parentIndex);
 		this.hiddenRowIndexes.removeAll(rowIndexes);
 		invalidateCache();
-		
-		//TODO restore the hidden states
-//		restoreHiddenRowStates();
-		
 		fireLayerEvent(new ShowRowPositionsEvent(this, rowIndexes));
 	}
 	
@@ -178,34 +169,6 @@
 		return (underlyingLayer.getRowPositionByIndex(rowIndex) == -1);
 	}
 	
-	private List<Integer> hiddenCollapsed = new ArrayList<Integer>();
-	
-	private void storeHiddenRowStates(List<Integer> collapsed) {
-		for (Integer rowIndex : collapsed) {
-			if (isHiddenInUnderlyingLayer(rowIndex)) {
-				hiddenCollapsed.add(rowIndex);
-			}
-		}
-	}
-	
-	private void restoreHiddenRowStates() {
-		List<Integer> hidePositions = new ArrayList<Integer>();
-		for (Iterator<Integer> iterator = hiddenCollapsed.iterator(); iterator.hasNext();) {
-			Integer rowIndex = iterator.next();
-			if (!isHiddenInUnderlyingLayer(rowIndex)) {
-				hidePositions.add(getRowPositionByIndex(rowIndex));
-				iterator.remove();
-			}
-		}
-		if (!hidePositions.isEmpty()) {
-			int[] positions = new int[hidePositions.size()];
-			for (int i = 0; i < hidePositions.size(); i++) {
-				positions[i] = hidePositions.get(i); 
-			}
-			new MultiRowHideCommand(this, positions);
-		}
-	}
-	
 	@Override
 	public boolean doCommand(ILayerCommand command) {
 		//special command transformations are needed to hide also child nodes
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java
new file mode 100644
index 0000000..979ff09
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.examples._500_Layers;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
+import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
+import org.eclipse.nebula.widgets.nattable.examples.data.person.Person;
+import org.eclipse.nebula.widgets.nattable.examples.data.person.PersonService;
+import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.DetailGlazedListsEventLayer;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsDataProvider;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow.GlazedListsRowHideShowLayer;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;
+import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
+import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import ca.odell.glazedlists.EventList;
+import ca.odell.glazedlists.FilterList;
+import ca.odell.glazedlists.GlazedLists;
+
+/**
+ * Simple example showing how to add the row hide/show functionality to a grid that is build
+ * using GlazedLists and how to add the corresponding actions to the row header menu.
+ * 
+ * @author Dirk Fauth
+ *
+ */
+public class _532_GlazedListsRowHideShowExample extends AbstractNatExample {
+
+	public static void main(String[] args) throws Exception {
+		StandaloneNatExampleRunner.run(new _532_GlazedListsRowHideShowExample());
+	}
+
+	@Override
+	public String getDescription() {
+		return "This example shows the usage of the row hide/show functionality within a grid and "
+				+ "its corresponding actions in the row header menu using the GlazedLists extension. "
+				+ "If you perform a right click on the row header, you are able to hide the current selected "
+				+ "row or show all rows again.";
+	}
+	
+	@Override
+	public Control createExampleControl(Composite parent) {
+		//property names of the Person class
+		String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};
+
+		//mapping from property to label, needed for column header labels
+		Map<String, String> propertyToLabelMap = new HashMap<String, String>();
+		propertyToLabelMap.put("firstName", "Firstname");
+		propertyToLabelMap.put("lastName", "Lastname");
+		propertyToLabelMap.put("gender", "Gender");
+		propertyToLabelMap.put("married", "Married");
+		propertyToLabelMap.put("birthday", "Birthday");
+
+		//build the body layer stack 
+		//Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
+		//setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
+		//directly as body layer is also working.
+		
+		//first wrap the base list in a GlazedLists EventList and a FilterList so it is possible to filter
+		EventList<Person> eventList = GlazedLists.eventList(PersonService.getPersons(10));
+		FilterList<Person> filterList = new FilterList<Person>(eventList);
+		
+		//use the GlazedListsDataProvider for some performance tweaks
+		final IRowDataProvider<Person> bodyDataProvider = new GlazedListsDataProvider<Person>(filterList, 
+				new ReflectiveColumnPropertyAccessor<Person>(propertyNames));
+		//create the IRowIdAccessor that is necessary for row hide/show
+		final IRowIdAccessor<Person> rowIdAccessor = new IRowIdAccessor<Person>() {
+			@Override
+			public Serializable getRowId(Person rowObject) {
+				return rowObject.getId();
+			}
+		};
+		
+		DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
+		
+		//add a GlazedLists event layer that is responsible for updating the grid on list changes
+		DetailGlazedListsEventLayer<Person> glazedListsEventLayer = 
+				new DetailGlazedListsEventLayer<Person>(bodyDataLayer, filterList);
+
+		GlazedListsRowHideShowLayer<Person> rowHideShowLayer = new GlazedListsRowHideShowLayer<Person>(
+				glazedListsEventLayer, bodyDataProvider, rowIdAccessor, filterList);
+		
+		SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
+		ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
+
+		//build the column header layer
+		IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
+		DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
+		ILayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
+		
+		//build the row header layer
+		IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
+		DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
+		ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);
+		
+		//build the corner layer
+		IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
+		DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
+		ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);
+		
+		//build the grid layer
+		GridLayer gridLayer = new GridLayer(viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);
+		
+		//turn the auto configuration off as we want to add our header menu configuration
+		NatTable natTable = new NatTable(parent, gridLayer, false);
+		
+		//as the autoconfiguration of the NatTable is turned off, we have to add the 
+		//DefaultNatTableStyleConfiguration manually	
+		natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
+		
+		//add the header menu configuration for adding the column header menu with hide/show actions
+		natTable.addConfiguration(new AbstractHeaderMenuConfiguration(natTable) {
+			
+			@Override
+			protected PopupMenuBuilder createRowHeaderMenu(NatTable natTable) {
+				return new PopupMenuBuilder(natTable)
+							.withHideRowMenuItem()
+							.withShowAllRowsMenuItem();
+			}
+			
+			@Override
+			protected PopupMenuBuilder createCornerMenu(NatTable natTable) {
+				return super.createCornerMenu(natTable)
+							.withHideRowMenuItem();
+			}
+		});
+		natTable.configure();
+		
+		return natTable;
+	}
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
index bb8747f..4ac3ac4 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
@@ -29,11 +29,11 @@
 	private String filename;

 	

 	@SuppressWarnings("deprecation")

-	public ExtendedPersonWithAddress(String firstName, String lastName,

+	public ExtendedPersonWithAddress(int id, String firstName, String lastName,

 			Gender gender, boolean married, Date birthday, Address address,

 			String password, String description, double money, List<String> favouriteFood, 

 			List<String> favouriteDrinks) {

-		super(firstName, lastName, gender, married, birthday, address);

+		super(id, firstName, lastName, gender, married, birthday, address);

 

 		this.password = password;

 		this.description = description;

diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
index 88999d4..a46257e 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
@@ -7,15 +7,19 @@
 		MALE, FEMALE

 	}

 	

+	private final int id;

 	private String firstName;

 	private String lastName;

 	private Gender gender;

 	private boolean married;

 	private Date birthday;

 	

-	public Person() { }

+	public Person(int id) { 

+		this.id = id;

+	}

 	

-	public Person(String firstName, String lastName, Gender gender, boolean married, Date birthday) {

+	public Person(int id, String firstName, String lastName, Gender gender, boolean married, Date birthday) {

+		this.id = id;

 		this.firstName = firstName;

 		this.lastName = lastName;

 		this.gender = gender;

@@ -24,6 +28,13 @@
 	}

 	

 	/**

+	 * @return the id

+	 */

+	public int getId() {

+		return id;

+	}

+	

+	/**

 	 * @return the firstName

 	 */

 	public String getFirstName() {

diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
index 0bb10f5..22a8b07 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
@@ -27,7 +27,7 @@
 		List<Person> result = new ArrayList<Person>();

 		

 		for (int i = 0; i < numberOfPersons; i++) {

-			result.add(createPerson());

+			result.add(createPerson(i));

 		}

 		

 		return result;

@@ -42,7 +42,7 @@
 		List<PersonWithAddress> result = new ArrayList<PersonWithAddress>();

 		

 		for (int i = 0; i < numberOfPersons; i++) {

-			result.add(new PersonWithAddress(createPerson(), createAddress()));

+			result.add(new PersonWithAddress(createPerson(i), createAddress()));

 		}

 		

 		return result;

@@ -57,7 +57,7 @@
 		List<ExtendedPersonWithAddress> result = new ArrayList<ExtendedPersonWithAddress>();

 		

 		for (int i = 0; i < numberOfPersons; i++) {

-			result.add(new ExtendedPersonWithAddress(createPerson(), createAddress(), 

+			result.add(new ExtendedPersonWithAddress(createPerson(i), createAddress(), 

 					generateSimplePassword(), createRandomLengthText(), createRandomMoneyAmount(), 

 					createFavouriteFood(), createFavouriteDrinks()));

 		}

@@ -70,14 +70,14 @@
 	 * and enrich them with random generated married state and birthday date.

 	 * @return

 	 */

-	private static Person createPerson() {

+	private static Person createPerson(int id) {

 		String[] maleNames = {"Bart", "Homer", "Lenny", "Carl", "Waylon", "Ned", "Timothy"};

 		String[] femaleNames = {"Marge", "Lisa", "Maggie", "Edna", "Helen", "Jessica"};

 		String[] lastNames = {"Simpson", "Leonard", "Carlson", "Smithers", "Flanders", "Krabappel", "Lovejoy"};

 		

 		Random randomGenerator = new Random();

 		

-		Person result = new Person();

+		Person result = new Person(id);

 		result.setGender(Gender.values()[randomGenerator.nextInt(2)]);

 		

 		if (result.getGender().equals(Gender.MALE)) {

diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
index 1e07498..4979dec 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
@@ -7,14 +7,14 @@
 

 	private Address address;

 	

-	public PersonWithAddress(String firstName, String lastName, Gender gender,

+	public PersonWithAddress(int id, String firstName, String lastName, Gender gender,

 			boolean married, Date birthday, Address address) {

-		super(firstName, lastName, gender, married, birthday);

+		super(id, firstName, lastName, gender, married, birthday);

 		this.address = address;

 	}

 

 	public PersonWithAddress(Person person, Address address) {

-		super(person.getFirstName(), person.getLastName(), person.getGender(), 

+		super(person.getId(), person.getFirstName(), person.getLastName(), person.getGender(), 

 				person.isMarried(), person.getBirthday());

 		this.address = address;

 	}

diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
index 26f4e0c..6d4ea20 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
@@ -28,7 +28,7 @@
 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsDataProvider;

 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;

 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;

-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.NewGlazedListsEventLayer;

+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.DetailGlazedListsEventLayer;

 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeData;

 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeRowModel;

 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;

@@ -104,8 +104,8 @@
 		

 //		GlazedListsEventLayer<Datum> glazedListsEventLayer = 

 //				new GlazedListsEventLayer<Datum>(bodyDataLayer, treeList);

-		NewGlazedListsEventLayer<Datum> glazedListsEventLayer = 

-				new NewGlazedListsEventLayer<Datum>(bodyDataLayer, treeList);

+		DetailGlazedListsEventLayer<Datum> glazedListsEventLayer = 

+				new DetailGlazedListsEventLayer<Datum>(bodyDataLayer, treeList);

 

 		// Body layer

 		ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(glazedListsEventLayer);

diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
index 8a216b0..3d4e19f 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@
  org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy,

  org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.action,

  org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.command,

+ org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow,

  org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree

 Import-Package: ca.odell.glazedlists,

  ca.odell.glazedlists.event,

@@ -34,6 +35,7 @@
  org.eclipse.nebula.widgets.nattable.grid.data,

  org.eclipse.nebula.widgets.nattable.grid.layer,

  org.eclipse.nebula.widgets.nattable.hideshow,

+ org.eclipse.nebula.widgets.nattable.hideshow.command,

  org.eclipse.nebula.widgets.nattable.hideshow.event,

  org.eclipse.nebula.widgets.nattable.layer,

  org.eclipse.nebula.widgets.nattable.layer.cell,

diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
similarity index 75%
rename from org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java
rename to org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
index 9ce17c7..e1f37b4 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
@@ -32,13 +32,30 @@
 import ca.odell.glazedlists.event.ListEventListener;
 
 /**
+ * This layer acts as the event listener for:
+ * <ol>
+ *    <li>Glazed list events - {@link ListEvent}
+ *    <li>Bean updates - PropertyChangeEvent(s)
+ * </ol>
+ * 
+ * Compared to the GlazedListsEventLayer, this layer does not conflate events and only
+ * fire a single RowStructuralRefreshEvent for all events within 100ms. Instead it will
+ * fire a corresponding NatTable event with the detail information for every {@link ListEvent}
+ * fired by the GlazedLists immediately.
+ * 
+ * @param <T> Type of the bean in the backing list.
+ * 
  * @author Dirk Fauth
  *
  */
-public class NewGlazedListsEventLayer<T> extends AbstractLayerTransform
+public class DetailGlazedListsEventLayer<T> extends AbstractLayerTransform
 		implements IUniqueIndexLayer, ListEventListener<T>, PropertyChangeListener {
 
-	private static final Scheduler scheduler = new Scheduler(NewGlazedListsEventLayer.class.getSimpleName());
+	/**
+	 * The scheduler needed to add cleanup tasks which are scheduled after handling
+	 * glazedlists events.
+	 */
+	private static final Scheduler scheduler = new Scheduler(DetailGlazedListsEventLayer.class.getSimpleName());
 
 	/**
 	 * The underlying layer of type {@link IUniqueIndexLayer}
@@ -57,16 +74,27 @@
 	 */
 	private EventList<T> eventList;
 	
-	
+	/**
+	 * The {@link ListEvent} that was handled before. Needed to ensure that the same event
+	 * is not processed several times. Will be reset by the cleanup task 100ms after the handling.
+	 */
 	private ListEvent<T> lastFiredEvent;
 	
-	
+	/**
+	 * The current scheduled cleanup task which is stored to ensure that at most only one cleanup
+	 * task is active at any time and it can be stopped if the NatTable itself is disposed to avoid
+	 * still active background tasks that get never be done.
+	 */
 	private ScheduledFuture<?> cleanupFuture;
 	
 	/**
-	 * @param underlyingLayer
+	 * Create a new {@link DetailGlazedListsEventLayer} which is in fact a {@link ListEventListener}
+	 * that listens to GlazedLists events and translate them into events that are understandable
+	 * by the NatTable.
+	 * @param underlyingLayer The underlying layer of type {@link IUniqueIndexLayer}
+	 * @param eventList The {@link EventList} this layer should be added as listener.
 	 */
-	public NewGlazedListsEventLayer(IUniqueIndexLayer underlyingLayer, EventList<T> eventList) {
+	public DetailGlazedListsEventLayer(IUniqueIndexLayer underlyingLayer, EventList<T> eventList) {
 		super(underlyingLayer);
 		this.underlyingLayer = underlyingLayer;
 		
@@ -115,7 +143,7 @@
 				cleanupFuture = scheduler.schedule(new Runnable() {
 					@Override
 					public void run() {
-						NewGlazedListsEventLayer.this.lastFiredEvent = null;
+						DetailGlazedListsEventLayer.this.lastFiredEvent = null;
 					}
 				}, 100L);
 			}
@@ -126,7 +154,7 @@
 	public boolean doCommand(ILayerCommand command) {
 		if (command instanceof DisposeResourcesCommand) {
 			//ensure to kill a possible running cleanup task
-			if (cleanupFuture == null || cleanupFuture.isDone() || cleanupFuture.isCancelled()) {
+			if (cleanupFuture != null && !cleanupFuture.isDone() && !cleanupFuture.isCancelled()) {
 				scheduler.unschedule(cleanupFuture);
 			}
 		}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java
new file mode 100644
index 0000000..3d89ea7
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiRowHideCommand;
+
+/**
+ * Command handler for handling {@link MultiRowHideCommand}s in a NatTable that uses GlazedLists.
+ * 
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsMultiRowHideCommandHandler<T> extends AbstractLayerCommandHandler<MultiRowHideCommand>{
+
+	/**
+	 * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+	/**
+	 * 
+	 * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	public GlazedListsMultiRowHideCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+		this.rowHideShowLayer = rowHideShowLayer;
+	}
+	
+	@Override
+	public Class<MultiRowHideCommand> getCommandClass() {
+		return MultiRowHideCommand.class;
+	}
+
+	@Override
+	protected boolean doCommand(MultiRowHideCommand command) {
+		rowHideShowLayer.hideRowPositions(command.getRowPositions());
+		return true;
+	}
+	
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java
new file mode 100644
index 0000000..c78c3ac
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiRowShowCommand;
+
+/**
+ * Command handler for handling {@link MultiRowShowCommand}s in a NatTable that uses GlazedLists.
+ * 
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsMultiRowShowCommandHandler<T> extends AbstractLayerCommandHandler<MultiRowShowCommand> {
+
+	/**
+	 * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+	
+	/**
+	 * 
+	 * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	public GlazedListsMultiRowShowCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+		this.rowHideShowLayer = rowHideShowLayer;
+	}
+	
+	@Override
+	public Class<MultiRowShowCommand> getCommandClass() {
+		return MultiRowShowCommand.class;
+	}
+
+	@Override
+	protected boolean doCommand(MultiRowShowCommand command) {
+		rowHideShowLayer.showRowIndexes(command.getRowIndexes());
+		return true;
+	}
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java
new file mode 100644
index 0000000..d07e4a0
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import static java.util.Arrays.asList;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.RowHideCommand;
+
+/**
+ * Command handler for handling {@link RowHideCommand}s in a NatTable that uses GlazedLists.
+ * 
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsRowHideCommandHandler<T> extends AbstractLayerCommandHandler<RowHideCommand> {
+	
+	/**
+	 * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+	
+	/**
+	 * 
+	 * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	public GlazedListsRowHideCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+		this.rowHideShowLayer = rowHideShowLayer;
+	}
+
+	@Override
+	public Class<RowHideCommand> getCommandClass() {
+		return RowHideCommand.class;
+	}
+
+	@Override
+	protected boolean doCommand(RowHideCommand command) {
+		rowHideShowLayer.hideRowPositions(asList(command.getRowPosition()));
+		return true;
+	}
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java
new file mode 100644
index 0000000..9d3c876
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
+
+import ca.odell.glazedlists.FilterList;
+import ca.odell.glazedlists.matchers.AbstractMatcherEditor;
+import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
+import ca.odell.glazedlists.matchers.Matcher;
+import ca.odell.glazedlists.matchers.MatcherEditor;
+
+/**
+ * Adds the functionality for manually hiding rows in a NatTable that is based on GlazedLists.
+ * Technically it will filter items by id in the {@link FilterList}.
+ * <p>
+ * Note: If you want to add row hide/show AND filtering to your NatTable, you need to use the
+ * 		 DefaultGlazedListsStaticFilterStrategy and add the {@link Matcher} that is used by
+ * 		 this command as a static {@link MatcherEditor}. Otherwise these two functions will not work
+ * 		 correctly together.
+ * 
+ * @author Dirk Fauth
+ *
+ * TODO add IPersistable 
+ */
+public class GlazedListsRowHideShowLayer<T> extends AbstractLayerTransform implements IUniqueIndexLayer {
+
+	/**
+	 * The collection of row id's that are hidden.
+	 */
+	private final Set<Serializable> rowIdsToHide = new HashSet<Serializable>();
+	
+	/**
+	 * The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+	 * This is necessary to determine the row object to hide in terms of content.
+	 */
+	private final IRowIdAccessor<T> rowIdAccessor;
+	
+	/**
+	 * The {@link IRowDataProvider} needed to get the object at a given position so it
+	 * is possible to retrieve the id that is used for filtering.
+	 */
+	private final IRowDataProvider<T> rowDataProvider;
+	
+	/**
+	 * The {@link MatcherEditor} that is used to filter the rows with the specified id's.
+	 */
+	private final HideRowMatcherEditor hideRowByIdMatcherEditor = new HideRowMatcherEditor();
+
+	/**
+	 * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+	 * NatTables. Using this constructor will only instantiate this layer. To use this correctly
+	 * you need to register the local row hide {@link MatcherEditor} against the {@link FilterList} yourself.
+	 * @param underlyingLayer The underlying layer.
+	 * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+	 * 			is possible to retrieve the id that is used for filtering.
+	 * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+	 * 			This is necessary to determine the row object to hide in terms of content.
+	 */
+	public GlazedListsRowHideShowLayer(
+			ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor) {
+		super(underlyingLayer);
+		if (rowIdAccessor == null) {
+			throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+		}
+		
+		this.rowDataProvider = rowDataProvider;
+		this.rowIdAccessor = rowIdAccessor;
+		
+		registerCommandHandlers();
+	}
+	
+	/**
+	 * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+	 * NatTables. Using this constructor will add the {@link MatcherEditor} to the given {@link FilterList}.
+	 * This might not work correctly in combination with other filters like e.g. the filter row.
+	 * @param underlyingLayer The underlying layer.
+	 * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+	 * 			is possible to retrieve the id that is used for filtering.
+	 * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+	 * 			This is necessary to determine the row object to hide in terms of content.
+	 * @param filterList The {@link FilterList} to apply the local row hide {@link Matcher} to.
+	 */
+	public GlazedListsRowHideShowLayer(
+			ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor, FilterList<T> filterList) {
+		super(underlyingLayer);
+		if (rowIdAccessor == null) {
+			throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+		}
+		if (filterList == null) {
+			throw new IllegalArgumentException("filterList can not be null!"); //$NON-NLS-1$
+		}
+		
+		this.rowDataProvider = rowDataProvider;
+		this.rowIdAccessor = rowIdAccessor;
+		
+		filterList.setMatcherEditor(this.hideRowByIdMatcherEditor);
+		
+		registerCommandHandlers();
+	}
+
+	/**
+	 * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+	 * NatTables. Using this constructor will add the {@link MatcherEditor} to the given 
+	 * {@link CompositeMatcherEditor}. This way it is possible to add more filter logic than only the 
+	 * row hide filter.
+	 * @param underlyingLayer The underlying layer.
+	 * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+	 * 			is possible to retrieve the id that is used for filtering.
+	 * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+	 * 			This is necessary to determine the row object to hide in terms of content.
+	 * @param matcherEditor The {@link CompositeMatcherEditor} to which the local row hide {@link Matcher}
+	 * 			should be added.
+	 */
+	public GlazedListsRowHideShowLayer(
+			ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor, CompositeMatcherEditor<T> matcherEditor) {
+		super(underlyingLayer);
+		if (rowIdAccessor == null) {
+			throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+		}
+		if (matcherEditor == null) {
+			throw new IllegalArgumentException("matcherEditor can not be null!"); //$NON-NLS-1$
+		}
+		
+		this.rowDataProvider = rowDataProvider;
+		this.rowIdAccessor = rowIdAccessor;
+		
+		matcherEditor.getMatcherEditors().add(this.hideRowByIdMatcherEditor);
+		
+		registerCommandHandlers();
+	}
+
+	/**
+	 * Register the {@link ILayerCommandHandler} that will handle the row hide/show events
+	 * for this layer.
+	 */
+	protected void registerCommandHandlers() {
+		registerCommandHandler(new GlazedListsRowHideCommandHandler<T>(this));
+		registerCommandHandler(new GlazedListsMultiRowHideCommandHandler<T>(this));
+		registerCommandHandler(new GlazedListsShowAllRowsCommandHandler<T>(this));
+		registerCommandHandler(new GlazedListsMultiRowShowCommandHandler<T>(this));
+	}
+	
+	/**
+	 * Hide the rows at the given positions. Will collect the id's of the rows at
+	 * the given positions as this layer operates on content rather than positions.
+	 * @param rowPositions The positions of the rows to hide.
+	 */
+	public void hideRowPositions(Collection<Integer> rowPositions) {
+		Collection<Serializable> rowIds = new HashSet<Serializable>();
+		for (Integer rowPos : rowPositions) {
+			int rowIndex = getRowIndexByPosition(rowPos);
+			rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+		}
+		hideRows(rowIds);
+	}
+	
+	/**
+	 * Hide the rows at the given indexes. Will collect the id's of the rows at
+	 * the given positions as this layer operates on content rather than positions.
+	 * @param rowIndexes The indexes of the rows to hide.
+	 */
+	public void hideRowIndexes(Collection<Integer> rowIndexes) {
+		Collection<Serializable> rowIds = new HashSet<Serializable>();
+		for (Integer rowIndex : rowIndexes) {
+			rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+		}
+		hideRows(rowIds);
+	}
+	
+	/**
+	 * Show the rows with the given indexes again. Will collect the id's of the rows at
+	 * the given positions as this layer operates on content rather than positions.
+	 * @param rowIndexes The indexes of the rows that should be showed again.
+	 */
+	public void showRowIndexes(Collection<Integer> rowIndexes) {
+		Collection<Serializable> rowIds = new HashSet<Serializable>();
+		for (Integer rowIndex : rowIndexes) {
+			rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+		}
+		showRows(rowIds);
+	}
+	
+	/**
+	 * Hide the rows that contain the objects with the given row ids.
+	 * @param rowIds The row ids of the rows that should be hidden.
+	 */
+	public void hideRows(Collection<Serializable> rowIds) {
+		this.rowIdsToHide.addAll(rowIds);
+		this.hideRowByIdMatcherEditor.fireChange();
+	}
+
+	/**
+	 * Show the rows that contain the objects with the given row ids.
+	 * Will of course only have impact if those rows are currently hidden.
+	 * @param rowIds The row ids of the rows that should be showed.
+	 */
+	public void showRows(Collection<Serializable> rowIds) {
+		this.rowIdsToHide.removeAll(rowIds);
+		this.hideRowByIdMatcherEditor.fireChange();
+	}
+
+	/**
+	 * Show all rows that where previously hidden.
+	 */
+	public void showAllRows() {
+		this.rowIdsToHide.clear();
+		this.hideRowByIdMatcherEditor.fireChange();
+	}
+	
+	/**
+	 * @return The {@link MatcherEditor} that is used to filter the rows with the specified id's.
+	 */
+	public MatcherEditor<T> getMatcherEditor() {
+		return this.hideRowByIdMatcherEditor;
+	}
+
+	@Override
+	public int getColumnPositionByIndex(int columnIndex) {
+		return ((IUniqueIndexLayer) getUnderlyingLayer()).getColumnPositionByIndex(columnIndex);
+	}
+
+	@Override
+	public int getRowPositionByIndex(int rowIndex) {
+		return ((IUniqueIndexLayer) getUnderlyingLayer()).getRowPositionByIndex(rowIndex);
+	}
+	
+	/**
+	 * {@link MatcherEditor} implementation that will only match objects that are not hidden by
+	 * id. It also enables to fire change events to indicate changes to the filter.
+	 * 
+	 * @author Dirk Fauth
+	 *
+	 */
+	class HideRowMatcherEditor extends AbstractMatcherEditor<T> {
+		/**
+		 * The {@link Matcher} that is used to filter the rows with the specified id's.
+		 */
+		private final Matcher<T> hideRowByIdMatcher = new Matcher<T>() {
+			@Override
+			public boolean matches(T rowObject) {
+				return !rowIdsToHide.contains(rowIdAccessor.getRowId(rowObject));
+			}
+		};
+		
+		@Override
+		public Matcher<T> getMatcher() {
+			return this.hideRowByIdMatcher;
+		}
+		
+		/**
+		 * Fire a change so the listeners can be informed about a change for the {@link Matcher}
+		 */
+		public void fireChange() {
+			fireChanged(this.hideRowByIdMatcher);
+		}
+	}
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java
new file mode 100644
index 0000000..9a1e021
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.ShowAllRowsCommand;
+
+/**
+ * Command handler to show all rows again that are currently hidden in the context of 
+ * using GlazedLists.
+ * 
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsShowAllRowsCommandHandler<T> extends AbstractLayerCommandHandler<ShowAllRowsCommand> {
+	
+	/**
+	 * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+	 */
+	private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+	/**
+	 * 
+	 * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} to operate on.
+	 */
+	public GlazedListsShowAllRowsCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+		this.rowHideShowLayer = rowHideShowLayer;
+	}
+	
+	@Override
+	public Class<ShowAllRowsCommand> getCommandClass() {
+		return ShowAllRowsCommand.class;
+	}
+
+	@Override
+	protected boolean doCommand(ShowAllRowsCommand command) {
+		rowHideShowLayer.showAllRows();
+		return true;
+	}
+	
+}