Bug 562423 - Extend ILayer interface

Change-Id: Ic1eb46f266ad9c728d27bdcd9057694151668b42
Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
diff --git a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/fixture/TestLayer.java b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/fixture/TestLayer.java
index f260e26..f2543d9 100644
--- a/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/fixture/TestLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core.test/src/org/eclipse/nebula/widgets/nattable/test/fixture/TestLayer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -16,7 +16,6 @@
 
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.ILayer;
@@ -440,8 +439,7 @@
     }
 
     @Override
-    public void configure(ConfigRegistry configRegistry,
-            UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         // Do nothing
     }
 
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java
index 8a25751..e672420 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/NatTable.java
@@ -12,7 +12,6 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -41,7 +40,6 @@
 import org.eclipse.nebula.widgets.nattable.edit.editor.ICellEditor;
 import org.eclipse.nebula.widgets.nattable.grid.command.ClientAreaResizeCommand;
 import org.eclipse.nebula.widgets.nattable.grid.command.InitializeGridCommand;
-import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
 import org.eclipse.nebula.widgets.nattable.layer.DefaultHorizontalDpiConverter;
 import org.eclipse.nebula.widgets.nattable.layer.DefaultVerticalDpiConverter;
 import org.eclipse.nebula.widgets.nattable.layer.IDpiConverter;
@@ -680,7 +678,7 @@
     }
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         throw new UnsupportedOperationException("Cannot use this method to configure NatTable. Use no-argument configure() instead."); //$NON-NLS-1$
     }
 
@@ -696,8 +694,7 @@
         }
 
         if (this.underlyingLayer != null) {
-            this.underlyingLayer.configure((ConfigRegistry) getConfigRegistry(),
-                    getUiBindingRegistry());
+            this.underlyingLayer.configure(getConfigRegistry(), getUiBindingRegistry());
         }
 
         for (IConfiguration configuration : this.configurations) {
@@ -1293,10 +1290,8 @@
      *
      * @since 1.4
      */
+    @Override
     public Collection<String> getProvidedLabels() {
-        if (this.underlyingLayer instanceof AbstractLayer) {
-            return ((AbstractLayer) this.underlyingLayer).getProvidedLabels();
-        }
-        return Collections.emptySet();
+        return this.underlyingLayer.getProvidedLabels();
     }
 }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/config/IConfiguration.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/config/IConfiguration.java
index 6836da1..a6667df 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/config/IConfiguration.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/config/IConfiguration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -22,17 +22,23 @@
  * These will be processed when {@link NatTable#configure()} is invoked.
  *
  * Default configurations are added to most layers
- * {@link AbstractLayer#addConfiguration(IConfiguration)}. You can turn off
- * default configuration for an {@link ILayer} by setting auto configure to
- * false in the constructor.
+ * {@link AbstractLayer#addConfiguration(IConfiguration)}. Typically you can
+ * turn off default configurations for an {@link ILayer} by setting
+ * autoconfigure to <code>false</code> in the constructor.
  */
 public interface IConfiguration {
 
+    /**
+     * Perform configurations on the provided layer.
+     *
+     * @param layer
+     *            The {@link ILayer} to configure.
+     */
     public void configureLayer(ILayer layer);
 
     /**
-     * Configure NatTable's {@link IConfigRegistry} upon receiving this call
-     * back. A mechanism to plug-in custom {@link ICellPainter},
+     * Configure NatTable's {@link IConfigRegistry} upon receiving this
+     * callback. A mechanism to plug-in custom {@link ICellPainter},
      * {@link IDataValidator} etc.
      *
      * @param configRegistry
@@ -42,8 +48,8 @@
     public void configureRegistry(IConfigRegistry configRegistry);
 
     /**
-     * Configure NatTable's {@link IConfigRegistry} upon receiving this call
-     * back A mechanism to customize key/mouse bindings.
+     * Configure NatTable's {@link UiBindingRegistry} upon receiving this
+     * callback. A mechanism to customize key/mouse bindings.
      *
      * @param uiBindingRegistry
      *            The {@link UiBindingRegistry} instance to register ui bindings
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java
index 855a224..d52174a 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/edit/editor/AbstractCellEditor.java
@@ -467,8 +467,6 @@
         return cellBounds;
     }
 
-    // TODO move to interface
-
     /**
      * This method can be used to set the {@link IDataValidator} to use. This
      * might be useful e.g. the configured validator needs to be wrapped to add
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/grid/layer/DimensionallyDependentLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/grid/layer/DimensionallyDependentLayer.java
index 3697e5f..4e91890 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/grid/layer/DimensionallyDependentLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/grid/layer/DimensionallyDependentLayer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2016 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -16,7 +16,7 @@
 
 import org.eclipse.nebula.widgets.nattable.command.AbstractRegionCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
 import org.eclipse.nebula.widgets.nattable.layer.ILayer;
@@ -96,7 +96,7 @@
     // Configuration
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         this.baseLayer.configure(configRegistry, uiBindingRegistry);
         super.configure(configRegistry, uiBindingRegistry);
     }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractIndexLayerTransform.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractIndexLayerTransform.java
index 5cb625c..ba2164c 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractIndexLayerTransform.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractIndexLayerTransform.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -16,7 +16,6 @@
 import java.util.Properties;
 
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
@@ -40,7 +39,8 @@
 
     private IUniqueIndexLayer underlyingLayer;
 
-    public AbstractIndexLayerTransform() {}
+    public AbstractIndexLayerTransform() {
+    }
 
     public AbstractIndexLayerTransform(IUniqueIndexLayer underlyingLayer) {
         setUnderlyingLayer(underlyingLayer);
@@ -88,7 +88,7 @@
     // Configuration
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         super.configure(configRegistry, uiBindingRegistry);
         this.underlyingLayer.configure(configRegistry, uiBindingRegistry);
     }
@@ -386,7 +386,6 @@
 
     @Override
     public boolean isDynamicSizeLayer() {
-        return this.underlyingLayer instanceof AbstractLayer
-                && ((AbstractLayer) this.underlyingLayer).isDynamicSizeLayer();
+        return this.underlyingLayer.isDynamicSizeLayer();
     }
 }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayer.java
index 2c6ad7a..26c810b 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayer.java
@@ -29,7 +29,6 @@
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
 import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfiguration;
 import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
@@ -161,7 +160,7 @@
     }
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         if (!this.configurationApplied) {
             for (IConfiguration configuration : this.configurations) {
                 configuration.configureLayer(this);
@@ -414,6 +413,7 @@
      *         or a fixed size.
      * @since 1.4
      */
+    @Override
     public boolean isDynamicSizeLayer() {
         return false;
     }
@@ -422,13 +422,14 @@
      * @return The collection of labels that are provided by this layer.
      * @since 1.4
      */
+    @Override
     public Collection<String> getProvidedLabels() {
         Collection<String> labels = null;
 
-        if (getUnderlyingLayerByPosition(0, 0) instanceof AbstractLayer) {
-            labels = ((AbstractLayer) getUnderlyingLayerByPosition(0, 0)).getProvidedLabels();
+        if (getUnderlyingLayerByPosition(0, 0) != null) {
+            labels = getUnderlyingLayerByPosition(0, 0).getProvidedLabels();
         } else {
-            labels = new LinkedHashSet<String>();
+            labels = new LinkedHashSet<>();
         }
 
         // add the region
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayerTransform.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayerTransform.java
index d5315ec..a1a22a9 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayerTransform.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/AbstractLayerTransform.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2018 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -16,7 +16,6 @@
 import java.util.Properties;
 
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
@@ -39,7 +38,8 @@
 
     protected ILayer underlyingLayer;
 
-    public AbstractLayerTransform() {}
+    public AbstractLayerTransform() {
+    }
 
     public AbstractLayerTransform(ILayer underlyingLayer) {
         setUnderlyingLayer(underlyingLayer);
@@ -84,7 +84,7 @@
     // Configuration
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         this.underlyingLayer.configure(configRegistry, uiBindingRegistry);
         super.configure(configRegistry, uiBindingRegistry);
     }
@@ -390,7 +390,7 @@
 
     @Override
     public boolean isDynamicSizeLayer() {
-        return ((AbstractLayer) this.underlyingLayer).isDynamicSizeLayer();
+        return this.underlyingLayer.isDynamicSizeLayer();
     }
 
 }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/CompositeLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/CompositeLayer.java
index c3f749b..d3337d6 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/CompositeLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/CompositeLayer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2018 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -21,7 +21,6 @@
 
 import org.eclipse.nebula.widgets.nattable.command.AbstractRegionCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.cell.AggregateConfigLabelAccumulator;
@@ -115,7 +114,7 @@
     // Configuration
 
     @Override
-    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         for (int layoutX = 0; layoutX < this.layoutXCount; layoutX++) {
             for (int layoutY = 0; layoutY < this.layoutYCount; layoutY++) {
                 this.childLayerLayout[layoutX][layoutY].configure(
@@ -696,7 +695,7 @@
 
         final Rectangle compositeClientArea = getClientAreaProvider().getClientArea();
 
-        if (childLayer instanceof AbstractLayer && ((AbstractLayer) childLayer).isDynamicSizeLayer()) {
+        if (childLayer.isDynamicSizeLayer()) {
 
             // check if there are further sections to the bottom and reduce the
             // height accordingly necessary in case the current child layer is
@@ -1010,8 +1009,7 @@
     public boolean isDynamicSizeLayer() {
         for (int layoutX = 0; layoutX < this.layoutXCount; layoutX++) {
             for (int layoutY = 0; layoutY < this.layoutYCount; layoutY++) {
-                if (this.childLayerLayout[layoutX][layoutY] instanceof AbstractLayer
-                        && ((AbstractLayer) this.childLayerLayout[layoutX][layoutY]).isDynamicSizeLayer()) {
+                if (this.childLayerLayout[layoutX][layoutY].isDynamicSizeLayer()) {
                     return true;
                 }
             }
@@ -1034,9 +1032,7 @@
                     labels.addAll(((IConfigLabelProvider) accumulator).getProvidedLabels());
                 }
 
-                if (childLayer instanceof AbstractLayer) {
-                    labels.addAll(((AbstractLayer) childLayer).getProvidedLabels());
-                }
+                labels.addAll(childLayer.getProvidedLabels());
             }
         }
         return labels;
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/ILayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/ILayer.java
index 624348a..ae45531 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/ILayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/ILayer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
+ * Copyright (c) 2012, 2020 Original authors 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
@@ -11,12 +11,12 @@
 package org.eclipse.nebula.widgets.nattable.layer;
 
 import java.util.Collection;
+import java.util.LinkedHashSet;
 import java.util.Properties;
 
 import org.eclipse.nebula.widgets.nattable.NatTable;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
@@ -25,7 +25,6 @@
 import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
 import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter;
 import org.eclipse.nebula.widgets.nattable.persistence.IPersistable;
-import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
 import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
 import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
 import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
@@ -91,48 +90,63 @@
 
     // Dispose
 
+    /**
+     * Dispose any resource allocated by this layer.
+     */
     public void dispose();
 
     // Persistence
 
     /**
-     * Persistables registered with a layer will have a chance to write their
-     * data out to the {@link Properties} instance when the layer is persisted.
+     * Register an {@link IPersistable} that can write its state to the state
+     * {@link Properties} instance when the layer is persisted.
      *
      * @param persistable
-     *            the persistable to be registered
+     *            The persistable that should be registered.
      */
     public void registerPersistable(IPersistable persistable);
 
+    /**
+     * Unregister the given {@link IPersistable}.
+     *
+     * @param persistable
+     *            The persistable to unregister.
+     */
     public void unregisterPersistable(IPersistable persistable);
 
     // Configuration
 
     /**
-     * Every layer gets this call back, starting at the top of the stack. This
-     * is triggered by the {@link NatTable#configure()} method. This is an
-     * opportunity to add any key/mouse bindings and other general
+     * Configure this layer, e.g. add any key/mouse bindings and other general
      * configuration.
+     * <p>
+     * This method is triggered by {@link NatTable#configure()} and executed
+     * down the layer stack.
+     * </p>
      *
      * @param configRegistry
-     *            instance owned by {@link NatTable}
+     *            The {@link IConfigRegistry} instance owned by the
+     *            {@link NatTable} this layer is attached to.
      * @param uiBindingRegistry
-     *            instance owned by {@link NatTable}
+     *            The {@link UiBindingRegistry} instance owned by
+     *            {@link NatTable} this layer is attached to.
+     *
+     * @since 2.0
      */
-    public void configure(ConfigRegistry configRegistry,
-            UiBindingRegistry uiBindingRegistry);
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry);
 
     // Region
 
     /**
-     * Layer can apply its own labels to any cell it wishes.
+     * Return the {@link LabelStack} containing the region labels for the cell
+     * at the given pixel position.
      *
      * @param x
      *            the x pixel coordinate
      * @param y
      *            the y pixel coordinate
-     * @return a LabelStack containing the region labels for the cell at the
-     *         given pixel position
+     * @return LabelStack containing the region labels for the cell at the given
+     *         pixel position.
      */
     public LabelStack getRegionLabelsByXY(int x, int y);
 
@@ -142,21 +156,37 @@
      * Opportunity to respond to a command as it flows down the stack. If the
      * layer is not interested in the command it should allow the command to
      * keep traveling down the stack.
-     *
-     * Note: Before the layer can process a command it <i>must</i> convert the
-     * command to its local co-ordinates using
+     * <p>
+     * <b>Note:</b> Before the layer can process a command it <i>must</i>
+     * convert the command to its local coordinates using
      * {@link ILayerCommand#convertToTargetLayer(ILayer)}
      *
      * @param command
-     *            the command to perform
-     * @return true if the command has been handled, false otherwise
+     *            The command to execute.
+     * @return <code>true</code> if the command has been handled and was
+     *         therefore consumed, <code>false</code> otherwise.
      */
     public boolean doCommand(ILayerCommand command);
 
+    /**
+     * Register an {@link ILayerCommandHandler} to handle a command in this
+     * layer. Only one {@link ILayerCommandHandler} per {@link ILayerCommand}
+     * can be registered per layer.
+     *
+     * @param commandHandler
+     *            The command handler to register with this layer.
+     */
     public void registerCommandHandler(ILayerCommandHandler<?> commandHandler);
 
-    public void unregisterCommandHandler(
-            Class<? extends ILayerCommand> commandClass);
+    /**
+     * Unregister the {@link ILayerCommandHandler} that is registered for the
+     * given {@link ILayerCommand} class.
+     *
+     * @param commandClass
+     *            The {@link ILayerCommand} class for which the
+     *            {@link ILayerCommandHandler} should be unregistered.
+     */
+    public void unregisterCommandHandler(Class<? extends ILayerCommand> commandClass);
 
     // Events
 
@@ -172,27 +202,56 @@
      */
     public void fireLayerEvent(ILayerEvent event);
 
+    /**
+     * Add a general {@link ILayerListener} to handle {@link ILayerEvent}s on
+     * this layer.
+     *
+     * @param listener
+     *            The {@link ILayerListener} to add.
+     */
     public void addLayerListener(ILayerListener listener);
 
+    /**
+     * Remove the given {@link ILayerListener} from this layer.
+     *
+     * @param listener
+     *            The {@link ILayerListener} to remove.
+     */
     public void removeLayerListener(ILayerListener listener);
 
     /**
+     * Check if an {@link ILayerListener} of the given type is registered on
+     * this layer or not.
+     *
      * @param layerListenerClass
-     *            The type of {@link ILayerListener} to check for existence
+     *            The type of {@link ILayerListener} to check for.
      * @return <code>true</code> if this {@link ILayer} has a
-     *         {@link ILayerListener} registered for the specified type,
-     *         <code>false</code> if there is no such listener registered
-     *         already
+     *         {@link ILayerListener} of the specified type registered,
+     *         <code>false</code> if there is no such listener registered.
      */
-    public boolean hasLayerListener(
-            Class<? extends ILayerListener> layerListenerClass);
+    public boolean hasLayerListener(Class<? extends ILayerListener> layerListenerClass);
 
+    /**
+     *
+     * @return The {@link ILayerPainter} used to render this layer.
+     */
     public ILayerPainter getLayerPainter();
 
     // Client area
 
+    /**
+     *
+     * @return The {@link IClientAreaProvider} that specifies the rectangular
+     *         area available on this layer.
+     */
     public IClientAreaProvider getClientAreaProvider();
 
+    /**
+     *
+     * @param clientAreaProvider
+     *            The {@link IClientAreaProvider} that specifies the rectangular
+     *            area available on this layer.
+     */
     public void setClientAreaProvider(IClientAreaProvider clientAreaProvider);
 
     // Horizontal features
@@ -200,7 +259,7 @@
     // Columns
 
     /**
-     * @return the number of columns in this coordinate model
+     * @return The number of columns in this layer.
      */
     public int getColumnCount();
 
@@ -208,12 +267,12 @@
 
     /**
      * Gets the underlying non-transformed column index for the given column
-     * position.
+     * position on this layer.
      *
      * @param columnPosition
-     *            a column position relative to this coordinate model
-     * @return an underlying non-transformed column index, or -1 if the given
-     *         column position does not exist within this coordinate system
+     *            The column position relative to this layer.
+     * @return An underlying non-transformed column index, or -1 if the given
+     *         column position does not exist within this coordinate system.
      */
     public int getColumnIndexByPosition(int columnPosition);
 
@@ -227,9 +286,34 @@
      */
     public int localToUnderlyingColumnPosition(int localColumnPosition);
 
-    public int underlyingToLocalColumnPosition(ILayer sourceUnderlyingLayer,
+    /**
+     * Transforms the column position relative to the given underlying layer to
+     * this layer coordinates.
+     *
+     * @param sourceUnderlyingLayer
+     *            The underlying layer to which the given column position
+     *            matches.
+     * @param underlyingColumnPosition
+     *            The column position in the given underlying layer that should
+     *            be converted to a local column position.
+     * @return The given column position transformed to be local to this layer.
+     */
+    public int underlyingToLocalColumnPosition(
+            ILayer sourceUnderlyingLayer,
             int underlyingColumnPosition);
 
+    /**
+     * Transforms the column position ranges relative to the given underlying
+     * layer to this layer coordinates.
+     *
+     * @param sourceUnderlyingLayer
+     *            The underlying layer to which the given column positions
+     *            match.
+     * @param underlyingColumnPositionRanges
+     *            The column position ranges relative to the given underlying
+     *            layer that should be converted to local column positions.
+     * @return The given column position ranges transformed to this layer.
+     */
     public Collection<Range> underlyingToLocalColumnPositions(
             ILayer sourceUnderlyingLayer,
             Collection<Range> underlyingColumnPositionRanges);
@@ -239,7 +323,7 @@
     /**
      * Returns the total width in pixels of this layer.
      *
-     * @return the width of this layer
+     * @return The total width in pixels of this layer.
      */
     public int getWidth();
 
@@ -251,14 +335,22 @@
      * The width of invisible and non-existing columns is 0.
      *
      * @param columnPosition
-     *            the column position in this layer
+     *            The column position in this layer.
      *
-     * @return the width of the column
+     * @return The width of the column.
      */
     public int getColumnWidthByPosition(int columnPosition);
 
     // Column resize
 
+    /**
+     * Check if the column at the given position is resizable.
+     *
+     * @param columnPosition
+     *            The column position to check.
+     * @return <code>true</code> if the column is resizable, <code>false</code>
+     *         if not.
+     */
     public boolean isColumnPositionResizable(int columnPosition);
 
     // X
@@ -267,10 +359,10 @@
      * Returns the column position that contains the given x coordinate.
      *
      * @param x
-     *            a horizontal pixel location relative to the pixel boundary of
-     *            this layer
-     * @return a column position relative to the associated coordinate system,
-     *         or -1 if there is no column that contains x
+     *            A horizontal pixel location relative to the pixel boundary of
+     *            this layer.
+     * @return A column position relative to the associated coordinate system,
+     *         or -1 if there is no column that contains x.
      */
     public int getColumnPositionByX(int x);
 
@@ -278,42 +370,87 @@
      * Returns the x offset in pixels of the given column.
      *
      * @param columnPosition
-     *            the column position in this layer
-     * @return the x offset of the column, or -1
+     *            The column position in this layer.
+     * @return The x offset of the column, or -1.
      */
     public int getStartXOfColumnPosition(int columnPosition);
 
     // Underlying
 
-    public Collection<ILayer> getUnderlyingLayersByColumnPosition(
-            int columnPosition);
+    /**
+     * Returns the layers that are directly below this layer for the given
+     * column position. For simple layers this collection will typically only
+     * have one entry. Layer compositions might return multiple values, e.g. in
+     * a default grid there will be 2 layers in the collection as there are two
+     * layers involved in a column.
+     *
+     * @param columnPosition
+     *            The column position for which the underlying layers are
+     *            requested.
+     * @return The layers that are directly below this layer for the given
+     *         column position or <code>null</code> if this layer has no
+     *         underlying layers.
+     */
+    public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition);
 
     // Vertical features
 
     // Rows
 
     /**
-     * @return the number of rows in this coordinate model
+     * @return The number of rows in this layer.
      */
     public int getRowCount();
 
     public int getPreferredRowCount();
 
     /**
-     * Gets the underlying non-transformed row index for the given row position.
+     * Gets the underlying non-transformed row index for the given row position
+     * on this layer.
      *
      * @param rowPosition
-     *            a row position relative to this coordinate model
-     * @return an underlying non-transformed row index, or -1 if the given row
-     *         position does not exist within this coordinate system
+     *            The row position relative to this layer.
+     * @return An underlying non-transformed row index, or -1 if the given row
+     *         position does not exist within this coordinate system.
      */
     public int getRowIndexByPosition(int rowPosition);
 
+    /**
+     * Convert a row position to the coordinates of the underlying layer. This
+     * is possible since each layer is aware of its underlying layer.
+     *
+     * @param localRowPosition
+     *            row position in local (the layer's own) coordinates
+     * @return row position in the underlying layer's coordinates
+     */
     public int localToUnderlyingRowPosition(int localRowPosition);
 
-    public int underlyingToLocalRowPosition(ILayer sourceUnderlyingLayer,
+    /**
+     * Transforms the row position relative to the given underlying layer to
+     * this layer coordinates.
+     *
+     * @param sourceUnderlyingLayer
+     *            The underlying layer to which the given row position matches.
+     * @param underlyingRowPosition
+     *            The row position in the given underlying layer that should be
+     *            converted to a local row position.
+     * @return The given row position transformed to be local to this layer.
+     */
+    public int underlyingToLocalRowPosition(
+            ILayer sourceUnderlyingLayer,
             int underlyingRowPosition);
 
+    /**
+     * Transforms the row position ranges relative to the given underlying layer
+     * to this layer coordinates.
+     *
+     * @param sourceUnderlyingLayer
+     *            The underlying layer to which the given row positions match.
+     * @param underlyingRowPositionRanges
+     *            The row position ranges relative to the given underlying layer
+     *            that should be converted to local row positions.
+     * @return The given row position ranges transformed to this layer.
+     */
     public Collection<Range> underlyingToLocalRowPositions(
             ILayer sourceUnderlyingLayer,
             Collection<Range> underlyingRowPositionRanges);
@@ -323,7 +460,7 @@
     /**
      * Returns the total height in pixels of this layer.
      *
-     * @return the height of this layer
+     * @return The total height in pixels of this layer.
      */
     public int getHeight();
 
@@ -335,14 +472,22 @@
      * The height of invisible and non-existing rows is 0.
      *
      * @param rowPosition
-     *            the row position in this layer
+     *            The row position in this layer.
      *
-     * @return the height of the row
+     * @return The height of the row.
      */
     public int getRowHeightByPosition(int rowPosition);
 
     // Row resize
 
+    /**
+     * Check if the row at the given position is resizable.
+     *
+     * @param rowPosition
+     *            The row position to check.
+     * @return <code>true</code> if the row is resizable, <code>false</code> if
+     *         not.
+     */
     public boolean isRowPositionResizable(int rowPosition);
 
     // Y
@@ -370,10 +515,34 @@
 
     // Underlying
 
+    /**
+     * Returns the layers that are directly below this layer for the given row
+     * position. For simple layers this collection will typically only have one
+     * entry. Layer compositions might return multiple values, e.g. in a default
+     * grid there will be 2 layers in the collection as there are two layers
+     * involved in a row.
+     *
+     * @param rowPosition
+     *            The row position for which the underlying layers are
+     *            requested.
+     * @return The layers that are directly below this layer for the given row
+     *         position or <code>null</code> if this layer has no underlying
+     *         layers.
+     */
     public Collection<ILayer> getUnderlyingLayersByRowPosition(int rowPosition);
 
     // Cell features
 
+    /**
+     * Returns the cell for the given coordinates on this layer.
+     *
+     * @param columnPosition
+     *            The column position of the requested cell.
+     * @param rowPosition
+     *            The row position of the requested cell.
+     * @return The {@link ILayerCell} for the given coordinates in this layer or
+     *         <code>null</code> if the coordinates are invalid on this layer.
+     */
     public ILayerCell getCellByPosition(int columnPosition, int rowPosition);
 
     /**
@@ -389,28 +558,99 @@
     public Rectangle getBoundsByPosition(int columnPosition, int rowPosition);
 
     /**
+     * Returns the active {@link DisplayMode} for the cell at the given
+     * coordinates. Needed to retrieve the corresponding configurations out of
+     * the {@link IConfigRegistry}. The default value is
+     * {@link DisplayMode#NORMAL}. The SelectionLayer for example overrides this
+     * to return {@link DisplayMode#SELECT} for cells that are currently
+     * selected.
+     *
      * @param columnPosition
-     *            the column position of the cell
+     *            The column position of the cell.
      * @param rowPosition
-     *            the row position of the cell
-     * @return {@link DisplayMode} for the cell at the given position. The
-     *         {@link DisplayMode} affects the settings out of the
-     *         {@link ConfigRegistry}. Display mode is <i>NORMAL</i> by default.
-     *         <p>
-     *         <b>Example:</b> {@link SelectionLayer} overrides this to return
-     *         the <i>SELECT</i> label for cells which are selected.
+     *            The row position of the cell.
+     * @return {@link DisplayMode} for the cell at the given coordinates.
      */
     public String getDisplayModeByPosition(int columnPosition, int rowPosition);
 
-    public LabelStack getConfigLabelsByPosition(int columnPosition,
-            int rowPosition);
+    /**
+     * Returns the config labels for the cell at the given coordinates. Needed
+     * to retrieve the corresponding configurations out of the
+     * {@link IConfigRegistry}.
+     *
+     * @param columnPosition
+     *            The column position of the cell.
+     * @param rowPosition
+     *            The row position of the cell.
+     * @return The {@link LabelStack} with the config labels for the cell at the
+     *         given coordinates.
+     */
+    public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition);
 
+    /**
+     * Returns the data value for the cell at the given coordinates.
+     *
+     * @param columnPosition
+     *            The column position of the cell.
+     * @param rowPosition
+     *            The row position of the cell.
+     * @return The data value for the cell at the given coordinates.
+     */
     public Object getDataValueByPosition(int columnPosition, int rowPosition);
 
-    public ILayer getUnderlyingLayerByPosition(int columnPosition,
-            int rowPosition);
+    /**
+     * Returns the layer that is directly below this layer for the given cell
+     * coordinate.
+     *
+     * @param columnPosition
+     *            The column position for which the underlying layer is
+     *            requested.
+     * @param rowPosition
+     *            The row position for which the underlying layer is requested.
+     * @return The layer that is directly below this layer for the given cell
+     *         coordinates or <code>null</code> if this layer has no underlying
+     *         layers.
+     */
+    public ILayer getUnderlyingLayerByPosition(int columnPosition, int rowPosition);
 
-    public ICellPainter getCellPainter(int columnPosition, int rowPosition,
-            ILayerCell cell, IConfigRegistry configRegistry);
+    /**
+     * Return the {@link ICellPainter} for the given {@link ILayerCell} at the
+     * given coordinates out of the given {@link IConfigRegistry}.
+     *
+     * @param columnPosition
+     *            The column position of the cell.
+     * @param rowPosition
+     *            The row position of the cell.
+     * @param cell
+     *            The {@link ILayerCell} for which the {@link ICellPainter} is
+     *            requested.
+     * @param configRegistry
+     *            The {@link IConfigRegistry} to retrieve the painter from.
+     * @return The {@link ICellPainter} for the given cell at the given
+     *         coordinates or <code>null</code> if no painter is configured.
+     */
+    public ICellPainter getCellPainter(
+            int columnPosition,
+            int rowPosition,
+            ILayerCell cell,
+            IConfigRegistry configRegistry);
+
+    /**
+     * @return <code>true</code> if the layer has a dynamic size (e.g. viewport)
+     *         or a fixed size.
+     * @since 2.0
+     */
+    public default boolean isDynamicSizeLayer() {
+        return false;
+    }
+
+    /**
+     * @return The collection of labels that are provided by this layer used
+     *         e.g. for CSS styling.
+     * @since 2.0
+     */
+    public default Collection<String> getProvidedLabels() {
+        return new LinkedHashSet<String>();
+    }
 
 }
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/InvertedLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/InvertedLayer.java
index 0cc5dc3..2380237 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/InvertedLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/layer/InvertedLayer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Edwin Park and others.
+ * Copyright (c) 2012, 2020 Edwin Park 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
@@ -15,7 +15,6 @@
 
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
 import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
 import org.eclipse.nebula.widgets.nattable.coordinate.Range;
 import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
@@ -77,8 +76,7 @@
     // Configuration
 
     @Override
-    public void configure(ConfigRegistry configRegistry,
-            UiBindingRegistry uiBindingRegistry) {
+    public void configure(IConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
         this.underlyingLayer.configure(configRegistry, uiBindingRegistry);
     }